summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Murray <markm@FreeBSD.org>2000-01-09 20:58:00 +0000
committerMark Murray <markm@FreeBSD.org>2000-01-09 20:58:00 +0000
commitb528cefc6b8f9670b31a865051741d946cb37085 (patch)
tree36fa73706fa0587a390c45a3fbf17c9523cb0e35
downloadsrc-test2-b528cefc6b8f9670b31a865051741d946cb37085.tar.gz
src-test2-b528cefc6b8f9670b31a865051741d946cb37085.zip
Import KTH Heimdal, which will be the core of our Kerberos5.vendor/heimdal/0.2m
Userland to follow.
Notes
Notes: svn path=/vendor-crypto/heimdal/dist/; revision=55682 svn path=/vendor-crypto/heimdal/0.2m/; revision=55684; tag=vendor/heimdal/0.2m
-rw-r--r--crypto/heimdal/ChangeLog5455
-rw-r--r--crypto/heimdal/Makefile.am9
-rw-r--r--crypto/heimdal/Makefile.am.common35
-rw-r--r--crypto/heimdal/Makefile.in645
-rw-r--r--crypto/heimdal/NEWS272
-rw-r--r--crypto/heimdal/TODO103
-rw-r--r--crypto/heimdal/acconfig.h96
-rw-r--r--crypto/heimdal/acinclude.m49
-rw-r--r--crypto/heimdal/aclocal.m41615
-rw-r--r--crypto/heimdal/admin/Makefile.am29
-rw-r--r--crypto/heimdal/admin/Makefile.in680
-rw-r--r--crypto/heimdal/admin/add.c155
-rw-r--r--crypto/heimdal/admin/change.c224
-rw-r--r--crypto/heimdal/admin/copy.c119
-rw-r--r--crypto/heimdal/admin/get.c162
-rw-r--r--crypto/heimdal/admin/ktutil.8119
-rw-r--r--crypto/heimdal/admin/ktutil.c155
-rw-r--r--crypto/heimdal/admin/ktutil_locl.h81
-rw-r--r--crypto/heimdal/admin/list.c83
-rw-r--r--crypto/heimdal/admin/purge.c175
-rw-r--r--crypto/heimdal/admin/remove.c107
-rw-r--r--crypto/heimdal/admin/srvconvert.c181
-rw-r--r--crypto/heimdal/admin/srvcreate.c124
-rw-r--r--crypto/heimdal/appl/Makefile.am22
-rw-r--r--crypto/heimdal/appl/Makefile.in602
-rw-r--r--crypto/heimdal/appl/afsutil/ChangeLog23
-rw-r--r--crypto/heimdal/appl/afsutil/Makefile.am21
-rw-r--r--crypto/heimdal/appl/afsutil/Makefile.in654
-rw-r--r--crypto/heimdal/appl/afsutil/afslog.c227
-rw-r--r--crypto/heimdal/appl/afsutil/pagsh.c152
-rw-r--r--crypto/heimdal/appl/ftp/ChangeLog414
-rw-r--r--crypto/heimdal/appl/ftp/Makefile.am5
-rw-r--r--crypto/heimdal/appl/ftp/Makefile.in598
-rw-r--r--crypto/heimdal/appl/ftp/common/Makefile.am12
-rw-r--r--crypto/heimdal/appl/ftp/common/Makefile.in611
-rw-r--r--crypto/heimdal/appl/ftp/common/buffer.c69
-rw-r--r--crypto/heimdal/appl/ftp/common/common.h60
-rw-r--r--crypto/heimdal/appl/ftp/common/sockbuf.c56
-rw-r--r--crypto/heimdal/appl/ftp/ftp/Makefile.am46
-rw-r--r--crypto/heimdal/appl/ftp/ftp/Makefile.in702
-rw-r--r--crypto/heimdal/appl/ftp/ftp/cmds.c2116
-rw-r--r--crypto/heimdal/appl/ftp/ftp/cmdtab.c202
-rw-r--r--crypto/heimdal/appl/ftp/ftp/domacro.c138
-rw-r--r--crypto/heimdal/appl/ftp/ftp/extern.h173
-rw-r--r--crypto/heimdal/appl/ftp/ftp/ftp.11193
-rw-r--r--crypto/heimdal/appl/ftp/ftp/ftp.c1746
-rw-r--r--crypto/heimdal/appl/ftp/ftp/ftp_locl.h139
-rw-r--r--crypto/heimdal/appl/ftp/ftp/ftp_var.h127
-rw-r--r--crypto/heimdal/appl/ftp/ftp/globals.c76
-rw-r--r--crypto/heimdal/appl/ftp/ftp/gssapi.c379
-rw-r--r--crypto/heimdal/appl/ftp/ftp/kauth.c198
-rw-r--r--crypto/heimdal/appl/ftp/ftp/krb4.c334
-rw-r--r--crypto/heimdal/appl/ftp/ftp/main.c549
-rw-r--r--crypto/heimdal/appl/ftp/ftp/pathnames.h44
-rw-r--r--crypto/heimdal/appl/ftp/ftp/ruserpass.c313
-rw-r--r--crypto/heimdal/appl/ftp/ftp/security.c785
-rw-r--r--crypto/heimdal/appl/ftp/ftp/security.h131
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/Makefile.am56
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/Makefile.in768
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/extern.h160
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/ftpcmd.y1455
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/ftpd.8473
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/ftpd.c2249
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/ftpd_locl.h170
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/ftpusers.538
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/gss_userok.c69
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/kauth.c365
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/logwtmp.c137
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/ls.c588
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/pathnames.h58
-rw-r--r--crypto/heimdal/appl/ftp/ftpd/popen.c224
-rw-r--r--crypto/heimdal/appl/kauth/ChangeLog39
-rw-r--r--crypto/heimdal/appl/kauth/Makefile.am42
-rw-r--r--crypto/heimdal/appl/kauth/Makefile.in739
-rw-r--r--crypto/heimdal/appl/kauth/encdata.c96
-rw-r--r--crypto/heimdal/appl/kauth/kauth.c385
-rw-r--r--crypto/heimdal/appl/kauth/kauth.h116
-rw-r--r--crypto/heimdal/appl/kauth/kauthd.c207
-rwxr-xr-xcrypto/heimdal/appl/kauth/ksrvtgt.in14
-rw-r--r--crypto/heimdal/appl/kauth/marshall.c126
-rw-r--r--crypto/heimdal/appl/kauth/rkinit.c226
-rwxr-xr-xcrypto/heimdal/appl/kauth/zrefresh12
-rw-r--r--crypto/heimdal/appl/kf/Makefile.am14
-rw-r--r--crypto/heimdal/appl/kf/Makefile.in626
-rw-r--r--crypto/heimdal/appl/kf/kf.c361
-rw-r--r--crypto/heimdal/appl/kf/kf_locl.h80
-rw-r--r--crypto/heimdal/appl/kf/kfd.c326
-rw-r--r--crypto/heimdal/appl/login/ChangeLog162
-rw-r--r--crypto/heimdal/appl/login/Makefile.am34
-rw-r--r--crypto/heimdal/appl/login/Makefile.in645
-rw-r--r--crypto/heimdal/appl/login/conf.c55
-rw-r--r--crypto/heimdal/appl/login/login.c730
-rw-r--r--crypto/heimdal/appl/login/login_access.c261
-rw-r--r--crypto/heimdal/appl/login/login_locl.h128
-rw-r--r--crypto/heimdal/appl/login/login_protos.h67
-rw-r--r--crypto/heimdal/appl/login/osfc2.c79
-rw-r--r--crypto/heimdal/appl/login/read_string.c127
-rw-r--r--crypto/heimdal/appl/login/shadow.c95
-rw-r--r--crypto/heimdal/appl/login/stty_default.c100
-rw-r--r--crypto/heimdal/appl/login/tty.c70
-rw-r--r--crypto/heimdal/appl/login/utmp_login.c120
-rw-r--r--crypto/heimdal/appl/login/utmpx_login.c89
-rw-r--r--crypto/heimdal/appl/push/ChangeLog150
-rw-r--r--crypto/heimdal/appl/push/Makefile.am27
-rw-r--r--crypto/heimdal/appl/push/Makefile.in713
-rw-r--r--crypto/heimdal/appl/push/pfrom.in6
-rw-r--r--crypto/heimdal/appl/push/push.8138
-rw-r--r--crypto/heimdal/appl/push/push.c790
-rw-r--r--crypto/heimdal/appl/push/push_locl.h98
-rw-r--r--crypto/heimdal/appl/rsh/ChangeLog237
-rw-r--r--crypto/heimdal/appl/rsh/Makefile.am19
-rw-r--r--crypto/heimdal/appl/rsh/Makefile.in698
-rw-r--r--crypto/heimdal/appl/rsh/common.c124
-rw-r--r--crypto/heimdal/appl/rsh/rsh.c948
-rw-r--r--crypto/heimdal/appl/rsh/rsh_locl.h139
-rw-r--r--crypto/heimdal/appl/rsh/rshd.c850
-rw-r--r--crypto/heimdal/appl/su/ChangeLog39
-rw-r--r--crypto/heimdal/appl/su/Makefile.am16
-rw-r--r--crypto/heimdal/appl/su/Makefile.in620
-rw-r--r--crypto/heimdal/appl/su/su.c418
-rw-r--r--crypto/heimdal/appl/test/Makefile.am37
-rw-r--r--crypto/heimdal/appl/test/Makefile.in708
-rw-r--r--crypto/heimdal/appl/test/common.c159
-rw-r--r--crypto/heimdal/appl/test/gss_common.c108
-rw-r--r--crypto/heimdal/appl/test/gss_common.h45
-rw-r--r--crypto/heimdal/appl/test/gssapi_client.c157
-rw-r--r--crypto/heimdal/appl/test/gssapi_server.c175
-rw-r--r--crypto/heimdal/appl/test/nt_gss_client.c163
-rw-r--r--crypto/heimdal/appl/test/nt_gss_common.c131
-rw-r--r--crypto/heimdal/appl/test/nt_gss_common.h45
-rw-r--r--crypto/heimdal/appl/test/nt_gss_server.c242
-rw-r--r--crypto/heimdal/appl/test/tcp_client.c132
-rw-r--r--crypto/heimdal/appl/test/tcp_server.c168
-rw-r--r--crypto/heimdal/appl/test/test_locl.h85
-rw-r--r--crypto/heimdal/appl/test/uu_client.c175
-rw-r--r--crypto/heimdal/appl/test/uu_server.c203
-rw-r--r--crypto/heimdal/cf/ChangeLog235
-rw-r--r--crypto/heimdal/cf/Makefile.am.common255
-rw-r--r--crypto/heimdal/cf/auth-modules.m427
-rw-r--r--crypto/heimdal/cf/broken-glob.m422
-rw-r--r--crypto/heimdal/cf/broken-snprintf.m458
-rw-r--r--crypto/heimdal/cf/broken.m419
-rw-r--r--crypto/heimdal/cf/c-attribute.m431
-rw-r--r--crypto/heimdal/cf/c-function.m433
-rw-r--r--crypto/heimdal/cf/capabilities.m414
-rw-r--r--crypto/heimdal/cf/check-declaration.m425
-rw-r--r--crypto/heimdal/cf/check-getpwnam_r-posix.m424
-rw-r--r--crypto/heimdal/cf/check-man.m459
-rw-r--r--crypto/heimdal/cf/check-netinet-ip-and-tcp.m438
-rw-r--r--crypto/heimdal/cf/check-type-extra.m423
-rw-r--r--crypto/heimdal/cf/check-var.m420
-rw-r--r--crypto/heimdal/cf/check-x.m452
-rw-r--r--crypto/heimdal/cf/check-xau.m464
-rw-r--r--crypto/heimdal/cf/find-func-no-libs.m49
-rw-r--r--crypto/heimdal/cf/find-func-no-libs2.m463
-rw-r--r--crypto/heimdal/cf/find-func.m49
-rw-r--r--crypto/heimdal/cf/find-if-not-broken.m413
-rw-r--r--crypto/heimdal/cf/grok-type.m438
-rw-r--r--crypto/heimdal/cf/have-pragma-weak.m437
-rw-r--r--crypto/heimdal/cf/have-struct-field.m419
-rw-r--r--crypto/heimdal/cf/have-type.m432
-rw-r--r--crypto/heimdal/cf/have-types.m414
-rw-r--r--crypto/heimdal/cf/krb-bigendian.m457
-rw-r--r--crypto/heimdal/cf/krb-find-db.m498
-rw-r--r--crypto/heimdal/cf/krb-func-getcwd-broken.m442
-rw-r--r--crypto/heimdal/cf/krb-func-getlogin.m422
-rw-r--r--crypto/heimdal/cf/krb-ipv6.m4122
-rw-r--r--crypto/heimdal/cf/krb-prog-ln-s.m428
-rw-r--r--crypto/heimdal/cf/krb-prog-ranlib.m48
-rw-r--r--crypto/heimdal/cf/krb-prog-yacc.m48
-rw-r--r--crypto/heimdal/cf/krb-struct-spwd.m422
-rw-r--r--crypto/heimdal/cf/krb-struct-winsize.m427
-rw-r--r--crypto/heimdal/cf/krb-sys-aix.m415
-rw-r--r--crypto/heimdal/cf/krb-sys-nextstep.m421
-rw-r--r--crypto/heimdal/cf/krb-version.m425
-rw-r--r--crypto/heimdal/cf/make-proto.pl199
-rw-r--r--crypto/heimdal/cf/mips-abi.m487
-rw-r--r--crypto/heimdal/cf/misc.m43
-rw-r--r--crypto/heimdal/cf/need-proto.m425
-rw-r--r--crypto/heimdal/cf/osfc2.m414
-rw-r--r--crypto/heimdal/cf/proto-compat.m422
-rw-r--r--crypto/heimdal/cf/shared-libs.m4187
-rw-r--r--crypto/heimdal/cf/test-package.m488
-rw-r--r--crypto/heimdal/cf/wflags.m421
-rwxr-xr-xcrypto/heimdal/config.guess973
-rwxr-xr-xcrypto/heimdal/config.sub957
-rwxr-xr-xcrypto/heimdal/configure12371
-rw-r--r--crypto/heimdal/configure.in934
-rw-r--r--crypto/heimdal/doc/Makefile.am8
-rw-r--r--crypto/heimdal/doc/Makefile.in620
-rw-r--r--crypto/heimdal/doc/ack.texi55
-rw-r--r--crypto/heimdal/doc/heimdal.texi246
-rw-r--r--crypto/heimdal/doc/init-creds374
-rw-r--r--crypto/heimdal/doc/install.texi86
-rw-r--r--crypto/heimdal/doc/intro.texi93
-rw-r--r--crypto/heimdal/doc/kerberos4.texi183
-rw-r--r--crypto/heimdal/doc/latin1.tex95
-rw-r--r--crypto/heimdal/doc/layman.asc1855
-rwxr-xr-xcrypto/heimdal/doc/mdate-sh92
-rw-r--r--crypto/heimdal/doc/misc.texi62
-rw-r--r--crypto/heimdal/doc/setup.texi247
-rw-r--r--crypto/heimdal/doc/standardisation/draft-brezak-win2k-krb-rc4-hmac-01.txt412
-rw-r--r--crypto/heimdal/doc/standardisation/draft-foo171
-rw-r--r--crypto/heimdal/doc/standardisation/draft-foo.ms136
-rw-r--r--crypto/heimdal/doc/standardisation/draft-foo2171
-rw-r--r--crypto/heimdal/doc/standardisation/draft-foo2.ms145
-rw-r--r--crypto/heimdal/doc/standardisation/draft-foo3227
-rw-r--r--crypto/heimdal/doc/standardisation/draft-foo3.ms260
-rw-r--r--crypto/heimdal/doc/standardisation/draft-horowitz-key-derivation-01.txt244
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-gssv2-08.txt62
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-gssv2-cbind-04.txt6188
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-chg-password-02.txt311
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-des3-hmac-sha1-00.txt127
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-key-derivation-00.txt250
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-err-msg-00.txt252
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-pk-cross-01.txt282
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-pk-init-03.txt589
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-00.txt8277
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-01.txt6214
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-03.txt6766
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-04.txt6780
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-cat-krb-dns-locate-00.txt250
-rw-r--r--crypto/heimdal/doc/standardisation/draft-ietf-ftpext-mlst-08.txt3415
-rw-r--r--crypto/heimdal/doc/standardisation/rfc1508.txt2747
-rw-r--r--crypto/heimdal/doc/standardisation/rfc1509.txt2691
-rw-r--r--crypto/heimdal/doc/standardisation/rfc1510.txt6275
-rw-r--r--crypto/heimdal/doc/standardisation/rfc1750.txt1683
-rw-r--r--crypto/heimdal/doc/standardisation/rfc1831.txt1011
-rw-r--r--crypto/heimdal/doc/standardisation/rfc1964.txt1123
-rw-r--r--crypto/heimdal/doc/standardisation/rfc2078.txt4763
-rw-r--r--crypto/heimdal/doc/standardisation/rfc2203.txt1291
-rw-r--r--crypto/heimdal/doc/standardisation/rfc2228.txt1515
-rw-r--r--crypto/heimdal/doc/whatis.texi149
-rw-r--r--crypto/heimdal/doc/win2k.texi57
-rw-r--r--crypto/heimdal/etc/services.append27
-rw-r--r--crypto/heimdal/include/Makefile.am50
-rw-r--r--crypto/heimdal/include/Makefile.in748
-rw-r--r--crypto/heimdal/include/bits.c201
-rw-r--r--crypto/heimdal/include/config.h.in1164
-rw-r--r--crypto/heimdal/include/kadm5/Makefile.am5
-rw-r--r--crypto/heimdal/include/kadm5/Makefile.in494
-rw-r--r--crypto/heimdal/include/stamp-h.in0
-rwxr-xr-xcrypto/heimdal/install-sh238
-rw-r--r--crypto/heimdal/kadmin/ChangeLog212
-rw-r--r--crypto/heimdal/kadmin/Makefile.am55
-rw-r--r--crypto/heimdal/kadmin/Makefile.in702
-rw-r--r--crypto/heimdal/kadmin/ank.c266
-rw-r--r--crypto/heimdal/kadmin/cpw.c177
-rw-r--r--crypto/heimdal/kadmin/del.c53
-rw-r--r--crypto/heimdal/kadmin/del_enctype.c132
-rw-r--r--crypto/heimdal/kadmin/dump.c80
-rw-r--r--crypto/heimdal/kadmin/ext.c116
-rw-r--r--crypto/heimdal/kadmin/get.c250
-rw-r--r--crypto/heimdal/kadmin/init.c210
-rw-r--r--crypto/heimdal/kadmin/kadmin.c281
-rw-r--r--crypto/heimdal/kadmin/kadmin_locl.h161
-rw-r--r--crypto/heimdal/kadmin/kadmind.c151
-rw-r--r--crypto/heimdal/kadmin/load.c335
-rw-r--r--crypto/heimdal/kadmin/mod.c143
-rw-r--r--crypto/heimdal/kadmin/random_password.c156
-rw-r--r--crypto/heimdal/kadmin/rename.c66
-rw-r--r--crypto/heimdal/kadmin/server.c506
-rw-r--r--crypto/heimdal/kadmin/util.c520
-rw-r--r--crypto/heimdal/kadmin/version4.c985
-rw-r--r--crypto/heimdal/kdc/524.c183
-rw-r--r--crypto/heimdal/kdc/Makefile.am62
-rw-r--r--crypto/heimdal/kdc/Makefile.in799
-rw-r--r--crypto/heimdal/kdc/config.c309
-rw-r--r--crypto/heimdal/kdc/connect.c727
-rw-r--r--crypto/heimdal/kdc/headers.h96
-rw-r--r--crypto/heimdal/kdc/hprop-common.c83
-rw-r--r--crypto/heimdal/kdc/hprop.866
-rw-r--r--crypto/heimdal/kdc/hprop.c676
-rw-r--r--crypto/heimdal/kdc/hprop.h55
-rw-r--r--crypto/heimdal/kdc/hpropd.827
-rw-r--r--crypto/heimdal/kdc/hpropd.c419
-rw-r--r--crypto/heimdal/kdc/kadb.h78
-rw-r--r--crypto/heimdal/kdc/kaserver.c794
-rw-r--r--crypto/heimdal/kdc/kdc.892
-rw-r--r--crypto/heimdal/kdc/kdc_locl.h103
-rw-r--r--crypto/heimdal/kdc/kerberos4.c557
-rw-r--r--crypto/heimdal/kdc/kerberos4.h43
-rw-r--r--crypto/heimdal/kdc/kerberos5.c1639
-rw-r--r--crypto/heimdal/kdc/kstash.827
-rw-r--r--crypto/heimdal/kdc/kstash.c188
-rw-r--r--crypto/heimdal/kdc/log.c86
-rw-r--r--crypto/heimdal/kdc/main.c98
-rw-r--r--crypto/heimdal/kdc/misc.c63
-rw-r--r--crypto/heimdal/kdc/rx.h79
-rw-r--r--crypto/heimdal/kdc/string2key.c179
-rw-r--r--crypto/heimdal/kpasswd/Makefile.am25
-rw-r--r--crypto/heimdal/kpasswd/Makefile.in758
-rw-r--r--crypto/heimdal/kpasswd/kpasswd.120
-rw-r--r--crypto/heimdal/kpasswd/kpasswd.c144
-rw-r--r--crypto/heimdal/kpasswd/kpasswd_locl.h94
-rw-r--r--crypto/heimdal/kpasswd/kpasswdd.860
-rw-r--r--crypto/heimdal/kpasswd/kpasswdd.c634
-rw-r--r--crypto/heimdal/krb5.conf26
-rw-r--r--crypto/heimdal/kuser/Makefile.am37
-rw-r--r--crypto/heimdal/kuser/Makefile.in777
-rw-r--r--crypto/heimdal/kuser/kauth_options.c40
-rw-r--r--crypto/heimdal/kuser/kdecode_ticket.c160
-rw-r--r--crypto/heimdal/kuser/kdestroy.134
-rw-r--r--crypto/heimdal/kuser/kdestroy.c125
-rw-r--r--crypto/heimdal/kuser/kgetcred.141
-rw-r--r--crypto/heimdal/kuser/kgetcred.c121
-rw-r--r--crypto/heimdal/kuser/kinit.1175
-rw-r--r--crypto/heimdal/kuser/kinit.c391
-rw-r--r--crypto/heimdal/kuser/kinit_options.c40
-rw-r--r--crypto/heimdal/kuser/klist.137
-rw-r--r--crypto/heimdal/kuser/klist.c445
-rw-r--r--crypto/heimdal/kuser/kuser_locl.h89
-rw-r--r--crypto/heimdal/kuser/kverify.c82
-rw-r--r--crypto/heimdal/lib/45/45_locl.h52
-rw-r--r--crypto/heimdal/lib/45/Makefile.am11
-rw-r--r--crypto/heimdal/lib/45/Makefile.in636
-rw-r--r--crypto/heimdal/lib/45/get_ad_tkt.c116
-rw-r--r--crypto/heimdal/lib/45/mk_req.c130
-rw-r--r--crypto/heimdal/lib/Makefile.am13
-rw-r--r--crypto/heimdal/lib/Makefile.in604
-rw-r--r--crypto/heimdal/lib/asn1/Makefile.am107
-rw-r--r--crypto/heimdal/lib/asn1/Makefile.in794
-rw-r--r--crypto/heimdal/lib/asn1/asn1_err.et20
-rw-r--r--crypto/heimdal/lib/asn1/asn1_print.c239
-rw-r--r--crypto/heimdal/lib/asn1/check-der.c289
-rw-r--r--crypto/heimdal/lib/asn1/der.h132
-rw-r--r--crypto/heimdal/lib/asn1/der_copy.c57
-rw-r--r--crypto/heimdal/lib/asn1/der_free.c48
-rw-r--r--crypto/heimdal/lib/asn1/der_get.c356
-rw-r--r--crypto/heimdal/lib/asn1/der_length.c111
-rw-r--r--crypto/heimdal/lib/asn1/der_locl.h54
-rw-r--r--crypto/heimdal/lib/asn1/der_put.c310
-rw-r--r--crypto/heimdal/lib/asn1/gen.c351
-rw-r--r--crypto/heimdal/lib/asn1/gen.h38
-rw-r--r--crypto/heimdal/lib/asn1/gen_copy.c146
-rw-r--r--crypto/heimdal/lib/asn1/gen_decode.c375
-rw-r--r--crypto/heimdal/lib/asn1/gen_encode.c250
-rw-r--r--crypto/heimdal/lib/asn1/gen_free.c130
-rw-r--r--crypto/heimdal/lib/asn1/gen_glue.c139
-rw-r--r--crypto/heimdal/lib/asn1/gen_length.c153
-rw-r--r--crypto/heimdal/lib/asn1/gen_locl.h72
-rw-r--r--crypto/heimdal/lib/asn1/hash.c207
-rw-r--r--crypto/heimdal/lib/asn1/hash.h87
-rw-r--r--crypto/heimdal/lib/asn1/k5.asn1385
-rw-r--r--crypto/heimdal/lib/asn1/lex.h36
-rw-r--r--crypto/heimdal/lib/asn1/lex.l102
-rw-r--r--crypto/heimdal/lib/asn1/libasn1.h50
-rw-r--r--crypto/heimdal/lib/asn1/main.c90
-rw-r--r--crypto/heimdal/lib/asn1/parse.y231
-rw-r--r--crypto/heimdal/lib/asn1/symbol.c90
-rw-r--r--crypto/heimdal/lib/asn1/symbol.h83
-rw-r--r--crypto/heimdal/lib/asn1/timegm.c71
-rw-r--r--crypto/heimdal/lib/auth/ChangeLog74
-rw-r--r--crypto/heimdal/lib/auth/Makefile.am6
-rw-r--r--crypto/heimdal/lib/auth/Makefile.in599
-rw-r--r--crypto/heimdal/lib/auth/afskauthlib/Makefile.am38
-rw-r--r--crypto/heimdal/lib/auth/afskauthlib/Makefile.in538
-rw-r--r--crypto/heimdal/lib/auth/afskauthlib/verify.c288
-rw-r--r--crypto/heimdal/lib/auth/pam/Makefile.am3
-rw-r--r--crypto/heimdal/lib/auth/pam/Makefile.in491
-rw-r--r--crypto/heimdal/lib/auth/pam/pam.c243
-rw-r--r--crypto/heimdal/lib/auth/pam/pam.conf.add76
-rw-r--r--crypto/heimdal/lib/auth/sia/Makefile.am66
-rw-r--r--crypto/heimdal/lib/auth/sia/Makefile.in551
-rw-r--r--crypto/heimdal/lib/auth/sia/krb4+c2_matrix.conf58
-rw-r--r--crypto/heimdal/lib/auth/sia/krb4_matrix.conf59
-rw-r--r--crypto/heimdal/lib/auth/sia/krb5+c2_matrix.conf27
-rw-r--r--crypto/heimdal/lib/auth/sia/krb5_matrix.conf27
-rw-r--r--crypto/heimdal/lib/auth/sia/posix_getpw.c78
-rw-r--r--crypto/heimdal/lib/auth/sia/security.patch11
-rw-r--r--crypto/heimdal/lib/auth/sia/sia.c672
-rw-r--r--crypto/heimdal/lib/auth/sia/sia_locl.h94
-rw-r--r--crypto/heimdal/lib/des/rc4.h76
-rw-r--r--crypto/heimdal/lib/des/rc4_enc.c133
-rw-r--r--crypto/heimdal/lib/des/rc4_skey.c101
-rw-r--r--crypto/heimdal/lib/des/rc4test.c201
-rw-r--r--crypto/heimdal/lib/gssapi/8003.c152
-rw-r--r--crypto/heimdal/lib/gssapi/ChangeLog60
-rw-r--r--crypto/heimdal/lib/gssapi/Makefile.am46
-rw-r--r--crypto/heimdal/lib/gssapi/Makefile.in654
-rw-r--r--crypto/heimdal/lib/gssapi/accept_sec_context.c242
-rw-r--r--crypto/heimdal/lib/gssapi/acquire_cred.c87
-rw-r--r--crypto/heimdal/lib/gssapi/add_oid_set_member.c54
-rw-r--r--crypto/heimdal/lib/gssapi/canonicalize_name.c46
-rw-r--r--crypto/heimdal/lib/gssapi/compare_name.c49
-rw-r--r--crypto/heimdal/lib/gssapi/context_time.c64
-rw-r--r--crypto/heimdal/lib/gssapi/create_emtpy_oid_set.c50
-rw-r--r--crypto/heimdal/lib/gssapi/decapsulate.c100
-rw-r--r--crypto/heimdal/lib/gssapi/delete_sec_context.c64
-rw-r--r--crypto/heimdal/lib/gssapi/display_name.c68
-rw-r--r--crypto/heimdal/lib/gssapi/display_status.c135
-rw-r--r--crypto/heimdal/lib/gssapi/duplicate_name.c55
-rw-r--r--crypto/heimdal/lib/gssapi/encapsulate.c100
-rw-r--r--crypto/heimdal/lib/gssapi/export_name.c48
-rw-r--r--crypto/heimdal/lib/gssapi/external.c212
-rw-r--r--crypto/heimdal/lib/gssapi/get_mic.c115
-rw-r--r--crypto/heimdal/lib/gssapi/gssapi.h742
-rw-r--r--crypto/heimdal/lib/gssapi/gssapi_locl.h89
-rw-r--r--crypto/heimdal/lib/gssapi/import_name.c137
-rw-r--r--crypto/heimdal/lib/gssapi/indicate_mechs.c55
-rw-r--r--crypto/heimdal/lib/gssapi/init.c43
-rw-r--r--crypto/heimdal/lib/gssapi/init_sec_context.c360
-rw-r--r--crypto/heimdal/lib/gssapi/inquire_context.c84
-rw-r--r--crypto/heimdal/lib/gssapi/inquire_cred.c78
-rw-r--r--crypto/heimdal/lib/gssapi/release_buffer.c46
-rw-r--r--crypto/heimdal/lib/gssapi/release_cred.c57
-rw-r--r--crypto/heimdal/lib/gssapi/release_name.c47
-rw-r--r--crypto/heimdal/lib/gssapi/release_oid_set.c46
-rw-r--r--crypto/heimdal/lib/gssapi/test_oid_set_member.c57
-rw-r--r--crypto/heimdal/lib/gssapi/unwrap.c190
-rw-r--r--crypto/heimdal/lib/gssapi/v1.c104
-rw-r--r--crypto/heimdal/lib/gssapi/verify_mic.c124
-rw-r--r--crypto/heimdal/lib/gssapi/wrap.c169
-rw-r--r--crypto/heimdal/lib/hdb/Makefile.am57
-rw-r--r--crypto/heimdal/lib/hdb/Makefile.in709
-rw-r--r--crypto/heimdal/lib/hdb/common.c145
-rw-r--r--crypto/heimdal/lib/hdb/convert_db.c219
-rw-r--r--crypto/heimdal/lib/hdb/db.c268
-rw-r--r--crypto/heimdal/lib/hdb/hdb-private.h48
-rw-r--r--crypto/heimdal/lib/hdb/hdb-protos.h158
-rw-r--r--crypto/heimdal/lib/hdb/hdb.asn165
-rw-r--r--crypto/heimdal/lib/hdb/hdb.c349
-rw-r--r--crypto/heimdal/lib/hdb/hdb.h86
-rw-r--r--crypto/heimdal/lib/hdb/hdb_err.et26
-rw-r--r--crypto/heimdal/lib/hdb/hdb_locl.h83
-rw-r--r--crypto/heimdal/lib/hdb/keytab.c187
-rw-r--r--crypto/heimdal/lib/hdb/libasn1.h51
-rw-r--r--crypto/heimdal/lib/hdb/ndbm.c316
-rw-r--r--crypto/heimdal/lib/hdb/print.c236
-rw-r--r--crypto/heimdal/lib/kadm5/ChangeLog306
-rw-r--r--crypto/heimdal/lib/kadm5/Makefile.am110
-rw-r--r--crypto/heimdal/lib/kadm5/Makefile.in812
-rw-r--r--crypto/heimdal/lib/kadm5/acl.c138
-rw-r--r--crypto/heimdal/lib/kadm5/admin.h698
-rw-r--r--crypto/heimdal/lib/kadm5/chpass_c.c70
-rw-r--r--crypto/heimdal/lib/kadm5/chpass_s.c114
-rw-r--r--crypto/heimdal/lib/kadm5/client_glue.c150
-rw-r--r--crypto/heimdal/lib/kadm5/common_glue.c124
-rw-r--r--crypto/heimdal/lib/kadm5/context_s.c221
-rw-r--r--crypto/heimdal/lib/kadm5/create_c.c73
-rw-r--r--crypto/heimdal/lib/kadm5/create_s.c191
-rw-r--r--crypto/heimdal/lib/kadm5/delete_c.c69
-rw-r--r--crypto/heimdal/lib/kadm5/delete_s.c70
-rw-r--r--crypto/heimdal/lib/kadm5/destroy_c.c51
-rw-r--r--crypto/heimdal/lib/kadm5/destroy_s.c50
-rw-r--r--crypto/heimdal/lib/kadm5/dump_log.c262
-rw-r--r--crypto/heimdal/lib/kadm5/ent_setup.c141
-rw-r--r--crypto/heimdal/lib/kadm5/error.c48
-rw-r--r--crypto/heimdal/lib/kadm5/flush.c48
-rw-r--r--crypto/heimdal/lib/kadm5/flush_c.c41
-rw-r--r--crypto/heimdal/lib/kadm5/flush_s.c41
-rw-r--r--crypto/heimdal/lib/kadm5/free.c91
-rw-r--r--crypto/heimdal/lib/kadm5/get_c.c76
-rw-r--r--crypto/heimdal/lib/kadm5/get_princs_c.c86
-rw-r--r--crypto/heimdal/lib/kadm5/get_princs_s.c113
-rw-r--r--crypto/heimdal/lib/kadm5/get_s.c181
-rw-r--r--crypto/heimdal/lib/kadm5/init_c.c602
-rw-r--r--crypto/heimdal/lib/kadm5/init_s.c232
-rw-r--r--crypto/heimdal/lib/kadm5/iprop.h53
-rw-r--r--crypto/heimdal/lib/kadm5/ipropd_master.c422
-rw-r--r--crypto/heimdal/lib/kadm5/ipropd_slave.c313
-rw-r--r--crypto/heimdal/lib/kadm5/kadm5_err.et59
-rw-r--r--crypto/heimdal/lib/kadm5/kadm5_locl.h83
-rw-r--r--crypto/heimdal/lib/kadm5/log.c666
-rw-r--r--crypto/heimdal/lib/kadm5/marshall.c330
-rw-r--r--crypto/heimdal/lib/kadm5/modify_c.c73
-rw-r--r--crypto/heimdal/lib/kadm5/modify_s.c92
-rw-r--r--crypto/heimdal/lib/kadm5/password_quality.c147
-rw-r--r--crypto/heimdal/lib/kadm5/private.h281
-rw-r--r--crypto/heimdal/lib/kadm5/privs_c.c73
-rw-r--r--crypto/heimdal/lib/kadm5/privs_s.c44
-rw-r--r--crypto/heimdal/lib/kadm5/randkey_c.c89
-rw-r--r--crypto/heimdal/lib/kadm5/randkey_s.c96
-rw-r--r--crypto/heimdal/lib/kadm5/rename_c.c73
-rw-r--r--crypto/heimdal/lib/kadm5/rename_s.c104
-rw-r--r--crypto/heimdal/lib/kadm5/replay_log.c118
-rw-r--r--crypto/heimdal/lib/kadm5/sample_passwd_check.c85
-rw-r--r--crypto/heimdal/lib/kadm5/send_recv.c89
-rw-r--r--crypto/heimdal/lib/kadm5/server_glue.c150
-rw-r--r--crypto/heimdal/lib/kadm5/set_keys.c292
-rw-r--r--crypto/heimdal/lib/kadm5/set_modifier.c54
-rw-r--r--crypto/heimdal/lib/kafs/ChangeLog169
-rw-r--r--crypto/heimdal/lib/kafs/Makefile.am71
-rw-r--r--crypto/heimdal/lib/kafs/Makefile.in898
-rw-r--r--crypto/heimdal/lib/kafs/README.dlfcn246
-rw-r--r--crypto/heimdal/lib/kafs/afskrb.c139
-rw-r--r--crypto/heimdal/lib/kafs/afskrb5.c179
-rw-r--r--crypto/heimdal/lib/kafs/afsl.exp6
-rw-r--r--crypto/heimdal/lib/kafs/afslib.c55
-rw-r--r--crypto/heimdal/lib/kafs/afslib.exp3
-rw-r--r--crypto/heimdal/lib/kafs/afssys.c395
-rw-r--r--crypto/heimdal/lib/kafs/afssysdefs.h87
-rw-r--r--crypto/heimdal/lib/kafs/common.c396
-rw-r--r--crypto/heimdal/lib/kafs/dlfcn.c581
-rw-r--r--crypto/heimdal/lib/kafs/dlfcn.h46
-rw-r--r--crypto/heimdal/lib/kafs/kafs.3158
-rw-r--r--crypto/heimdal/lib/kafs/kafs.h191
-rw-r--r--crypto/heimdal/lib/kafs/kafs_locl.h135
-rw-r--r--crypto/heimdal/lib/krb5/Makefile.am148
-rw-r--r--crypto/heimdal/lib/krb5/Makefile.in956
-rw-r--r--crypto/heimdal/lib/krb5/add_et_list.c50
-rw-r--r--crypto/heimdal/lib/krb5/addr_families.c544
-rw-r--r--crypto/heimdal/lib/krb5/address.c197
-rw-r--r--crypto/heimdal/lib/krb5/aname_to_localname.c76
-rw-r--r--crypto/heimdal/lib/krb5/asn1_glue.c59
-rw-r--r--crypto/heimdal/lib/krb5/auth_context.c426
-rw-r--r--crypto/heimdal/lib/krb5/build_ap_req.c79
-rw-r--r--crypto/heimdal/lib/krb5/build_auth.c156
-rw-r--r--crypto/heimdal/lib/krb5/cache.c422
-rw-r--r--crypto/heimdal/lib/krb5/changepw.c346
-rw-r--r--crypto/heimdal/lib/krb5/codec.c251
-rw-r--r--crypto/heimdal/lib/krb5/config_file.c750
-rw-r--r--crypto/heimdal/lib/krb5/config_file_netinfo.c178
-rw-r--r--crypto/heimdal/lib/krb5/constants.c39
-rw-r--r--crypto/heimdal/lib/krb5/context.c357
-rw-r--r--crypto/heimdal/lib/krb5/convert_creds.c215
-rw-r--r--crypto/heimdal/lib/krb5/copy_host_realm.c66
-rw-r--r--crypto/heimdal/lib/krb5/crc.c71
-rw-r--r--crypto/heimdal/lib/krb5/creds.c149
-rw-r--r--crypto/heimdal/lib/krb5/crypto.c2314
-rw-r--r--crypto/heimdal/lib/krb5/data.c109
-rw-r--r--crypto/heimdal/lib/krb5/dump_config.c71
-rw-r--r--crypto/heimdal/lib/krb5/expand_hostname.c80
-rw-r--r--crypto/heimdal/lib/krb5/fcache.c431
-rw-r--r--crypto/heimdal/lib/krb5/free.c52
-rw-r--r--crypto/heimdal/lib/krb5/free_host_realm.c54
-rw-r--r--crypto/heimdal/lib/krb5/generate_seq_number.c62
-rw-r--r--crypto/heimdal/lib/krb5/generate_subkey.c52
-rw-r--r--crypto/heimdal/lib/krb5/get_addrs.c310
-rw-r--r--crypto/heimdal/lib/krb5/get_cred.c776
-rw-r--r--crypto/heimdal/lib/krb5/get_default_principal.c67
-rw-r--r--crypto/heimdal/lib/krb5/get_default_realm.c80
-rw-r--r--crypto/heimdal/lib/krb5/get_for_creds.c287
-rw-r--r--crypto/heimdal/lib/krb5/get_host_realm.c194
-rw-r--r--crypto/heimdal/lib/krb5/get_in_tkt.c794
-rw-r--r--crypto/heimdal/lib/krb5/get_in_tkt_pw.c87
-rw-r--r--crypto/heimdal/lib/krb5/get_in_tkt_with_keytab.c103
-rw-r--r--crypto/heimdal/lib/krb5/get_in_tkt_with_skey.c82
-rw-r--r--crypto/heimdal/lib/krb5/get_port.c52
-rw-r--r--crypto/heimdal/lib/krb5/heim_err.et18
-rw-r--r--crypto/heimdal/lib/krb5/init_creds.c111
-rw-r--r--crypto/heimdal/lib/krb5/init_creds_pw.c547
-rw-r--r--crypto/heimdal/lib/krb5/keyblock.c77
-rw-r--r--crypto/heimdal/lib/krb5/keytab.c407
-rw-r--r--crypto/heimdal/lib/krb5/keytab_file.c540
-rw-r--r--crypto/heimdal/lib/krb5/keytab_keyfile.c316
-rw-r--r--crypto/heimdal/lib/krb5/keytab_krb4.c272
-rw-r--r--crypto/heimdal/lib/krb5/keytab_memory.c161
-rw-r--r--crypto/heimdal/lib/krb5/krb5-private.h58
-rw-r--r--crypto/heimdal/lib/krb5/krb5-protos.h2352
-rw-r--r--crypto/heimdal/lib/krb5/krb5.conf.5167
-rw-r--r--crypto/heimdal/lib/krb5/krb5.h600
-rw-r--r--crypto/heimdal/lib/krb5/krb5_425_conv_principal.3198
-rw-r--r--crypto/heimdal/lib/krb5/krb5_build_principal.378
-rw-r--r--crypto/heimdal/lib/krb5/krb5_create_checksum.368
-rw-r--r--crypto/heimdal/lib/krb5/krb5_crypto_init.341
-rw-r--r--crypto/heimdal/lib/krb5/krb5_encrypt.360
-rw-r--r--crypto/heimdal/lib/krb5/krb5_err.et215
-rw-r--r--crypto/heimdal/lib/krb5/krb5_free_principal.330
-rw-r--r--crypto/heimdal/lib/krb5/krb5_locl.h136
-rw-r--r--crypto/heimdal/lib/krb5/krb5_openlog.3225
-rw-r--r--crypto/heimdal/lib/krb5/krb5_parse_name.339
-rw-r--r--crypto/heimdal/lib/krb5/krb5_sname_to_principal.358
-rw-r--r--crypto/heimdal/lib/krb5/krb5_unparse_name.334
-rw-r--r--crypto/heimdal/lib/krb5/krb5_warn.373
-rw-r--r--crypto/heimdal/lib/krb5/krbhst.c196
-rw-r--r--crypto/heimdal/lib/krb5/kuserok.c108
-rw-r--r--crypto/heimdal/lib/krb5/log.c426
-rw-r--r--crypto/heimdal/lib/krb5/mcache.c227
-rw-r--r--crypto/heimdal/lib/krb5/misc.c36
-rw-r--r--crypto/heimdal/lib/krb5/mk_error.c124
-rw-r--r--crypto/heimdal/lib/krb5/mk_priv.c168
-rw-r--r--crypto/heimdal/lib/krb5/mk_rep.c116
-rw-r--r--crypto/heimdal/lib/krb5/mk_req.c102
-rw-r--r--crypto/heimdal/lib/krb5/mk_req_ext.c151
-rw-r--r--crypto/heimdal/lib/krb5/mk_safe.c115
-rw-r--r--crypto/heimdal/lib/krb5/n-fold-test.c104
-rw-r--r--crypto/heimdal/lib/krb5/n-fold.c126
-rw-r--r--crypto/heimdal/lib/krb5/net_read.c47
-rw-r--r--crypto/heimdal/lib/krb5/net_write.c47
-rw-r--r--crypto/heimdal/lib/krb5/padata.c45
-rw-r--r--crypto/heimdal/lib/krb5/principal.c898
-rw-r--r--crypto/heimdal/lib/krb5/prog_setup.c62
-rw-r--r--crypto/heimdal/lib/krb5/prompter_posix.c70
-rw-r--r--crypto/heimdal/lib/krb5/rd_cred.c185
-rw-r--r--crypto/heimdal/lib/krb5/rd_error.c66
-rw-r--r--crypto/heimdal/lib/krb5/rd_priv.c150
-rw-r--r--crypto/heimdal/lib/krb5/rd_rep.c108
-rw-r--r--crypto/heimdal/lib/krb5/rd_req.c441
-rw-r--r--crypto/heimdal/lib/krb5/rd_safe.c172
-rw-r--r--crypto/heimdal/lib/krb5/read_message.c63
-rw-r--r--crypto/heimdal/lib/krb5/recvauth.c190
-rw-r--r--crypto/heimdal/lib/krb5/replay.c224
-rw-r--r--crypto/heimdal/lib/krb5/send_to_kdc.c395
-rw-r--r--crypto/heimdal/lib/krb5/sendauth.c208
-rw-r--r--crypto/heimdal/lib/krb5/set_default_realm.c87
-rw-r--r--crypto/heimdal/lib/krb5/sock_principal.c74
-rw-r--r--crypto/heimdal/lib/krb5/store.c609
-rw-r--r--crypto/heimdal/lib/krb5/store_emem.c126
-rw-r--r--crypto/heimdal/lib/krb5/store_fd.c74
-rw-r--r--crypto/heimdal/lib/krb5/store_mem.c117
-rw-r--r--crypto/heimdal/lib/krb5/string-to-key-test.c106
-rw-r--r--crypto/heimdal/lib/krb5/ticket.c74
-rw-r--r--crypto/heimdal/lib/krb5/time.c58
-rw-r--r--crypto/heimdal/lib/krb5/transited.c382
-rw-r--r--crypto/heimdal/lib/krb5/verify_init.c196
-rw-r--r--crypto/heimdal/lib/krb5/verify_krb5_conf.c102
-rw-r--r--crypto/heimdal/lib/krb5/verify_user.c170
-rw-r--r--crypto/heimdal/lib/krb5/version.c43
-rw-r--r--crypto/heimdal/lib/krb5/warn.c193
-rw-r--r--crypto/heimdal/lib/krb5/write_message.c55
-rw-r--r--crypto/heimdal/lib/roken/ChangeLog715
-rw-r--r--crypto/heimdal/lib/roken/Makefile.am177
-rw-r--r--crypto/heimdal/lib/roken/Makefile.in800
-rw-r--r--crypto/heimdal/lib/roken/base64.c146
-rw-r--r--crypto/heimdal/lib/roken/base64.h42
-rw-r--r--crypto/heimdal/lib/roken/chown.c45
-rw-r--r--crypto/heimdal/lib/roken/concat.c112
-rw-r--r--crypto/heimdal/lib/roken/copyhostent.c102
-rw-r--r--crypto/heimdal/lib/roken/daemon.c88
-rw-r--r--crypto/heimdal/lib/roken/emalloc.c56
-rw-r--r--crypto/heimdal/lib/roken/eread.c57
-rw-r--r--crypto/heimdal/lib/roken/erealloc.c56
-rw-r--r--crypto/heimdal/lib/roken/err.c48
-rw-r--r--crypto/heimdal/lib/roken/err.h71
-rw-r--r--crypto/heimdal/lib/roken/errx.c48
-rw-r--r--crypto/heimdal/lib/roken/estrdup.c56
-rw-r--r--crypto/heimdal/lib/roken/ewrite.c57
-rw-r--r--crypto/heimdal/lib/roken/fchown.c45
-rw-r--r--crypto/heimdal/lib/roken/flock.c87
-rw-r--r--crypto/heimdal/lib/roken/fnmatch.c173
-rw-r--r--crypto/heimdal/lib/roken/fnmatch.h49
-rw-r--r--crypto/heimdal/lib/roken/freeaddrinfo.c52
-rw-r--r--crypto/heimdal/lib/roken/freehostent.c62
-rw-r--r--crypto/heimdal/lib/roken/gai_strerror.c73
-rw-r--r--crypto/heimdal/lib/roken/get_default_username.c80
-rw-r--r--crypto/heimdal/lib/roken/get_window_size.c102
-rw-r--r--crypto/heimdal/lib/roken/getaddrinfo-test.c144
-rw-r--r--crypto/heimdal/lib/roken/getaddrinfo.c400
-rw-r--r--crypto/heimdal/lib/roken/getarg.3317
-rw-r--r--crypto/heimdal/lib/roken/getarg.c547
-rw-r--r--crypto/heimdal/lib/roken/getarg.h89
-rw-r--r--crypto/heimdal/lib/roken/getcap.c1118
-rw-r--r--crypto/heimdal/lib/roken/getcwd.c57
-rw-r--r--crypto/heimdal/lib/roken/getdtablesize.c101
-rw-r--r--crypto/heimdal/lib/roken/getegid.c48
-rw-r--r--crypto/heimdal/lib/roken/geteuid.c48
-rw-r--r--crypto/heimdal/lib/roken/getgid.c48
-rw-r--r--crypto/heimdal/lib/roken/gethostname.c72
-rw-r--r--crypto/heimdal/lib/roken/getipnodebyaddr.c74
-rw-r--r--crypto/heimdal/lib/roken/getipnodebyname.c86
-rw-r--r--crypto/heimdal/lib/roken/getnameinfo.c127
-rw-r--r--crypto/heimdal/lib/roken/getnameinfo_verified.c69
-rw-r--r--crypto/heimdal/lib/roken/getopt.c128
-rw-r--r--crypto/heimdal/lib/roken/gettimeofday.c55
-rw-r--r--crypto/heimdal/lib/roken/getuid.c48
-rw-r--r--crypto/heimdal/lib/roken/getusershell.c160
-rw-r--r--crypto/heimdal/lib/roken/glob.c835
-rw-r--r--crypto/heimdal/lib/roken/glob.h84
-rw-r--r--crypto/heimdal/lib/roken/hstrerror.c85
-rw-r--r--crypto/heimdal/lib/roken/inet_aton.c49
-rw-r--r--crypto/heimdal/lib/roken/inet_ntop.c153
-rw-r--r--crypto/heimdal/lib/roken/inet_pton.c66
-rw-r--r--crypto/heimdal/lib/roken/initgroups.c45
-rw-r--r--crypto/heimdal/lib/roken/innetgr.c49
-rw-r--r--crypto/heimdal/lib/roken/iruserok.c287
-rw-r--r--crypto/heimdal/lib/roken/issuid.c53
-rw-r--r--crypto/heimdal/lib/roken/k_getpwnam.c64
-rw-r--r--crypto/heimdal/lib/roken/k_getpwuid.c64
-rw-r--r--crypto/heimdal/lib/roken/lstat.c45
-rw-r--r--crypto/heimdal/lib/roken/make-print-version.c68
-rw-r--r--crypto/heimdal/lib/roken/memmove.c64
-rw-r--r--crypto/heimdal/lib/roken/mini_inetd.c147
-rw-r--r--crypto/heimdal/lib/roken/mkstemp.c84
-rw-r--r--crypto/heimdal/lib/roken/net_read.c74
-rw-r--r--crypto/heimdal/lib/roken/net_write.c72
-rw-r--r--crypto/heimdal/lib/roken/parse_bytes-test.c92
-rw-r--r--crypto/heimdal/lib/roken/parse_bytes.c78
-rw-r--r--crypto/heimdal/lib/roken/parse_bytes.h48
-rw-r--r--crypto/heimdal/lib/roken/parse_time.c78
-rw-r--r--crypto/heimdal/lib/roken/parse_time.h51
-rw-r--r--crypto/heimdal/lib/roken/parse_units.c324
-rw-r--r--crypto/heimdal/lib/roken/parse_units.h73
-rw-r--r--crypto/heimdal/lib/roken/print_version.c78
-rw-r--r--crypto/heimdal/lib/roken/putenv.c76
-rw-r--r--crypto/heimdal/lib/roken/rcmd.c52
-rw-r--r--crypto/heimdal/lib/roken/readv.c67
-rw-r--r--crypto/heimdal/lib/roken/recvmsg.c69
-rw-r--r--crypto/heimdal/lib/roken/resolve.c353
-rw-r--r--crypto/heimdal/lib/roken/resolve.h103
-rw-r--r--crypto/heimdal/lib/roken/resource.h15
-rw-r--r--crypto/heimdal/lib/roken/roken-common.h283
-rw-r--r--crypto/heimdal/lib/roken/roken.awk35
-rw-r--r--crypto/heimdal/lib/roken/roken.def17
-rw-r--r--crypto/heimdal/lib/roken/roken.dsp156
-rw-r--r--crypto/heimdal/lib/roken/roken.h.in573
-rw-r--r--crypto/heimdal/lib/roken/roken.mak316
-rw-r--r--crypto/heimdal/lib/roken/roken.rc105
-rw-r--r--crypto/heimdal/lib/roken/roken_gethostby.c274
-rw-r--r--crypto/heimdal/lib/roken/sendmsg.c65
-rw-r--r--crypto/heimdal/lib/roken/setegid.c57
-rw-r--r--crypto/heimdal/lib/roken/setenv.c66
-rw-r--r--crypto/heimdal/lib/roken/seteuid.c57
-rw-r--r--crypto/heimdal/lib/roken/signal.c81
-rw-r--r--crypto/heimdal/lib/roken/simple_exec.c171
-rw-r--r--crypto/heimdal/lib/roken/snprintf.c619
-rw-r--r--crypto/heimdal/lib/roken/socket.c282
-rw-r--r--crypto/heimdal/lib/roken/strcasecmp.c58
-rw-r--r--crypto/heimdal/lib/roken/strdup.c50
-rw-r--r--crypto/heimdal/lib/roken/strerror.c57
-rw-r--r--crypto/heimdal/lib/roken/strftime.c396
-rw-r--r--crypto/heimdal/lib/roken/strlcat.c50
-rw-r--r--crypto/heimdal/lib/roken/strlcpy.c60
-rw-r--r--crypto/heimdal/lib/roken/strlwr.c53
-rw-r--r--crypto/heimdal/lib/roken/strncasecmp.c60
-rw-r--r--crypto/heimdal/lib/roken/strndup.c56
-rw-r--r--crypto/heimdal/lib/roken/strnlen.c49
-rw-r--r--crypto/heimdal/lib/roken/strpftime-test.c287
-rw-r--r--crypto/heimdal/lib/roken/strptime.c444
-rw-r--r--crypto/heimdal/lib/roken/strsep.c61
-rw-r--r--crypto/heimdal/lib/roken/strtok_r.c65
-rw-r--r--crypto/heimdal/lib/roken/strupr.c53
-rw-r--r--crypto/heimdal/lib/roken/swab.c54
-rw-r--r--crypto/heimdal/lib/roken/tm2time.c61
-rw-r--r--crypto/heimdal/lib/roken/unsetenv.c70
-rw-r--r--crypto/heimdal/lib/roken/verify.c62
-rw-r--r--crypto/heimdal/lib/roken/verr.c46
-rw-r--r--crypto/heimdal/lib/roken/verrx.c46
-rw-r--r--crypto/heimdal/lib/roken/vsyslog.c57
-rw-r--r--crypto/heimdal/lib/roken/vwarn.c45
-rw-r--r--crypto/heimdal/lib/roken/vwarnx.c46
-rw-r--r--crypto/heimdal/lib/roken/warn.c48
-rw-r--r--crypto/heimdal/lib/roken/warnerr.c79
-rw-r--r--crypto/heimdal/lib/roken/warnx.c48
-rw-r--r--crypto/heimdal/lib/roken/writev.c64
-rw-r--r--crypto/heimdal/lib/roken/xdbm.h73
-rw-r--r--crypto/heimdal/lib/sl/ChangeLog120
-rw-r--r--crypto/heimdal/lib/sl/Makefile.am44
-rw-r--r--crypto/heimdal/lib/sl/Makefile.in737
-rw-r--r--crypto/heimdal/lib/sl/lex.l114
-rw-r--r--crypto/heimdal/lib/sl/make_cmds.c240
-rw-r--r--crypto/heimdal/lib/sl/make_cmds.h69
-rw-r--r--crypto/heimdal/lib/sl/parse.y168
-rw-r--r--crypto/heimdal/lib/sl/roken_rename.h61
-rw-r--r--crypto/heimdal/lib/sl/sl.c223
-rw-r--r--crypto/heimdal/lib/sl/sl.h57
-rw-r--r--crypto/heimdal/lib/sl/sl_locl.h46
-rw-r--r--crypto/heimdal/lib/sl/ss.c133
-rw-r--r--crypto/heimdal/lib/sl/ss.h55
-rwxr-xr-xcrypto/heimdal/ltconfig2101
-rw-r--r--crypto/heimdal/ltmain.sh3079
-rw-r--r--crypto/heimdal/missing2
-rwxr-xr-xcrypto/heimdal/mkinstalldirs40
753 files changed, 234810 insertions, 0 deletions
diff --git a/crypto/heimdal/ChangeLog b/crypto/heimdal/ChangeLog
new file mode 100644
index 000000000000..4472260f7907
--- /dev/null
+++ b/crypto/heimdal/ChangeLog
@@ -0,0 +1,5455 @@
+2000-01-08 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2m
+
+2000-01-08 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/Makefile.am: bump version to 7:1:0
+ * lib/krb5/principal.c (krb5_sname_to_principal): use
+ krb5_expand_hostname
+ * lib/krb5/expand_hostname.c (krb5_expand_hostname): handle
+ ai_canonname being set in any of the addresses returnedby
+ getaddrinfo. glibc apparently returns the reverse lookup of every
+ address in ai_canonname.
+
+2000-01-06 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2l
+
+2000-01-06 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/Makefile.am: set version to 7:0:0
+ * lib/krb5/principal.c (krb5_sname_to_principal): remove `hp'
+
+ * lib/hdb/Makefile.am: set version to 4:1:1
+
+ * kdc/hpropd.c (dump_krb4): use `krb5_get_default_realms'
+ * lib/krb5/get_in_tkt.c (add_padata): change types to make
+ everything work out
+ (krb5_get_in_cred): remove const to make types match
+ * lib/krb5/crypto.c (ARCFOUR_string_to_key): correct signature
+ * lib/krb5/principal.c (krb5_sname_to_principal): handle not
+ getting back a canonname
+
+2000-01-06 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2k
+
+2000-01-06 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/send_to_kdc.c (krb5_sendto_kdc): advance colon so that
+ we actually parse the port number. based on a patch from Leif
+ Johansson <leifj@it.su.se>
+
+2000-01-02 Assar Westerlund <assar@sics.se>
+
+ * admin/purge.c: remove all non-current and old entries from a
+ keytab
+
+ * admin: break up ktutil.c into files
+
+ * admin/ktutil.c (list): support --verbose (also listning time
+ stamps)
+ (kt_add, kt_get): set timestamp in newly created entries
+ (kt_change): add `change' command
+
+ * admin/srvconvert.c (srvconv): set timestamp in newly created
+ entries
+ * lib/krb5/keytab_keyfile.c (akf_next_entry): set timetsamp,
+ always go the a predicatble position on error
+ * lib/krb5/keytab.c (krb5_kt_copy_entry_contents): copy timestamp
+ * lib/krb5/keytab_file.c (fkt_add_entry): store timestamp
+ (fkt_next_entry_int): return timestamp
+ * lib/krb5/krb5.h (krb5_keytab_entry): add timestamp
+
+1999-12-30 Assar Westerlund <assar@sics.se>
+
+ * configure.in (krb4): use `-ldes' in tests
+
+1999-12-26 Assar Westerlund <assar@sics.se>
+
+ * lib/hdb/print.c (event2string): handle events without principal.
+ From Luke Howard <lukeh@PADL.COM>
+
+1999-12-25 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2j
+
+Tue Dec 21 18:03:17 1999 Assar Westerlund <assar@sics.se>
+
+ * lib/hdb/Makefile.am (asn1_files): add $(EXEEXT) for cygwin and
+ related systems
+
+ * lib/asn1/Makefile.am (asn1_files): add $(EXEEXT) for cygwin and
+ related systems
+
+ * include/Makefile.am (krb5-types.h): add $(EXEEXT) for cygwin and
+ related systems
+
+1999-12-20 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2i
+
+1999-12-20 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/Makefile.am (libkrb5_la_LDFLAGS): bump version to 6:3:1
+
+ * lib/krb5/send_to_kdc.c (send_via_proxy): free data
+ * lib/krb5/send_to_kdc.c (send_via_proxy): new function use
+ getaddrinfo instead of gethostbyname{,2}
+ * lib/krb5/get_for_creds.c: use getaddrinfo instead of
+ getnodebyname{,2}
+
+1999-12-17 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2h
+
+1999-12-17 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2g
+
+1999-12-16 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/Makefile.am: bump version to 6:2:1
+
+ * lib/krb5/principal.c (krb5_sname_to_principal): handle
+ ai_canonname not being set
+ * lib/krb5/expand_hostname.c (krb5_expand_hostname): handle
+ ai_canonname not being set
+
+ * appl/test/uu_server.c: print messages to stderr
+ * appl/test/tcp_server.c: print messages to stderr
+ * appl/test/nt_gss_server.c: print messages to stderr
+ * appl/test/gssapi_server.c: print messages to stderr
+
+ * appl/test/tcp_client.c (proto): remove shadowing `context'
+ * appl/test/common.c (client_doit): add forgotten ntohs
+
+1999-12-13 Assar Westerlund <assar@sics.se>
+
+ * configure.in (VERISON): bump to 0.2g-pre
+
+1999-12-12 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/principal.c (krb5_425_conv_principal_ext): be more
+ robust and handle extra dot at the beginning of default_domain
+
+1999-12-12 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2f
+
+1999-12-12 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/Makefile.am: bump version to 6:1:1
+
+ * lib/krb5/changepw.c (get_kdc_address): use
+ `krb5_get_krb_changepw_hst'
+
+ * lib/krb5/krbhst.c (krb5_get_krb_changepw_hst): add
+
+ * lib/krb5/get_host_realm.c: add support for _kerberos.domain
+ (according to draft-ietf-cat-krb-dns-locate-01.txt)
+
+1999-12-06 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2e
+
+1999-12-06 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/changepw.c (krb5_change_password): use the correct
+ address
+
+ * lib/krb5/Makefile.am: bump version to 6:0:1
+
+ * lib/asn1/Makefile.am: bump version to 1:4:0
+
+1999-12-04 Assar Westerlund <assar@sics.se>
+
+ * configure.in: move AC_KRB_IPv6 to make sure it's performed
+ before AC_BROKEN
+ (el_init): use new feature of AC_FIND_FUNC_NO_LIBS
+
+ * appl/test/uu_client.c: use client_doit
+ * appl/test/test_locl.h (client_doit): add prototype
+ * appl/test/tcp_client.c: use client_doit
+ * appl/test/nt_gss_client.c: use client_doit
+ * appl/test/gssapi_client.c: use client_doit
+ * appl/test/common.c (client_doit): move identical code here and
+ start using getaddrinfo
+
+ * appl/kf/kf.c (doit): rewrite to use getaddrinfo
+ * kdc/hprop.c: re-write to use getaddrinfo
+ * lib/krb5/principal.c (krb5_sname_to_principal): use getaddrinfo
+ * lib/krb5/expand_hostname.c (krb5_expand_hostname): use
+ getaddrinfo
+ * lib/krb5/changepw.c: re-write to use getaddrinfo
+ * lib/krb5/addr_families.c (krb5_parse_address): use getaddrinfo
+
+1999-12-03 Assar Westerlund <assar@sics.se>
+
+ * configure.in (BROKEN): check for freeaddrinfo, getaddrinfo,
+ getnameinfo, gai_strerror
+ (socklen_t): check for
+
+1999-11-23 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/crypto.c (ARCFOUR_string_to_key): change order of bytes
+ within unicode characters. this should probably be done in some
+ arbitrarly complex way to do it properly and you would have to
+ know what character encoding was used for the password and salt
+ string.
+
+ * lib/krb5/addr_families.c (ipv4_uninteresting): ignore 0.0.0.0
+ (INADDR_ANY)
+ (ipv6_uninteresting): remove unused macro
+
+1999-11-22 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/krb5/krb5.h: rc4->arcfour
+
+ * lib/krb5/crypto.c: rc4->arcfour
+
+1999-11-17 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/krb5_locl.h: add <rc4.h>
+ * lib/krb5/krb5.h (krb5_keytype): add KEYTYPE_RC4
+ * lib/krb5/crypto.c: some code for doing RC4/MD5/HMAC which might
+ not be totally different from some small company up in the
+ north-west corner of the US
+
+ * lib/krb5/get_addrs.c (find_all_addresses): change code to
+ actually increment buf_size
+
+1999-11-14 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/krb5.h (krb5_context_data): add `scan_interfaces'
+ * lib/krb5/get_addrs.c (krb5_get_all_client_addrs): make interaces
+ scanning optional
+ * lib/krb5/context.c (init_context_from_config_file): set
+ `scan_interfaces'
+
+ * lib/krb5/Makefile.am (libkrb5_la_SOURCES): add add_et_list.c
+ * lib/krb5/add_et_list.c (krb5_add_et_list): new function
+
+1999-11-12 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_default_realm.c (krb5_get_default_realm,
+ krb5_get_default_realms): set realms if they were unset
+ * lib/krb5/context.c (init_context_from_config_file): don't
+ initialize default realms here. it's done lazily instead.
+
+ * lib/krb5/krb5.h (KRB5_TC_*): make constants unsigned
+ * lib/asn1/gen_glue.c (generate_2int, generate_units): make sure
+ bit constants are unsigned
+ * lib/asn1/gen.c (define_type): make length in sequences be
+ unsigned.
+
+ * configure.in: remove duplicate test for setsockopt test for
+ struct tm.tm_isdst
+
+ * lib/krb5/get_in_tkt.c (krb5_get_in_cred): generate
+ preauthentication information if we get back ERR_PREAUTH_REQUIRED
+ * lib/krb5/init_creds_pw.c (krb5_get_init_creds_password): remove
+ preauthentication generation code. it's now in krb5_get_in_cred
+
+ * configure.in (AC_BROKEN_SNPRINTF): add strptime check for struct
+ tm.tm_gmtoff and timezone
+
+1999-11-11 Johan Danielsson <joda@pdc.kth.se>
+
+ * kdc/main.c: make this work with multi-db
+
+ * kdc/kdc_locl.h: make this work with multi-db
+
+ * kdc/config.c: make this work with multi-db
+
+1999-11-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * kdc/misc.c: update for multi-database code
+
+ * kdc/main.c: update for multi-database code
+
+ * kdc/kdc_locl.h: update
+
+ * kdc/config.c: allow us to have more than one database
+
+1999-11-04 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2d
+
+ * lib/krb5/Makefile.am: bump version to 5:0:0 to be safe
+ (krb5_context_data has changed and some code do (might) access
+ fields directly)
+
+ * lib/krb5/krb5.h (krb5_context_data): add `etypes_des'
+
+ * lib/krb5/get_cred.c (init_tgs_req): use
+ krb5_keytype_to_enctypes_default
+
+ * lib/krb5/crypto.c (krb5_keytype_to_enctypes_default): new
+ function
+
+ * lib/krb5/context.c (set_etypes): new function
+ (init_context_from_config_file): set both `etypes' and `etypes_des'
+
+1999-11-02 Assar Westerlund <assar@sics.se>
+
+ * configure.in (VERSION): bump to 0.2d-pre
+
+1999-10-29 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/principal.c (krb5_parse_name): check memory allocations
+
+1999-10-28 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2c
+
+ * lib/krb5/dump_config.c (print_tree): check for empty tree
+
+ * lib/krb5/string-to-key-test.c (tests): update the test cases
+ with empty principals so that they actually use an empty realm and
+ not the default. use the correct etype for 3DES
+
+ * lib/krb5/Makefile.am: bump version to 4:1:0
+
+ * kdc/config.c (configure): more careful with the port string
+
+1999-10-26 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2b
+
+1999-10-20 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/Makefile.am: bump version to 4:0:0
+ (krb524_convert_creds_kdc and potentially some other functions
+ have changed prototypes)
+
+ * lib/hdb/Makefile.am: bump version to 4:0:1
+
+ * lib/asn1/Makefile.am: bump version to 1:3:0
+
+ * configure.in (LIB_roken): add dbopen. getcap in roken
+ references dbopen and with shared libraries we need to add this
+ dependency.
+
+ * lib/krb5/verify_krb5_conf.c (main): support speicifying the
+ configuration file to test on the command line
+
+ * lib/krb5/config_file.c (parse_binding): handle line with no
+ whitespace before =
+ (krb5_config_parse_file_debug): set lineno earlier so that we don't
+ use it unitialized
+
+ * configure.in (AM_INIT_AUTOMAKE): bump to 0.2b-pre opt*: need
+ more include files for these tests
+
+ * lib/krb5/set_default_realm.c (krb5_set_default_realm): use
+ krb5_config_get_strings, which means that your configuration file
+ should look like:
+
+ [libdefaults]
+ default_realm = realm1 realm2 realm3
+
+ * lib/krb5/set_default_realm.c (config_binding_to_list): fix
+ copy-o. From Michal Vocu <michal@karlin.mff.cuni.cz>
+
+ * kdc/config.c (configure): add a missing strdup. From Michal
+ Vocu <michal@karlin.mff.cuni.cz>
+
+1999-10-17 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2a
+
+ * configure.in: only test for db.h with using berkeley_db. remember
+ to link with LIB_tgetent when checking for el_init. add xnlock
+
+ * appl/Makefile.am: add xnlock
+
+ * kdc/kerberos5.c (find_etype): support null keys
+
+ * kdc/kerberos4.c (get_des_key): support null keys
+
+ * lib/krb5/crypto.c (krb5_get_wrapped_length): more correct
+ calculation
+
+1999-10-16 Johan Danielsson <joda@pdc.kth.se>
+
+ * kuser/kinit.c (main): pass ccache to krb524_convert_creds_kdc
+
+1999-10-12 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/krb5/crypto.c (krb5_enctype_to_keytype): remove warning
+
+1999-10-10 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/mk_req.c (krb5_mk_req): use krb5_free_host_realm
+
+ * lib/krb5/krb5.h (krb5_ccache_data): make `ops' const
+
+ * lib/krb5/crypto.c (krb5_string_to_salttype): new function
+
+ * **/*.[ch]: const-ize
+
+1999-10-06 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/creds.c (krb5_compare_creds): const-ify
+
+ * lib/krb5/cache.c: clean-up and comment-up
+
+ * lib/krb5/copy_host_realm.c (krb5_copy_host_realm): copy all the
+ strings
+
+ * lib/krb5/verify_user.c (krb5_verify_user_lrealm): free the
+ correct realm part
+
+ * kdc/connect.c (handle_tcp): things work much better when ret is
+ initialized
+
+1999-10-03 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/convert_creds.c (krb524_convert_creds_kdc): look at the
+ type of the session key
+
+ * lib/krb5/crypto.c (krb5_enctypes_compatible_keys): spell
+ correctly
+
+ * lib/krb5/creds.c (krb5_compare_creds): fix spelling of
+ krb5_enctypes_compatible_keys
+
+ * lib/krb5/convert_creds.c (krb524_convert_creds_kdc): get new
+ credentials from the KDC if the existing one doesn't have a DES
+ session key.
+
+ * lib/45/get_ad_tkt.c (get_ad_tkt): update to new
+ krb524_convert_creds_kdc
+
+1999-10-03 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/krb5/keytab_keyfile.c: make krb5_akf_ops const
+
+ * lib/krb5/keytab_memory.c: make krb5_mkt_ops const
+
+ * lib/krb5/keytab_file.c: make krb5_fkt_ops const
+
+1999-10-01 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/config_file.c: rewritten to allow error messages
+
+ * lib/krb5/Makefile.am (bin_PROGRAMS): add verify_krb5_conf
+ (libkrb5_la_SOURCES): add config_file_netinfo.c
+
+ * lib/krb5/verify_krb5_conf.c: new program for verifying that
+ krb5.conf is corret
+
+ * lib/krb5/config_file_netinfo.c: moved netinfo code here from
+ config_file.c
+
+1999-09-28 Assar Westerlund <assar@sics.se>
+
+ * kdc/hpropd.c (dump_krb4): kludge default_realm
+
+ * lib/asn1/check-der.c: add test cases for Generalized time and
+ make sure we return the correct value
+
+ * lib/asn1/der_put.c: simplify by using der_put_length_and_tag
+
+ * lib/krb5/verify_user.c (krb5_verify_user_lrealm): ariant of
+ krb5_verify_user that tries in all the local realms
+
+ * lib/krb5/set_default_realm.c: add support for having several
+ default realms
+
+ * lib/krb5/kuserok.c (krb5_kuserok): use `krb5_get_default_realms'
+
+ * lib/krb5/get_default_realm.c (krb5_get_default_realms): add
+
+ * lib/krb5/krb5.h (krb5_context_data): change `default_realm' to
+ `default_realms'
+
+ * lib/krb5/context.c: change from `default_realm' to
+ `default_realms'
+
+ * lib/krb5/aname_to_localname.c (krb5_aname_to_localname): use
+ krb5_get_default_realms
+
+ * lib/krb5/Makefile.am (libkrb5_la_SOURCES): add copy_host_realm.c
+
+ * lib/krb5/copy_host_realm.c: new file
+
+1999-09-27 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/asn1/der_put.c (encode_generalized_time): encode length
+
+ * lib/krb5/recvauth.c: new function `krb5_recvauth_match_version'
+ that allows more intelligent matching of the application version
+
+1999-09-26 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/asn1_print.c: add err.h
+
+ * kdc/config.c (configure): use parse_bytes
+
+ * appl/test/nt_gss_common.c: use the correct header file
+
+1999-09-24 Johan Danielsson <joda@pdc.kth.se>
+
+ * kuser/klist.c: add a `--cache' flag
+
+ * kuser/kinit.c (main): only get default value for `get_v4_tgt' if
+ it's explicitly set in krb5.conf
+
+1999-09-23 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/asn1_print.c (tag_names); add another univeral tag
+
+ * lib/asn1/der.h: update universal tags
+
+1999-09-22 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/asn1_print.c (loop): print length of octet string
+
+1999-09-21 Johan Danielsson <joda@pdc.kth.se>
+
+ * admin/ktutil.c (kt_get): add `--help'
+
+1999-09-21 Assar Westerlund <assar@sics.se>
+
+ * kuser/Makefile.am: add kdecode_ticket
+
+ * kuser/kdecode_ticket.c: new debug program
+
+ * appl/test/nt_gss_server.c: new program to test against `Sample *
+ SSPI Code' in Windows 2000 RC1 SDK.
+
+ * appl/test/Makefile.am: add nt_gss_client and nt_gss_server
+
+ * lib/asn1/der_get.c (decode_general_string): remember to advance
+ ret over the length-len
+
+ * lib/asn1/Makefile.am: add asn1_print
+
+ * lib/asn1/asn1_print.c: new program for printing DER-structures
+
+ * lib/asn1/der_put.c: make functions more consistent
+
+ * lib/asn1/der_get.c: make functions more consistent
+
+1999-09-20 Johan Danielsson <joda@pdc.kth.se>
+
+ * kdc/kerberos5.c: be more informative in pa-data error messages
+
+1999-09-16 Assar Westerlund <assar@sics.se>
+
+ * configure.in: test for strlcpy, strlcat
+
+1999-09-14 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/init_creds_pw.c (krb5_get_init_creds_password): return
+ KRB5_LIBOS_PWDINTR when interrupted
+
+ * lib/krb5/get_in_tkt_pw.c (krb5_password_key_proc): check return
+ value from des_read_pw_string
+
+ * kuser/kinit.c (main): don't print any error if reading the
+ password was interrupted
+
+ * kpasswd/kpasswd.c (main): don't print any error if reading the
+ password was interrupted
+
+ * kdc/string2key.c (main): check the return value from fgets
+
+ * kdc/kstash.c (main): check return value from des_read_pw_string
+
+ * admin/ktutil.c (kt_add): check the return-value from fgets and
+ overwrite the password for paranoid reasons
+
+ * lib/krb5/keytab_keyfile.c (get_cell_and_realm): only remove the
+ newline if it's there
+
+1999-09-13 Assar Westerlund <assar@sics.se>
+
+ * kdc/hpropd.c (main): remove bogus error with `--print'. remove
+ sysloging of number of principals transferred
+
+ * kdc/hprop.c (ka_convert): set flags correctly for krbtgt/CELL
+ principals
+ (main): get rid of bogus opening of hdb database when propagating
+ ka-server database
+
+1999-09-12 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/krb5_locl.h (O_BINARY): add fallback definition
+
+ * lib/krb5/krb5.h (krb5_context_data): add keytab types
+
+ * configure.in: revert back awk test, not worked around in
+ roken.awk
+
+ * lib/krb5/keytab_krb4.c: remove O_BINARY
+
+ * lib/krb5/keytab_keyfile.c: some support for AFS KeyFile's. From
+ Love <lha@e.kth.se>
+
+ * lib/krb5/keytab_file.c: remove O_BINARY
+
+ * lib/krb5/keytab.c: move the list of keytab types to the context
+
+ * lib/krb5/fcache.c: remove O_BINARY
+
+ * lib/krb5/context.c (init_context_from_config_file): register all
+ standard cache and keytab types
+ (krb5_free_context): free `kt_types'
+
+ * lib/krb5/cache.c (krb5_cc_resolve): move the registration of the
+ standard types of credential caches to context
+
+ * lib/krb5/Makefile.am (libkrb5_la_SOURCES): add keytab_keyfile.c
+
+1999-09-10 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/keytab.c: add comments and clean-up
+
+ * admin/ktutil.c: add `ktutil copy'
+
+ * lib/krb5/keytab_krb4.c: new file
+
+ * lib/krb5/krb5.h (krb5_kt_cursor): add a `data' field
+
+ * lib/krb5/Makefile.am: add keytab_krb4.c
+
+ * lib/krb5/keytab.c: add krb4 and correct some if's
+
+ * admin/srvconvert.c (srvconv): move common code
+
+ * lib/krb5/krb5.h (krb5_fkt_ops, krb5_mkt_ops): new variables
+
+ * lib/krb5/keytab.c: move out file and memory functions
+
+ * lib/krb5/Makefile.am (libkrb5_la_SOURCES): add keytab_file.c,
+ keytab_memory.c
+
+ * lib/krb5/keytab_memory.c: new file
+
+ * lib/krb5/keytab_file.c: new file
+
+ * kpasswd/kpasswdd.c: move out password quality functions
+
+1999-09-07 Assar Westerlund <assar@sics.se>
+
+ * lib/hdb/Makefile.am (libhdb_la_SOURCES): add keytab.c. From
+ Love <lha@e.kth.se>
+
+ * lib/krb5/convert_creds.c (krb524_convert_creds_kdc): check
+ return value from `krb5_sendto_kdc'
+
+1999-09-06 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/send_to_kdc.c (send_and_recv): rename to recv_loop and
+ remove the sending of data. add a parameter `limit'. let callers
+ send the date themselves (and preferably with net_write on tcp
+ sockets)
+ (send_and_recv_tcp): read first the length field and then only that
+ many bytes
+
+1999-09-05 Assar Westerlund <assar@sics.se>
+
+ * kdc/connect.c (handle_tcp): try to print warning `TCP data of
+ strange type' less often
+
+ * lib/krb5/send_to_kdc.c (send_and_recv): handle EINTR properly.
+ return on EOF. always free data. check return value from
+ realloc.
+ (send_and_recv_tcp, send_and_recv_http): check advertised length
+ against actual length
+
+1999-09-01 Johan Danielsson <joda@pdc.kth.se>
+
+ * configure.in: check for sgi capabilities
+
+1999-08-27 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/krb5/get_addrs.c: krb5_get_all_server_addrs shouldn't return
+ extra addresses
+
+ * kpasswd/kpasswdd.c: use HDB keytabs; change some error messages;
+ add --realm flag
+
+ * lib/krb5/address.c (krb5_append_addresses): remove duplicates
+
+1999-08-26 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/hdb/keytab.c: HDB keytab backend
+
+1999-08-25 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/krb5/keytab.c
+ (krb5_kt_{start_seq_get,next_entry,end_seq_get}): check for NULL
+ pointer
+
+1999-08-24 Johan Danielsson <joda@pdc.kth.se>
+
+ * kpasswd/kpasswdd.c: add `--keytab' flag
+
+1999-08-23 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/addr_families.c (IN6_ADDR_V6_TO_V4): use `s6_addr'
+ instead of the non-standard `s6_addr32'. From Yoshinobu Inoue
+ <shin@kame.net> by way of the KAME repository
+
+1999-08-18 Assar Westerlund <assar@sics.se>
+
+ * configure.in (--enable-new-des3-code): remove check for `struct
+ addrinfo'
+
+ * lib/krb5/crypto.c (etypes): remove NEW_DES3_CODE, enable
+ des3-cbc-sha1 and keep old-des3-cbc-sha1 for backwards
+ compatability
+
+ * lib/krb5/krb5.h (krb5_enctype): des3-cbc-sha1 (with key
+ derivation) just got assigned etype 16 by <bcn@isi.edu>. keep the
+ old etype at 7.
+
+1999-08-16 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/sendauth.c (krb5_sendauth): only look at errno if
+ krb5_net_read actually returns -1
+
+ * lib/krb5/recvauth.c (krb5_recvauth): only look at errno if
+ krb5_net_read actually returns -1
+
+ * appl/kf/kf.c (proto): don't trust errno if krb5_net_read hasn't
+ returned -1
+
+ * appl/test/tcp_server.c (proto): only trust errno if
+ krb5_net_read actually returns -1
+
+ * appl/kf/kfd.c (proto): be more careful with the return value
+ from krb5_net_read
+
+1999-08-13 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_addrs.c (get_addrs_int): try the different ways
+ sequentially instead of just one. this helps if your heimdal was
+ built with v6-support but your kernel doesn't have it, for
+ example.
+
+1999-08-12 Assar Westerlund <assar@sics.se>
+
+ * kdc/hpropd.c: add inetd flag. default means try to figure out
+ if stdin is a socket or not.
+
+ * Makefile.am (ACLOCAL): just use `cf', this variable is only used
+ when the current directory is $(top_srcdir) anyways and having
+ $(top_srcdir) there breaks if it's a relative path
+
+1999-08-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * configure.in: check for setproctitle
+
+1999-08-05 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/principal.c (krb5_sname_to_principal): remember to call
+ freehostent
+
+ * appl/test/tcp_client.c: call freehostent
+
+ * appl/kf/kf.c (doit): call freehostent
+
+ * appl/kf/kf.c: make v6 friendly and simplify
+
+ * appl/kf/kfd.c: make v6 friendly and simplify
+
+ * appl/test/tcp_server.c: simplify by using krb5_err instead of
+ errx
+
+ * appl/test/tcp_client.c: simplify by using krb5_err instead of
+ errx
+
+ * appl/test/tcp_server.c: make v6 friendly and simplify
+
+ * appl/test/tcp_client.c: make v6 friendly and simplify
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * Release 0.1m
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * kuser/kinit.c (main): some more KRB4-conditionalizing
+
+ * lib/krb5/get_in_tkt.c: type correctness
+
+ * lib/krb5/get_for_creds.c (krb5_fwd_tgs_creds): set forwarded in
+ flags. From Miroslav Ruda <ruda@ics.muni.cz>
+
+ * kuser/kinit.c (main): add config file support for forwardable
+ and krb4 support. From Miroslav Ruda <ruda@ics.muni.cz>
+
+ * kdc/kerberos5.c (as_rep): add an empty X500-compress string as
+ transited.
+ (fix_transited_encoding): check length.
+ From Miroslav Ruda <ruda@ics.muni.cz>
+
+ * kdc/hpropd.c (dump_krb4): check the realm so that we don't dump
+ principals in some other realm. From Miroslav Ruda
+ <ruda@ics.muni.cz>
+ (main): rename sa_len -> sin_len, sa_lan is a define on some
+ platforms.
+
+ * appl/kf/kfd.c: add regpag support. From Miroslav Ruda
+ <ruda@ics.muni.cz>
+
+ * appl/kf/kf.c: add `-G' and forwardable option in krb5.conf.
+ From Miroslav Ruda <ruda@ics.muni.cz>
+
+ * lib/krb5/config_file.c (parse_list): don't run past end of line
+
+ * appl/test/gss_common.h: new prototypes
+
+ * appl/test/gssapi_client.c: use gss_err instead of abort
+
+ * appl/test/gss_common.c (gss_verr, gss_err): add
+
+1999-08-03 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/Makefile.am (n_fold_test_LDADD): need to set this
+ otherwise it doesn't build with shared libraries
+
+ * kdc/hpropd.c: v6-ify
+
+ * kdc/hprop.c: v6-ify
+
+1999-08-01 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/mk_req.c (krb5_mk_req): use krb5_expand_hostname
+
+1999-07-31 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_host_realm.c (krb5_get_host_realm_int): new
+ function that takes a FQDN
+
+ * lib/krb5/Makefile.am (libkrb5_la_SOURCES): add exapnd_hostname.c
+
+ * lib/krb5/expand_hostname.c: new file
+
+1999-07-28 Assar Westerlund <assar@sics.se>
+
+ * Release 0.1l
+
+1999-07-28 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/Makefile.am: bump version to 1:2:0
+
+ * lib/krb5/Makefile.am: bump version to 3:1:0
+
+ * configure.in: more inet_pton to roken
+
+ * lib/krb5/principal.c (krb5_sname_to_principal): use
+ getipnodebyname
+
+1999-07-26 Assar Westerlund <assar@sics.se>
+
+ * Release 0.1k
+
+1999-07-26 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/krb5/Makefile.am: bump version number (changed function
+ signatures)
+
+ * lib/hdb/Makefile.am: bump version number (changes to some
+ function signatures)
+
+1999-07-26 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/Makefile.am: bump version to 3:0:2
+
+ * lib/hdb/Makefile.am: bump version to 2:1:0
+
+ * lib/asn1/Makefile.am: bump version to 1:1:0
+
+1999-07-26 Assar Westerlund <assar@sics.se>
+
+ * Release 0.1j
+
+1999-07-26 Assar Westerlund <assar@sics.se>
+
+ * configure.in: rokenize inet_ntop
+
+ * lib/krb5/store_fd.c: lots of changes from size_t to ssize_t
+
+ * lib/krb5/store_mem.c: lots of changes from size_t to ssize_t
+
+ * lib/krb5/store_emem.c: lots of changes from size_t to ssize_t
+
+ * lib/krb5/store.c: lots of changes from size_t to ssize_t
+ (krb5_ret_stringz): check return value from realloc
+
+ * lib/krb5/mk_safe.c: some type correctness
+
+ * lib/krb5/mk_priv.c: some type correctness
+
+ * lib/krb5/krb5.h (krb5_storage): change return values of
+ functions from size_t to ssize_t
+
+1999-07-24 Assar Westerlund <assar@sics.se>
+
+ * Release 0.1i
+
+ * configure.in (AC_PROG_AWK): disable. mawk seems to mishandle \#
+ in lib/roken/roken.awk
+
+ * lib/krb5/get_addrs.c (find_all_addresses): try to use SA_LEN to
+ step over addresses if there's no `sa_lan' field
+
+ * lib/krb5/sock_principal.c (krb5_sock_to_principal): simplify by
+ using `struct sockaddr_storage'
+
+ * lib/krb5/send_to_kdc.c (krb5_sendto_kdc): simplify by using
+ `struct sockaddr_storage'
+
+ * lib/krb5/changepw.c (krb5_change_password): simplify by using
+ `struct sockaddr_storage'
+
+ * lib/krb5/auth_context.c (krb5_auth_con_setaddrs_from_fd):
+ simplify by using `struct sockaddr_storage'
+
+ * kpasswd/kpasswdd.c (*): simplify by using `struct
+ sockaddr_storage'
+
+ * kdc/connect.c (*): simplify by using `struct sockaddr_storage'
+
+ * configure.in (sa_family_t): just test for existence
+ (sockaddr_storage): also specify include file
+
+ * configure.in (AM_INIT_AUTOMAKE): bump version to 0.1i
+ (sa_family_t): test for
+ (struct sockaddr_storage): test for
+
+ * kdc/hprop.c (propagate_database): typo, NULL should be
+ auth_context
+
+ * lib/krb5/get_addrs.c: conditionalize on HAVE_IPV6 instead of
+ AF_INET6
+
+ * appl/kf/kf.c (main): use warnx
+
+ * appl/kf/kf.c (proto): remove shadowing context
+
+ * lib/krb5/get_addrs.c (find_all_addresses): try to handle the
+ case of getting back an `sockaddr_in6' address when sizeof(struct
+ sockaddr_in6) > sizeof(struct sockaddr) and we have no sa_len to
+ tell us how large the address is. This obviously doesn't work
+ with unknown protocol types.
+
+1999-07-24 Assar Westerlund <assar@sics.se>
+
+ * Release 0.1h
+
+1999-07-23 Assar Westerlund <assar@sics.se>
+
+ * appl/kf/kfd.c: clean-up and more paranoia
+
+ * etc/services.append: add kf
+
+ * appl/kf/kf.c: rename tk_file to ccache for consistency. clean-up
+
+1999-07-22 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/n-fold-test.c (main): print the correct data
+
+ * appl/Makefile.am (SUBDIRS): add kf
+
+ * appl/kf: new program. From Miroslav Ruda <ruda@ics.muni.cz>
+
+ * kdc/hprop.c: declare some variables unconditionally to simplify
+ things
+
+ * kpasswd/kpasswdd.c: initialize kadm5 connection for every change
+ (otherwise the modifier in the database doesn't get set)
+
+ * kdc/hpropd.c: clean-up and re-organize
+
+ * kdc/hprop.c: clean-up and re-organize
+
+ * configure.in (SunOS): define to xy for SunOS x.y
+
+1999-07-19 Assar Westerlund <assar@sics.se>
+
+ * configure.in (AC_BROKEN): test for copyhostent, freehostent,
+ getipnodebyaddr, getipnodebyname
+
+1999-07-15 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/check-der.c: more test cases for integers
+
+ * lib/asn1/der_length.c (length_int): handle the case of the
+ largest negative integer by not calling abs
+
+1999-07-14 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/check-der.c (generic_test): check malloc return value
+ properly
+
+ * lib/krb5/Makefile.am: add string_to_key_test
+
+ * lib/krb5/prog_setup.c (krb5_program_setup): always initialize
+ the context
+
+ * lib/krb5/n-fold-test.c (main): return a relevant return value
+
+ * lib/krb5/krbhst.c: do SRV lookups for admin server as well.
+ some clean-up.
+
+1999-07-12 Assar Westerlund <assar@sics.se>
+
+ * configure.in: handle not building X programs
+
+1999-07-06 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/addr_families.c (ipv6_parse_addr): remove duplicate
+ variable
+ (ipv6_sockaddr2port): fix typo
+
+ * etc/services.append: beginning of a file with services
+
+ * lib/krb5/cache.c (krb5_cc_resolve): fall-back to files if
+ there's no prefix. also clean-up a little bit.
+
+ * kdc/hprop.c (--kaspecials): new flag for handling special KA
+ server entries. From "Brandon S. Allbery KF8NH"
+ <allbery@kf8nh.apk.net>
+
+1999-07-05 Assar Westerlund <assar@sics.se>
+
+ * kdc/connect.c (handle_tcp): make sure we have data before
+ starting to look for HTTP
+
+ * kdc/connect.c (handle_tcp): always do getpeername, we can't
+ trust recvfrom to return anything sensible
+
+1999-07-04 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_in_tkt.c (add_padat): encrypt pre-auth data with
+ all enctypes
+
+ * kpasswd/kpasswdd.c (change): fetch the salt-type from the entry
+
+ * admin/srvconvert.c (srvconv): better error messages
+
+1999-07-03 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/principal.c (unparse_name): error check malloc properly
+
+ * lib/krb5/get_in_tkt.c (krb5_init_etype): error check malloc
+ properly
+
+ * lib/krb5/crypto.c (*): do some malloc return-value checks
+ properly
+
+ * lib/hdb/hdb.c (hdb_process_master_key): simplify by using
+ krb5_data_alloc
+
+ * lib/hdb/hdb.c (hdb_process_master_key): check return value from
+ malloc
+
+ * lib/asn1/gen_decode.c (decode_type): fix generation of decoding
+ information for TSequenceOf.
+
+ * kdc/kerberos5.c (get_pa_etype_info): check return value from
+ malloc
+
+1999-07-02 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/der_copy.c (copy_octet_string): don't fail if length ==
+ 0 and malloc returns NULL
+
+1999-06-29 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/addr_families.c (ipv6_parse_addr): implement
+
+1999-06-24 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/rd_cred.c (krb5_rd_cred): compare the sender's address
+ as an addrport one
+
+ * lib/krb5/krb5.h (KRB5_ADDRESS_ADDRPORT, KRB5_ADDRESS_IPPORT):
+ add
+ (krb5_auth_context): add local and remote port
+
+ * lib/krb5/get_for_creds.c (krb5_get_forwarded_creds): get the
+ local and remote address and add them to the krb-cred packet
+
+ * lib/krb5/auth_context.c: save the local and remove ports in the
+ auth_context
+
+ * lib/krb5/address.c (krb5_make_addrport): create an address of
+ type KRB5_ADDRESS_ADDRPORT from (addr, port)
+
+ * lib/krb5/addr_families.c (krb5_sockaddr2port): new function for
+ grabbing the port number out of the sockaddr
+
+1999-06-23 Assar Westerlund <assar@sics.se>
+
+ * admin/srvcreate.c (srvcreate): always take the DES-CBC-MD5 key.
+ increase possible verbosity.
+
+ * lib/krb5/config_file.c (parse_list): handle blank lines at
+ another place
+
+ * kdc/connect.c (add_port_string): don't return a value
+
+ * lib/kadm5/init_c.c (get_cred_cache): you cannot reuse the cred
+ cache if the principals are different. close and NULL the old one
+ so that we create a new one.
+
+ * configure.in: move around cgywin et al
+ (LIB_kdb): set at the end of krb4-block
+ (krb4): test for krb_enable_debug and krb_disable_debug
+
+1999-06-16 Assar Westerlund <assar@sics.se>
+
+ * kuser/kdestroy.c (main): try to destroy v4 ticket even if the
+ destruction of the v5 one fails
+
+ * lib/krb5/crypto.c (DES3_postproc): new version that does the
+ right thing
+ (*): don't put and recover length in 3DES encoding
+ other small fixes
+
+1999-06-15 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_default_principal.c: rewrite to use
+ get_default_username
+
+ * lib/krb5/Makefile.am: add n-fold-test
+
+ * kdc/connect.c: add fallbacks for all lookups by service name
+ (handle_tcp): break-up and clean-up
+
+1999-06-09 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/addr_families.c (ipv6_uninteresting): don't consider
+ the loopback address as uninteresting
+
+ * lib/krb5/get_addrs.c: new magic flag to get loopback address if
+ there are no other addresses.
+ (krb5_get_all_client_addrs): use that flag
+
+1999-06-04 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/crypto.c (HMAC_SHA1_DES3_checksum): don't include the
+ length
+ (checksum_sha1, checksum_hmac_sha1_des3): blocksize should be 64
+ (encrypt_internal_derived): don't include the length and don't
+ decrease by the checksum size twice
+ (_get_derived_key): the constant should be 5 bytes
+
+1999-06-02 Johan Danielsson <joda@pdc.kth.se>
+
+ * configure.in: use KRB_CHECK_X
+
+ * configure.in: check for netinet/ip.h
+
+1999-05-31 Assar Westerlund <assar@sics.se>
+
+ * kpasswd/kpasswdd.c (setup_passwd_quality_check): conditionalize
+ on RTLD_NOW
+
+1999-05-23 Assar Westerlund <assar@sics.se>
+
+ * appl/test/uu_server.c: removed unused stuff
+
+ * appl/test/uu_client.c: removed unused stuff
+
+1999-05-21 Assar Westerlund <assar@sics.se>
+
+ * kuser/kgetcred.c (main): correct error message
+
+ * lib/krb5/crypto.c (verify_checksum): call (*ct->checksum)
+ directly, avoiding redundant lookups and memory leaks
+
+ * lib/krb5/auth_context.c (krb5_auth_con_setaddrs_from_fd): free
+ local and remote addresses
+
+ * lib/krb5/get_default_principal.c (get_logname): also try
+ $USERNAME
+
+ * lib/asn1/Makefile.am (asn1_files): add $(EXEEXT)
+
+ * lib/krb5/principal.c (USE_RESOLVER): try to define only if we
+ have a libresolv (currently by checking for res_search)
+
+1999-05-18 Johan Danielsson <joda@pdc.kth.se>
+
+ * kdc/connect.c (handle_tcp): remove %-escapes in request
+
+1999-05-14 Assar Westerlund <assar@sics.se>
+
+ * Release 0.1g
+
+ * admin/ktutil.c (kt_remove): -t should be -e
+
+ * configure.in (CHECK_NETINET_IP_AND_TCP): use
+
+ * kdc/hpropd.c: support for dumping to krb4. From Miroslav Ruda
+ <ruda@ics.muni.cz>
+
+ * admin/ktutil.c (kt_add): new option `--no-salt'. From Miroslav
+ Ruda <ruda@ics.muni.cz>
+
+ * configure.in: add cygwin and DOS tests replace sendmsg, recvmsg,
+ and innetgr with roken versions
+
+ * kuser/kgetcred.c: new program
+
+Tue May 11 14:09:33 1999 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/krb5/mcache.c: fix paste-o
+
+1999-05-10 Johan Danielsson <joda@pdc.kth.se>
+
+ * configure.in: don't use uname
+
+1999-05-10 Assar Westerlund <assar@sics.se>
+
+ * acconfig.h (KRB_PUT_INT): if we don't have KRB4 use four
+ arguments :-)
+
+ * appl/test/uu_server.c (setsockopt): cast to get rid of a warning
+
+ * appl/test/tcp_server.c (setsockopt): cast to get rid of a
+ warning
+
+ * appl/test/tcp_client.c (proto): call krb5_sendauth with ccache
+ == NULL
+
+ * appl/test/gssapi_server.c (setsockopt): cast to get rid of a
+ warning
+
+ * lib/krb5/sendauth.c (krb5_sendauth): handle ccache == NULL by
+ setting the default ccache.
+
+ * configure.in (getsockopt, setsockopt): test for
+ (AM_INIT_AUTOMAKE): bump version to 0.1g
+
+ * appl/Makefile.am (SUBDIRS): add kx
+
+ * lib/hdb/convert_db.c (main): handle the case of no master key
+
+1999-05-09 Assar Westerlund <assar@sics.se>
+
+ * Release 0.1f
+
+ * kuser/kinit.c: add --noaddresses
+
+ * lib/krb5/get_in_tkt.c (init_as_req): interpret `addrs' being an
+ empty sit of list as to not ask for any addresses.
+
+1999-05-08 Assar Westerlund <assar@sics.se>
+
+ * acconfig.h (_GNU_SOURCE): define this to enable (used)
+ extensions on glibc-based systems such as linux
+
+1999-05-03 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_cred.c (get_cred_from_kdc_flags): allocate and free
+ `*out_creds' properly
+
+ * lib/krb5/creds.c (krb5_compare_creds): just verify that the
+ keytypes/enctypes are compatible, not that they are the same
+
+ * kuser/kdestroy.c (cache): const-correctness
+
+1999-05-03 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/hdb/hdb.c (hdb_set_master_key): initialise master key
+ version
+
+ * lib/hdb/convert_db.c: add support for upgrading database
+ versions
+
+ * kdc/misc.c: add flags to fetch
+
+ * kdc/kstash.c: unlink keyfile on failure, chmod to 400
+
+ * kdc/hpropd.c: add --print option
+
+ * kdc/hprop.c: pass flags to hdb_foreach
+
+ * lib/hdb/convert_db.c: add some flags
+
+ * lib/hdb/Makefile.am: remove extra LDFLAGS, update version to 2;
+ build prototype headers
+
+ * lib/hdb/hdb_locl.h: update prototypes
+
+ * lib/hdb/print.c: move printable version of entry from kadmin
+
+ * lib/hdb/hdb.c: change hdb_{seal,unseal}_* to check if the key is
+ sealed or not; add flags to hdb_foreach
+
+ * lib/hdb/ndbm.c: add flags to NDBM_seq, NDBM_firstkey, and
+ NDBM_nextkey
+
+ * lib/hdb/db.c: add flags to DB_seq, DB_firstkey, and DB_nextkey
+
+ * lib/hdb/common.c: add flags to _hdb_{fetch,store}
+
+ * lib/hdb/hdb.h: add master_key_version to struct hdb, update
+ prototypes
+
+ * lib/hdb/hdb.asn1: make mkvno optional, update version to 2
+
+ * configure.in: --enable-netinfo
+
+ * lib/krb5/config_file.c: HAVE_NETINFO_NI_H -> HAVE_NETINFO
+
+ * config.sub: fix for crays
+
+ * config.guess: new version from automake 1.4
+
+ * config.sub: new version from automake 1.4
+
+Wed Apr 28 00:21:17 1999 Assar Westerlund <assar@sics.se>
+
+ * Release 0.1e
+
+ * lib/krb5/mcache.c (mcc_get_next): get the current cursor
+ correctly
+
+ * acconfig.h: correct definition of KRB_PUT_INT for old krb4 code.
+ From Ake Sandgren <ake@cs.umu.se>
+
+1999-04-27 Johan Danielsson <joda@pdc.kth.se>
+
+ * kdc/kerberos5.c: fix arguments to decrypt_ticket
+
+1999-04-25 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/mk_req_ext.c (krb5_mk_req_internal): try to handle old
+ DCE secd's that are not able to handle MD5 checksums by defaulting
+ to MD4 if the keytype was DES-CBC-CRC
+
+ * lib/krb5/mk_req.c (krb5_mk_req): use auth_context->keytype
+
+ * lib/krb5/krb5.h (krb5_auth_context_data): add `keytype' and
+ `cksumtype'
+
+ * lib/krb5/get_cred.c (make_pa_tgs_req): remove old kludge for
+ secd
+ (init_tgs_req): add all supported enctypes for the keytype in
+ `in_creds->session.keytype' if it's set
+
+ * lib/krb5/crypto.c (F_PSEUDO): new flag for non-protocol
+ encryption types
+ (do_checksum): new function
+ (verify_checksum): take the checksum to use from the checksum message
+ and not from the crypto struct
+ (etypes): add F_PSEUDO flags
+ (krb5_keytype_to_enctypes): new function
+
+ * lib/krb5/auth_context.c (krb5_auth_con_init): initalize keytype
+ and cksumtype
+ (krb5_auth_setcksumtype, krb5_auth_getcksumtype): implement
+ (krb5_auth_setkeytype, krb5_auth_getkeytype): implement
+ (krb5_auth_setenctype): comment out, it's rather bogus anyway
+
+Sun Apr 25 16:55:50 1999 Johan Danielsson <joda@pdc.kth.se>
+
+ * lib/krb5/krb5_locl.h: fix for stupid aix warnings
+
+ * lib/krb5/fcache.c (erase_file): don't malloc
+
+Sat Apr 24 18:35:21 1999 Johan Danielsson <joda@pdc.kth.se>
+
+ * kdc/config.c: pass context to krb5_config_file_free
+
+ * kuser/kinit.c: add `--fcache-version' to set cache version to
+ create
+
+ * kuser/klist.c: print cache version if verbose
+
+ * lib/krb5/transited.c (krb5_domain_x500_decode): don't abort
+
+ * lib/krb5/principal.c: abort -> krb5_abortx
+
+ * lib/krb5/mk_rep.c: abort -> krb5_abortx
+
+ * lib/krb5/config_file.c: abort -> krb5_abortx
+
+ * lib/krb5/context.c (init_context_from_config_file): init
+ fcache_version; add krb5_{get,set}_fcache_version
+
+ * lib/krb5/keytab.c: add support for reading (and writing?) old
+ version keytabs
+
+ * lib/krb5/cache.c: add krb5_cc_get_version
+
+ * lib/krb5/fcache.c: add support for reading and writing old
+ version cache files
+
+ * lib/krb5/store_mem.c (krb5_storage_from_mem): zero flags
+
+ * lib/krb5/store_emem.c (krb5_storage_emem): zero flags
+
+ * lib/krb5/store_fd.c (krb5_storage_from_fd): zero flags
+
+ * lib/krb5/store.c: add flags to change how various fields are
+ stored, used for old cache version support
+
+ * lib/krb5/krb5.h: add support for reading and writing old version
+ cache files, and keytabs
+
+Wed Apr 21 00:09:26 1999 Assar Westerlund <assar@sics.se>
+
+ * configure.in: fix test for readline.h remember to link with
+ $LIB_tgetent when trying linking with readline
+
+ * lib/krb5/init_creds_pw.c (get_init_creds_common): if start_time
+ is given, request a postdated ticket.
+
+ * lib/krb5/data.c (krb5_data_free): free data as long as it's not
+ NULL
+
+Tue Apr 20 20:18:14 1999 Assar Westerlund <assar@sics.se>
+
+ * kpasswd/Makefile.am (kpasswdd_LDADD): add LIB_dlopen
+
+ * lib/krb5/krb5.h (KRB5_VERIFY_AP_REQ_IGNORE_INVALID): add
+
+ * lib/krb5/rd_req.c (krb5_decrypt_ticket): add `flags` and
+ KRB5_VERIFY_AP_REQ_IGNORE_INVALID for ignoring that the ticket is
+ invalid
+
+Tue Apr 20 12:42:08 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * kpasswd/kpasswdd.c: don't try to load library by default; get
+ library and function name from krb5.conf
+
+ * kpasswd/sample_passwd_check.c: sample password checking
+ functions
+
+Mon Apr 19 22:22:19 1999 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/store.c (krb5_storage_to_data, krb5_ret_data): use
+ krb5_data_alloc and be careful with checking allocation and sizes.
+
+ * kuser/klist.c (--tokens): conditionalize on KRB4
+
+ * kuser/kinit.c (renew_validate): set all flags
+ (main): fix cut-n-paste error when setting start-time
+
+ * kdc/kerberos5.c (check_tgs_flags): starttime of a validate
+ ticket should be > than current time
+ (*): send flags to krb5_verify_ap_req and krb5_decrypt_ticket
+
+ * kuser/kinit.c (renew_validate): use the client realm instead of
+ the local realm when renewing tickets.
+
+ * lib/krb5/get_for_creds.c (krb5_fwd_tgs_creds): compat function
+ (krb5_get_forwarded_creds): correct freeing of out_creds
+
+ * kuser/kinit.c (renew_validate): hopefully fix up freeing of
+ memory
+
+ * configure.in: do all the krb4 tests with "$krb4" != "no"
+
+ * lib/krb5/keyblock.c (krb5_free_keyblock_contents): don't zero
+ keyvalue if it's NULL. noticed by Ake Sandgren <ake@cs.umu.se>
+
+ * lib/krb5/get_in_tkt.c (add_padata): loop over all enctypes
+ instead of just taking the first one. fix all callers. From
+ "Brandon S. Allbery KF8NH" <allbery@kf8nh.apk.net>
+
+ * kdc/kdc_locl.h (enable_kaserver): declaration
+
+ * kdc/hprop.c (ka_convert): print the failing principal. AFS 3.4a
+ creates krbtgt.REALMOFCELL as NOTGS+NOSEAL, work around. From
+ "Brandon S. Allbery KF8NH" <allbery@kf8nh.apk.net>
+
+ * kdc/hpropd.c (open_socket): stupid cast to get rid of a warning
+
+ * kdc/connect.c (add_standard_ports, process_request): look at
+ enable_kaserver. From "Brandon S. Allbery KF8NH"
+ <allbery@kf8nh.apk.net>
+
+ * kdc/config.c: new flag --kaserver and config file option
+ enable-kaserver. From "Brandon S. Allbery KF8NH"
+ <allbery@kf8nh.apk.net>
+
+Mon Apr 19 12:32:04 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * configure.in: check for dlopen, and dlfcn.h
+
+ * kpasswd/kpasswdd.c: add support for dlopen:ing password quality
+ check library
+
+ * configure.in: add appl/su
+
+Sun Apr 18 15:46:53 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/cache.c: add krb5_cc_get_type that returns type of a
+ cache
+
+Fri Apr 16 17:58:51 1999 Assar Westerlund <assar@sics.se>
+
+ * configure.in: LIB_kdb: -L should be before -lkdb
+ test for prototype of strsep
+
+Thu Apr 15 11:34:38 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/krb5/Makefile.am: update version
+
+ * lib/krb5/get_for_creds.c (krb5_get_forwarded_creds): use
+ ALLOC_SEQ
+
+ * lib/krb5/fcache.c: add some support for reading and writing old
+ cache formats;
+ (fcc_store_cred): use krb5_store_creds; (fcc_read_cred): use
+ krb5_ret_creds
+
+ * lib/krb5/store_mem.c (krb5_storage_from_mem): check malloc,
+ initialize host_byteorder
+
+ * lib/krb5/store_fd.c (krb5_storage_from_fd): initialize
+ host_byteorder
+
+ * lib/krb5/store_emem.c (krb5_storage_emem): initialize
+ host_byteorder
+
+ * lib/krb5/store.c (krb5_storage_set_host_byteorder): add;
+ (krb5_store_int32,krb5_ret_int32,krb5_store_int16,krb5_ret_int16):
+ check host_byteorder flag; (krb5_store_creds): add;
+ (krb5_ret_creds): add
+
+ * lib/krb5/krb5.h (krb5_storage): add `host_byteorder' flag for
+ storage of numbers
+
+ * lib/krb5/heim_err.et: add `host not found' error
+
+ * kdc/connect.c: don't use data after clearing decriptor
+
+ * lib/krb5/auth_context.c: abort -> krb5_abortx
+
+ * lib/krb5/warn.c: add __attribute__; add *abort functions
+
+ * configure.in: check for __attribute__
+
+ * kdc/connect.c: log bogus requests
+
+Tue Apr 13 18:38:05 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/kadm5/create_s.c (kadm5_s_create_principal): create v4 salts
+ for all DES keys
+
+1999-04-12 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_cred.c (init_tgs_req): re-structure a little bit
+
+ * lib/krb5/get_cred.c (init_tgs_req): some more error checking
+
+ * lib/krb5/generate_subkey.c (krb5_generate_subkey): check return
+ value from malloc
+
+Sun Apr 11 03:47:23 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/krb5/krb5.conf.5: update to reality
+
+ * lib/krb5/krb5_425_conv_principal.3: update to reality
+
+1999-04-11 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_host_realm.c: handle more than one realm for a host
+
+ * kpasswd/kpasswd.c (main): use krb5_program_setup and
+ print_version
+
+ * kdc/string2key.c (main): use krb5_program_setup and
+ print_version
+
+Sun Apr 11 02:35:58 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/krb5/principal.c (krb5_524_conv_principal): make it actually
+ work, and check built-in list of host-type first-components
+
+ * lib/krb5/krbhst.c: lookup SRV-records to find a kdc for a realm
+
+ * lib/krb5/context.c: add srv_* flags to context
+
+ * lib/krb5/principal.c: add default v4_name_convert entries
+
+ * lib/krb5/krb5.h: add srv_* flags to context
+
+Sat Apr 10 22:52:28 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * kadmin/kadmin.c: complain about un-recognised commands
+
+ * admin/ktutil.c: complain about un-recognised commands
+
+Sat Apr 10 15:41:49 1999 Assar Westerlund <assar@sics.se>
+
+ * kadmin/load.c (doit): fix error message
+
+ * lib/krb5/crypto.c (encrypt_internal): free checksum if lengths
+ fail to match.
+ (krb5_get_wrapped_length): new function
+
+ * configure.in: security/pam_modules.h: check for
+
+ * lib/krb5/init_creds_pw.c (krb5_get_init_creds_password): kludge
+ around `ret_as_reply' semantics by only freeing it when ret == 0
+
+Fri Apr 9 20:24:04 1999 Assar Westerlund <assar@sics.se>
+
+ * kuser/klist.c (print_cred_verbose): handle the case of a bad
+ enctype
+
+ * configure.in: test for more header files
+ (LIB_roken): set
+
+Thu Apr 8 15:01:59 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * configure.in: fixes for building w/o krb4
+
+ * ltmain.sh: update to libtool 1.2d
+
+ * ltconfig: update to libtool 1.2d
+
+Wed Apr 7 23:37:26 1999 Assar Westerlund <assar@sics.se>
+
+ * kdc/hpropd.c: fix some error messages to be more understandable.
+
+ * kdc/hprop.c (ka_dump): remove unused variables
+
+ * appl/test/tcp_server.c: remove unused variables
+
+ * appl/test/gssapi_server.c: remove unused variables
+
+ * appl/test/gssapi_client.c: remove unused variables
+
+Wed Apr 7 14:05:15 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/krb5/context.c (krb5_get_err_text): long -> krb5_error_code
+
+ * kuser/klist.c: make it compile w/o krb4
+
+ * kuser/kdestroy.c: make it compile w/o krb4
+
+ * admin/ktutil.c: fix {srv,key}2{srv,key}tab confusion; add help
+ strings
+
+Mon Apr 5 16:13:46 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * configure.in: test for MIPS ABI; new test_package
+
+Thu Apr 1 11:00:40 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * include/Makefile.am: clean krb5-private.h
+
+ * Release 0.1d
+
+ * kpasswd/kpasswdd.c (doit): pass context to
+ krb5_get_all_client_addrs
+
+ * kdc/connect.c (init_sockets): pass context to
+ krb5_get_all_server_addrs
+
+ * lib/krb5/get_in_tkt.c (init_as_req): pass context to
+ krb5_get_all_client_addrs
+
+ * lib/krb5/get_cred.c (get_cred_kdc_la): pass context to
+ krb5_get_all_client_addrs
+
+ * lib/krb5/get_addrs.c (get_addrs_int): add extra host addresses
+
+ * lib/krb5/krb5.h: add support for adding an extra set of
+ addresses
+
+ * lib/krb5/context.c: add support for adding an extra set of
+ addresses
+
+ * lib/krb5/addr_families.c: add krb5_parse_address
+
+ * lib/krb5/address.c: krb5_append_addresses
+
+ * lib/krb5/config_file.c (parse_binding): don't zap everything
+ after first whitespace
+
+ * kuser/kinit.c (renew_validate): don't allocate out
+
+ * lib/krb5/get_for_creds.c (krb5_get_forwarded_creds): don't
+ allocate out_creds
+
+ * lib/krb5/get_cred.c (get_cred_kdc, get_cred_kdc_la): make
+ out_creds pointer;
+ (krb5_get_kdc_cred): allocate out_creds; (get_cred_from_kdc_flags):
+ free more memory
+
+ * lib/krb5/crypto.c (encrypt_internal): free checksum
+
+ * lib/krb5/convert_creds.c (krb524_convert_creds_kdc): free reply,
+ and ticket
+
+ * kuser/Makefile.am: remove kfoo
+
+ * lib/Makefile.am: add auth
+
+ * lib/kadm5/iprop.h: getarg.h
+
+ * lib/kadm5/replay_log.c: use getarg
+
+ * lib/kadm5/ipropd_slave.c: use getarg
+
+ * lib/kadm5/ipropd_master.c: use getarg
+
+ * lib/kadm5/dump_log.c: use getarg
+
+ * kpasswd/kpasswdd.c: use getarg
+
+ * Makefile.am.common: make a more working check-local target
+
+ * lib/asn1/main.c: use getargs
+
+Mon Mar 29 20:19:57 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * kuser/klist.c (print_cred_verbose): use krb5_print_address
+
+ * lib/kadm5/server.c: k_{put,get}_int -> _krb5_{put,get}_int
+
+ * lib/krb5/addr_families.c (krb5_print_address): handle unknown
+ address types; (ipv6_print_addr): print in 16-bit groups (as it
+ should)
+
+ * lib/krb5/crc.c: crc_{init_table,update} ->
+ _krb5_crc_{init_table,update}
+
+ * lib/krb5/crypto.c: k_{put,get}_int -> _krb5_{put,get}_int
+ crc_{init_table,update} -> _krb5_crc_{init_table,update}
+
+ * lib/krb5/send_to_kdc.c: k_{put,get}_int -> _krb5_{put,get}_int
+
+ * lib/krb5/store.c: k_{put,get}_int -> _krb5_{put,get}_int
+
+ * lib/krb5/krb5_locl.h: include krb5-private.h
+
+ * kdc/connect.c (addr_to_string): use krb5_print_address
+
+ * lib/krb5/addr_families.c (krb5_print_address): int -> size_t
+
+ * lib/krb5/addr_families.c: add support for printing ipv6
+ addresses, either with inet_ntop, or ugly for-loop
+
+ * kdc/524.c: check that the ticket came from a valid address; use
+ the address of the connection as the address to put in the v4
+ ticket (if this address is AF_INET)
+
+ * kdc/connect.c: pass addr to do_524
+
+ * kdc/kdc_locl.h: prototype for do_524
+
+Sat Mar 27 17:48:31 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * configure.in: check for OSF C2; bind/bitypes.h, getudbnam,
+ setlim; check for auth modules; siad.h, getpwnam_r;
+ lib/auth/Makefile, lib/auth/sia/Makefile
+
+ * lib/krb5/crypto.c: n_fold -> _krb5_n_fold
+
+ * lib/krb5/n-fold.c: n_fold -> _krb5_n_fold
+
+Thu Mar 25 04:35:21 1999 Assar Westerlund <assar@sics.se>
+
+ * lib/kadm5/set_keys.c (_kadm5_set_keys): free salt when zapping
+ it
+
+ * lib/kadm5/free.c (kadm5_free_principal_ent): free `key_data'
+
+ * lib/hdb/ndbm.c (NDBM_destroy): clear master key
+
+ * lib/hdb/db.c (DB_destroy): clear master key
+ (DB_open): check malloc
+
+ * kdc/connect.c (init_sockets): free addresses
+
+ * kadmin/kadmin.c (main): make code more consistent. always free
+ configuration information.
+
+ * kadmin/init.c (create_random_entry): free the entry
+
+Wed Mar 24 04:02:03 1999 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/init_creds_pw.c (krb5_get_init_creds_password):
+ re-organize the code to always free `kdc_reply'
+
+ * lib/krb5/get_in_tkt.c (krb5_get_in_cred): be more careful about
+ freeing memory
+
+ * lib/krb5/fcache.c (fcc_destroy): don't call fcc_close
+
+ * lib/krb5/crypto.c (krb5_crypto_destroy): free `crypto'
+
+ * lib/hdb/hdb_locl.h: try db_185.h first in case db.h is a DB 2.0
+ header
+
+ * configure.in (db_185.h): check for
+
+ * admin/srvcreate.c: new file. contributed by Daniel Kouril
+ <kouril@informatics.muni.cz>
+
+ * admin/ktutil.c: srvcreate: new command
+
+ * kuser/klist.c: add support for printing AFS tokens
+
+ * kuser/kdestroy.c: add support for destroying v4 tickets and AFS
+ tokens. based on code by Love <lha@stacken.kth.se>
+
+ * kuser/Makefile.am (kdestroy_LDADD, klist_LDADD): more libraries
+
+ * configure.in: sys/ioccom.h: test for
+
+ * kuser/klist.c (main): don't print `no ticket file' with --test.
+ From: Love <lha@e.kth.se>
+
+ * kpasswd/kpasswdd.c (doit): more braces to make gcc happy
+
+ * kdc/connect.c (init_socket): get rid of a stupid warning
+
+ * include/bits.c (my_strupr): cast away some stupid warnings
+
+Tue Mar 23 14:34:44 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/krb5/get_host_realm.c (krb5_get_host_realm): no infinite
+ loops, please
+
+Tue Mar 23 00:00:45 1999 Assar Westerlund <assar@sics.se>
+
+ * lib/kadm5/Makefile.am (install_build_headers): recover from make
+ rewriting the names of the headers kludge to help solaris make
+
+ * lib/krb5/Makefile.am: kludge to help solaris make
+
+ * lib/hdb/Makefile.am: kludge to help solaris make
+
+ * configure.in (LIB_kdb): make sure there's a -L option in here by
+ adding $(LIB_krb4)
+
+ * lib/asn1/gen_glue.c (generate_2int, generate_int2): int ->
+ unsigned
+
+ * configure.in (SunOS): set to a number KRB4, KRB5 conditionals:
+ remove the `dnl' to work around an automake flaw
+
+Sun Mar 21 15:08:49 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/get_default_realm.c: char* -> krb5_realm
+
+Sun Mar 21 14:08:30 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * include/bits.c: <bind/bitypes.h>
+
+ * lib/krb5/Makefile.am: create krb5-private.h
+
+Sat Mar 20 00:08:59 1999 Assar Westerlund <assar@sics.se>
+
+ * configure.in (gethostname): remove duplicate
+
+Fri Mar 19 14:48:03 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/hdb/Makefile.am: add version-info
+
+ * lib/gssapi/Makefile.am: add version-info
+
+ * lib/asn1/Makefile.am: use $(x:y=z) make syntax; move check-der
+ to check_PROGRAMS
+
+ * lib/Makefile.am: add 45
+
+ * lib/kadm5/Makefile.am: split in client and server libraries
+ (breaks shared libraries otherwise)
+
+Thu Mar 18 11:33:30 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * include/kadm5/Makefile.am: clean a lot of header files (since
+ automake lacks a clean-hook)
+
+ * include/Makefile.am: clean a lot of header files (since automake
+ lacks a clean-hook)
+
+ * lib/kadm5/Makefile.am: fix build-installation of headers
+
+ * lib/krb5/Makefile.am: remove include_dir hack
+
+ * lib/hdb/Makefile.am: remove include_dir hack
+
+ * lib/asn1/Makefile.am: remove include_dir hack
+
+ * include/Makefile.am: remove include_dir hack
+
+ * doc/whatis.texi: define sub for html
+
+ * configure.in: LIB_kdb, have_err_h, have_fnmatch_h, have_glob_h
+
+ * lib/asn1/Makefile.am: der.h
+
+ * kpasswd/kpasswdd.c: admin.h -> kadm5/admin.h
+
+ * kdc/Makefile.am: remove junk
+
+ * kadmin/Makefile.am: sl.a -> sl.la
+
+ * appl/afsutil/Makefile.am: remove EXTRA_bin_PROGRAMS
+
+ * admin/Makefile.am: sl.a -> sl.la
+
+ * configure.in: condition KRB5; AC_CHECK_XAU
+
+ * Makefile.am: include Makefile.am.common
+
+ * include/kadm5/Makefile.am: include Makefile.am.common; don't
+ install headers from here
+
+ * include/Makefile.am: include Makefile.am.common; don't install
+ headers from here
+
+ * doc/Makefile.am: include Makefile.am.common
+
+ * lib/krb5/Makefile.am: include Makefile.am.common
+
+ * lib/kadm5/Makefile.am: include Makefile.am.common
+
+ * lib/hdb/Makefile.am: include Makefile.am.common
+
+ * lib/gssapi/Makefile.am: include Makefile.am.common
+
+ * lib/asn1/Makefile.am: include Makefile.am.common
+
+ * lib/Makefile.am: include Makefile.am.common
+
+ * lib/45/Makefile.am: include Makefile.am.common
+
+ * kuser/Makefile.am: include Makefile.am.common
+
+ * kpasswd/Makefile.am: include Makefile.am.common
+
+ * kdc/Makefile.am: include Makefile.am.common
+
+ * kadmin/Makefile.am: include Makefile.am.common
+
+ * appl/test/Makefile.am: include Makefile.am.common
+
+ * appl/afsutil/Makefile.am: include Makefile.am.common
+
+ * appl/Makefile.am: include Makefile.am.common
+
+ * admin/Makefile.am: include Makefile.am.common
+
+Wed Mar 17 03:04:38 1999 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/store.c (krb5_store_stringz): braces fix
+
+ * lib/kadm5/get_s.c (kadm5_s_get_principal): braces fix
+
+ * lib/kadm5/ent_setup.c (_kadm5_setup_entry): braces fix
+
+ * kdc/connect.c (loop): braces fix
+
+ * lib/krb5/config_file.c: cast to unsigned char to make is* happy
+
+ * lib/krb5/log.c (krb5_addlog_dest): more braces to make gcc happy
+
+ * lib/krb5/crypto.c (krb5_verify_checksum): rename C -> cksum to
+ be consistent
+
+ * kadmin/util.c (timeval2str): more braces to make gcc happy
+
+ * kadmin/load.c: cast in is* to get rid of stupid warning
+
+ * kadmin/dump.c (append_hex): cast in isalnum to get rid of stupid
+ warning
+
+ * kdc/kaserver.c: malloc checks and fixes
+
+ * lib/krb5/get_host_realm.c (krb5_get_host_realm): include leading
+ dot (if any) when looking up realms.
+
+Fri Mar 12 13:57:56 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/get_host_realm.c: add dns support
+
+ * lib/krb5/set_default_realm.c: use krb5_free_host_realm
+
+ * lib/krb5/free_host_realm.c: check for NULL realmlist
+
+ * lib/krb5/context.c: don't print warning if there is no krb5.conf
+
+Wed Mar 10 19:29:46 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * configure.in: use AC_WFLAGS
+
+Mon Mar 8 11:49:43 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Release 0.1c
+
+ * kuser/klist.c: use print_version
+
+ * kuser/kdestroy.c: use print_version
+
+ * kdc/hpropd.c: use print_version
+
+ * kdc/hprop.c: use print_version
+
+ * kdc/config.c: use print_version
+
+ * kadmin/kadmind.c: use print_version
+
+ * kadmin/kadmin.c: use print_version
+
+ * appl/test/common.c: use print_version
+
+ * appl/afsutil/afslog.c: use print_version
+
+Mon Mar 1 10:49:14 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/krb5/get_addrs.c: SOCKADDR_HAS_SA_LEN ->
+ HAVE_STRUCT_SOCKADDR_SA_LEN
+
+ * configure.in, acconfig.h, cf/*: update to automake 1.4/autoconf 2.13
+
+Sun Feb 28 18:19:20 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/asn1/gen.c: make `BIT STRING's unsigned
+
+ * lib/asn1/{symbol.h,gen.c}: add TUInteger type
+
+ * lib/krb5/verify_user.c (krb5_verify_user): pass prompter to
+ krb5_get_init_creds_password
+
+ * lib/krb5/fcache.c (fcc_gen_new): implement
+
+Sat Feb 27 22:41:23 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * doc/install.texi: krb4 is now automatically detected
+
+ * doc/misc.texi: update procedure to set supported encryption
+ types
+
+ * doc/setup.texi: change some silly wordings
+
+Sat Feb 27 22:17:30 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/keytab.c (fkt_remove_entry): make this work
+
+ * admin/ktutil.c: add minimally working `get' command
+
+Sat Feb 27 19:44:49 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/hdb/convert_db.c: more typos
+
+ * include/Makefile.am: remove EXTRA_DATA (as of autoconf
+ 2.13/automake 1.4)
+
+ * appl/Makefile.am: OTP_dir
+
+Fri Feb 26 17:37:00 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * doc/setup.texi: add kadmin section
+
+ * lib/asn1/check-der.c: fix printf warnings
+
+Thu Feb 25 11:16:49 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * configure.in: -O does not belong in WFLAGS
+
+Thu Feb 25 11:05:57 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/asn1/der_put.c: fix der_put_int
+
+Tue Feb 23 20:35:12 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * configure.in: use AC_BROKEN_GLOB
+
+Mon Feb 22 15:12:44 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * configure.in: check for glob
+
+Mon Feb 22 11:32:42 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Release 0.1b
+
+Sat Feb 20 15:48:06 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/hdb/convert_db.c: convert DES3 keys to des3-cbc-sha1, and
+ des3-cbc-md5
+
+ * lib/krb5/crypto.c (DES3_string_to_key): make this actually do
+ what the draft said it should
+
+ * lib/hdb/convert_db.c: little program for database conversion
+
+ * lib/hdb/db.c (DB_open): try to open database w/o .db extension
+
+ * lib/hdb/ndbm.c (NDBM_open): add test for database format
+
+ * lib/hdb/db.c (DB_open): add test for database format
+
+ * lib/asn1/gen_glue.c (generate_2int): don't depend on flags being
+ unsigned
+
+ * lib/hdb/hdb.c: change `hdb_set_master_key' to take an
+ EncryptionKey, and add a new function `hdb_set_master_keyfile' to
+ do what `hdb_set_master_key' used to do
+
+ * kdc/kstash.c: add `--convert-file' option to change keytype of
+ existing master key file
+
+Fri Feb 19 07:04:14 1999 Assar Westerlund <assar@squid.pdc.kth.se>
+
+ * Release 0.1a
+
+Sat Feb 13 17:12:53 1999 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/mk_safe.c (krb5_mk_safe): sizeof(buf) -> buf_size, buf
+ is now a `u_char *'
+
+ * lib/krb5/get_in_tkt.c (krb5_init_etype): etypes are now `int'
+
+ * lib/krb5/get_host_realm.c (krb5_get_host_realm): constize
+ orig_host
+
+ (krb5_salttype_to_string): new function (RSA_MD5_DES_verify,
+ RSA_MD5_DES3_verify): initialize ret
+
+ * lib/gssapi/init_sec_context.c (init_auth): remove unnecessary
+ gssapi_krb5_init. ask for KEYTYPE_DES credentials
+
+ * kadmin/get.c (print_entry_long): print the keytypes and salts
+ available for the principal
+
+ * configure.in (WFLAGS): add `-O' to catch unitialized variables
+ and such
+ (gethostname, mkstemp, getusershell, inet_aton): more tests
+
+ * lib/hdb/hdb.h: update prototypes
+
+ * configure.in: homogenize broken detection with krb4
+
+ * lib/kadm5/init_c.c (kadm5_c_init_with_context): remove unused
+ `error'
+
+ * lib/asn1/Makefile.am (check-der): add
+
+ * lib/asn1/gen.c (define_type): map ASN1 Integer to `int' instead
+ of `unsigned'
+
+ * lib/asn1/der_length.c (length_unsigned): new function
+ (length_int): handle signed integers
+
+ * lib/asn1/der_put.c (der_put_unsigned): new function
+ (der_put_int): handle signed integers
+
+ * lib/asn1/der_get.c (der_get_unsigned): new function
+ (der_get_int): handle signed integers
+
+ * lib/asn1/der.h: all integer functions take `int' instead of
+ `unsigned'
+
+ * lib/asn1/lex.l (filename): unused. remove.
+
+ * lib/asn1/check-der.c: new test program for der encoding and
+ decoding.
+
+Mon Feb 1 04:09:06 1999 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/send_to_kdc.c (krb5_sendto_kdc): only call
+ gethostbyname2 with AF_INET6 if we actually have IPv6. From
+ "Brandon S. Allbery KF8NH" <allbery@kf8nh.apk.net>
+
+ * lib/krb5/changepw.c (get_kdc_address): dito
+
+Sun Jan 31 06:26:36 1999 Assar Westerlund <assar@sics.se>
+
+ * kdc/connect.c (parse_prots): always bind to AF_INET, there are
+ v6-implementations without support for `mapped V4 addresses'.
+ From Jun-ichiro itojun Hagino <itojun@kame.net>
+
+Sat Jan 30 22:38:27 1999 Assar Westerlund <assar@juguete.sics.se>
+
+ * Release 0.0u
+
+Sat Jan 30 13:43:02 1999 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/Makefile.am: explicit rules for *.et files
+
+ * lib/kadm5/init_c.c (get_kadm_ticket): only remove creds if
+ krb5_get_credentials was succesful.
+ (get_new_cache): return better error codes and return earlier.
+ (get_cred_cache): only delete default_client if it's different
+ from client
+ (kadm5_c_init_with_context): return a more descriptive error.
+
+ * kdc/kerberos5.c (check_flags): handle NULL client or server
+
+ * lib/krb5/sendauth.c (krb5_sendauth): return the error in
+ `ret_error' iff != NULL
+
+ * lib/krb5/rd_error.c (krb5_free_error, krb5_free_error_contents):
+ new functions
+
+ * lib/krb5/mk_req_ext.c (krb5_mk_req_extended): more
+ type-correctness
+
+ * lib/krb5/krb5.h (krb5_error): typedef to KRB_ERROR
+
+ * lib/krb5/init_creds_pw.c: KRB5_TGS_NAME: use
+
+ * lib/krb5/get_cred.c: KRB5_TGS_NAME: use
+
+ * lib/kafs/afskrb5.c (afslog_uid_int): update to changes
+
+ * lib/kadm5/rename_s.c (kadm5_s_rename_principal): call remove
+ instead of rename, but shouldn't this just call rename?
+
+ * lib/kadm5/get_s.c (kadm5_s_get_principal): always return an
+ error if the principal wasn't found.
+
+ * lib/hdb/ndbm.c (NDBM_seq): unseal key
+
+ * lib/hdb/db.c (DB_seq): unseal key
+
+ * lib/asn1/Makefile.am: added explicit rules for asn1_err.[ch]
+
+ * kdc/hprop.c (v4_prop): add krbtgt/THISREALM@OTHERREALM when
+ finding cross-realm tgts in the v4 database
+
+ * kadmin/mod.c (mod_entry): check the number of arguments. check
+ that kadm5_get_principal worked.
+
+ * lib/krb5/keytab.c (fkt_remove_entry): remove KRB5_KT_NOTFOUND if
+ we weren't able to remove it.
+
+ * admin/ktutil.c: less drive-by-deleting. From Love
+ <lha@e.kth.se>
+
+ * kdc/connect.c (parse_ports): copy the string before mishandling
+ it with strtok_r
+
+ * kdc/kerberos5.c (tgs_rep2): print the principal with mismatching
+ kvnos
+
+ * kadmin/kadmind.c (main): convert `debug_port' to network byte
+ order
+
+ * kadmin/kadmin.c: allow specification of port number.
+
+ * lib/kadm5/kadm5_locl.h (kadm5_client_context): add
+ `kadmind_port'.
+
+ * lib/kadm5/init_c.c (_kadm5_c_init_context): move up
+ initalize_kadm5_error_table_r.
+ allow specification of port number.
+
+ From Love <lha@stacken.kth.se>
+
+ * kuser/klist.c: add option -t | --test
+
+Sat Dec 5 19:49:34 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/krb5/context.c: remove ktype_is_etype
+
+ * lib/krb5/crypto.c, lib/krb5/krb5.h, acconfig.h: NEW_DES3_CODE
+
+ * configure.in: fix for AIX install; better tests for AIX dynamic
+ AFS libs; `--enable-new-des3-code'
+
+Tue Dec 1 14:44:44 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * appl/afsutil/Makefile.am: link with extra libs for aix
+
+ * kuser/Makefile.am: link with extra libs for aix
+
+Sun Nov 29 01:56:21 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_addrs.c (krb5_get_all_server_addrs): add. almost
+ the same as krb5_get_all_client_addrs except that it includes
+ loopback addresses
+
+ * kdc/connect.c (init_socket): bind to a particular address
+ (init_sockets): get all local addresses and bind to them all
+
+ * lib/krb5/addr_families.c (addr2sockaddr, print_addr): new
+ methods
+ (find_af, find_atype): new functions. use them.
+
+ * configure.in: add hesiod
+
+Wed Nov 25 11:37:48 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/krb5/krb5_err.et: add some codes from kerberos-revisions-03
+
+Mon Nov 23 12:53:48 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/kadm5/log.c: rename delete -> remove
+
+ * lib/kadm5/delete_s.c: rename delete -> remove
+
+ * lib/hdb/common.c: rename delete -> remove
+
+Sun Nov 22 12:26:26 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: check for environ and `struct spwd'
+
+Sun Nov 22 11:42:45 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * kdc/kerberos5.c (as_rep): set keytype to sess_ktype if
+ ktype_is_etype
+
+ * lib/krb5/encrypt.c (krb5_keytype_to_etypes): zero terminate
+ etypes
+ (em): sort entries
+
+Sun Nov 22 06:54:48 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/init_creds_pw.c: more type correctness
+
+ * lib/krb5/get_cred.c: re-structure code. remove limits on ASN1
+ generated bits.
+
+Sun Nov 22 01:49:50 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * kdc/hprop.c (v4_prop): fix bogus indexing
+
+Sat Nov 21 21:39:20 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/verify_init.c (fail_verify_is_ok): new function
+ (krb5_verify_init_creds): if we cannot get a ticket for
+ host/`hostname` and fail_verify_is_ok just return. use
+ krb5_rd_req
+
+Sat Nov 21 23:12:27 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/free.c (krb5_xfree): new function
+
+ * lib/krb5/creds.c (krb5_free_creds_contents): new function
+
+ * lib/krb5/context.c: more type correctness
+
+ * lib/krb5/checksum.c: more type correctness
+
+ * lib/krb5/auth_context.c (krb5_auth_con_init): more type
+ correctness
+
+ * lib/asn1/der_get.c (der_get_length): fix test of len
+ (der_get_tag): more type correctness
+
+ * kuser/klist.c (usage): void-ize
+
+ * admin/ktutil.c (kt_remove): some more type correctness.
+
+Sat Nov 21 16:49:20 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * kuser/klist.c: try to list enctypes as keytypes
+
+ * kuser/kinit.c: remove extra `--cache' option, add `--enctypes'
+ to set list of enctypes to use
+
+ * kadmin/load.c: load strings as hex
+
+ * kadmin/dump.c: dump hex as string is possible
+
+ * admin/ktutil.c: use print_version()
+
+ * configure.in, acconfig.h: test for hesiod
+
+Sun Nov 15 17:28:19 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/krb5/crypto.c: add some crypto debug code
+
+ * lib/krb5/get_in_tkt.c (_krb5_extract_ticket): don't use fixed
+ buffer when encoding ticket
+
+ * lib/krb5/auth_context.c (re-)implement `krb5_auth_setenctype'
+
+ * kdc/kerberos5.c: allow mis-match of tgt session key, and service
+ session key
+
+ * admin/ktutil.c: keytype -> enctype
+
+Fri Nov 13 05:35:48 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/krb5.h (KRB5_TGS_NAME, KRB5_TGS_NAME_SIZE): added
+
+Sat Nov 7 19:56:31 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_cred.c (add_cred): add termination NULL pointer
+
+Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/rd_req.c: adapt to new crypto api
+
+ * lib/krb5/rd_rep.c: adapt to new crypto api
+
+ * lib/krb5/rd_priv.c: adopt to new crypto api
+
+ * lib/krb5/rd_cred.c: adopt to new crypto api
+
+ * lib/krb5/principal.c: ENOMEM -> ERANGE
+
+ * lib/krb5/mk_safe.c: cleanup and adopt to new crypto api
+
+ * lib/krb5/mk_req_ext.c: adopt to new crypto api
+
+ * lib/krb5/mk_req.c: get enctype from auth_context keyblock
+
+ * lib/krb5/mk_rep.c: cleanup and adopt to new crypto api
+
+ * lib/krb5/mk_priv.c: adopt to new crypto api
+
+ * lib/krb5/keytab.c: adopt to new crypto api
+
+ * lib/krb5/get_in_tkt_with_skey.c: adopt to new crypto api
+
+ * lib/krb5/get_in_tkt_with_keytab.c: adopt to new crypto api
+
+ * lib/krb5/get_in_tkt_pw.c: adopt to new crypto api
+
+ * lib/krb5/get_in_tkt.c: adopt to new crypto api
+
+ * lib/krb5/get_cred.c: adopt to new crypto api
+
+ * lib/krb5/generate_subkey.c: use new crypto api
+
+ * lib/krb5/context.c: rename etype functions to enctype ditto
+
+ * lib/krb5/build_auth.c: use new crypto api
+
+ * lib/krb5/auth_context.c: remove enctype and cksumtype from
+ auth_context
+
+Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se>
+
+ * kdc/connect.c (handle_udp, handle_tcp): correct type of `n'
+
+Tue Sep 15 18:41:38 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * admin/ktutil.c: fix printing of unrecognized keytypes
+
+Tue Sep 15 17:02:33 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/kadm5/set_keys.c: add KEYTYPE_USE_AFS3_SALT to keytype if
+ using AFS3 salt
+
+Tue Aug 25 23:30:52 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/send_to_kdc.c (krb5_sendto_kdc): care about
+ `use_admin_kdc'
+
+ * lib/krb5/changepw.c (get_kdc_address): use
+ krb5_get_krb_admin_hst
+
+ * lib/krb5/krbhst.c (krb5_get_krb_admin_hst): new function
+
+ * lib/krb5/krb5.h (krb5_context_data): add `use_admin_kdc'
+
+ * lib/krb5/context.c (krb5_get_use_admin_kdc,
+ krb5_set_use_admin_kdc): new functions
+
+Tue Aug 18 22:24:12 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/crypto.c: remove all calls to abort(); check return
+ value from _key_schedule;
+ (RSA_MD[45]_DES_verify): zero tmp and res;
+ (RSA_MD5_DES3_{verify,checksum}): implement
+
+Mon Aug 17 20:18:46 1998 Assar Westerlund <assar@sics.se>
+
+ * kdc/kerberos4.c (swap32): conditionalize
+
+ * lib/krb5/mk_req_ext.c (krb5_mk_req_internal): new function
+
+ * lib/krb5/get_host_realm.c (krb5_get_host_realm): if the hostname
+ returned from gethostby*() isn't a FQDN, try with the original
+ hostname
+
+ * lib/krb5/get_cred.c (make_pa_tgs_req): use krb5_mk_req_internal
+ and correct key usage
+
+ * lib/krb5/crypto.c (verify_checksum): make static
+
+ * admin/ktutil.c (kt_list): use krb5_enctype_to_string
+
+Sun Aug 16 20:57:56 1998 Assar Westerlund <assar@sics.se>
+
+ * kadmin/cpw.c (do_cpw_entry): use asprintf for the prompt
+
+ * kadmin/ank.c (ank): print principal name in prompt
+
+ * lib/krb5/crypto.c (hmac): always allocate space for checksum.
+ never trust c.checksum.length
+ (_get_derived_key): try to return the derived key
+
+Sun Aug 16 19:48:42 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/crypto.c (hmac): fix some peculiarities and bugs
+ (get_checksum_key): assume usage is `formatted'
+ (create_checksum,verify_checksum): moved the guts of the krb5_*
+ functions here, both take `formatted' key-usages
+ (encrypt_internal_derived): fix various bogosities
+ (derive_key): drop key_type parameter (already given by the
+ encryption_type)
+
+ * kdc/kerberos5.c (check_flags): handle case where client is NULL
+
+ * kdc/connect.c (process_request): return zero after processing
+ kerberos 4 request
+
+Sun Aug 16 18:38:15 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/crypto.c: merge x-*.[ch] into one file
+
+ * lib/krb5/cache.c: remove residual from krb5_ccache_data
+
+Fri Aug 14 16:28:23 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/x-crypto.c (derive_key): move DES3 specific code to
+ separate function (will eventually end up someplace else)
+
+ * lib/krb5/x-crypto.c (krb5_string_to_key_derived): allocate key
+
+ * configure.in, acconfig.h: test for four valued krb_put_int
+
+Thu Aug 13 23:46:29 1998 Assar Westerlund <assar@emma.pdc.kth.se>
+
+ * Release 0.0t
+
+Thu Aug 13 22:40:17 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/config_file.c (parse_binding): remove trailing
+ whitespace
+
+Wed Aug 12 20:15:11 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/x-checksum.c (krb5_verify_checksum): pass checksum type
+ to krb5_create_checksum
+
+ * lib/krb5/x-key.c: implement DES3_string_to_key_derived; fix a
+ few typos
+
+Wed Aug 5 12:39:54 1998 Assar Westerlund <assar@emma.pdc.kth.se>
+
+ * Release 0.0s
+
+Thu Jul 30 23:12:17 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/mk_error.c (krb5_mk_error): realloc until you die
+
+Thu Jul 23 19:49:03 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kdc_locl.h: proto for `get_des_key'
+
+ * configure.in: test for four valued el_init
+
+ * kuser/klist.c: keytype -> enctype
+
+ * kpasswd/kpasswdd.c (change): use new `krb5_string_to_key*'
+
+ * kdc/hprop.c (v4_prop, ka_convert): convert to a set of keys
+
+ * kdc/kaserver.c: use `get_des_key'
+
+ * kdc/524.c: use new crypto api
+
+ * kdc/kerberos4.c: use new crypto api
+
+ * kdc/kerberos5.c: always treat keytypes as enctypes; use new
+ crypto api
+
+ * kdc/kstash.c: adapt to new crypto api
+
+ * kdc/string2key.c: adapt to new crypto api
+
+ * admin/srvconvert.c: add keys for all possible enctypes
+
+ * admin/ktutil.c: keytype -> enctype
+
+ * lib/gssapi/init_sec_context.c: get enctype from auth_context
+ keyblock
+
+ * lib/hdb/hdb.c: remove hdb_*_keytype2key
+
+ * lib/kadm5/set_keys.c: adapt to new crypto api
+
+ * lib/kadm5/rename_s.c: adapt to new crypto api
+
+ * lib/kadm5/get_s.c: adapt to new crypto api
+
+ * lib/kadm5/create_s.c: add keys for des-cbc-crc, des-cbc-md4,
+ des-cbc-md5, and des3-cbc-sha1
+
+ * lib/krb5/heim_err.et: error message for unsupported salt
+
+ * lib/krb5/codec.c: short-circuit these functions, since they are
+ not needed any more
+
+ * lib/krb5/rd_safe.c: cleanup and adapt to new crypto api
+
+Mon Jul 13 23:00:59 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/send_to_kdc.c (krb5_sendto_kdc): don't advance
+ hostent->h_addr_list, use a copy instead
+
+Mon Jul 13 15:00:31 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/config_file.c (parse_binding, parse_section): make sure
+ everything is ok before adding to linked list
+
+ * lib/krb5/config_file.c: skip ws before checking for comment
+
+Wed Jul 8 10:45:45 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/asn1/k5.asn1: hmac-sha1-des3 = 12
+
+Tue Jun 30 18:08:05 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/send_to_kdc.c (krb5_sendto_kdc): do not close the
+ unopened file
+
+ * lib/krb5/mk_priv.c: realloc correctly
+
+ * lib/krb5/get_addrs.c (find_all_addresses): init j
+
+ * lib/krb5/context.c (krb5_init_context): print error if parsing
+ of config file produced an error.
+
+ * lib/krb5/config_file.c (parse_list, krb5_config_parse_file):
+ ignore more spaces
+
+ * lib/krb5/codec.c (krb5_encode_EncKrbCredPart,
+ krb5_encode_ETYPE_INFO): initialize `ret'
+
+ * lib/krb5/build_auth.c (krb5_build_authenticator): realloc
+ correctly
+
+ * lib/kadm5/set_keys.c (_kadm5_set_keys): initialize `ret'
+
+ * lib/kadm5/init_c.c (get_cred_cache): try to do the right thing
+ with default_client
+
+ * kuser/kinit.c (main): initialize `ticket_life'
+
+ * kdc/kerberos5.c (get_pa_etype_info): initialize `ret'
+ (tgs_rep2): initialize `krbtgt'
+
+ * kdc/connect.c (do_request): check for errors from `sendto'
+
+ * kdc/524.c (do_524): initialize `ret'
+
+ * kadmin/util.c (foreach_principal): don't clobber `ret'
+
+ * kadmin/del.c (del_entry): don't apply on zeroth argument
+
+ * kadmin/cpw.c (do_cpw_entry): initialize `ret'
+
+Sat Jun 13 04:14:01 1998 Assar Westerlund <assar@juguete.sics.se>
+
+ * Release 0.0r
+
+Sun Jun 7 04:13:14 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/addr_families.c: fall-back definition of
+ IN6_ADDR_V6_TO_V4
+
+ * configure.in: only set CFLAGS if it wasn't set look for
+ dn_expand and res_search
+
+Mon Jun 1 21:28:07 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: remove duplicate seteuid
+
+Sat May 30 00:19:51 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/convert_creds.c: import _krb_time_to_life, to avoid
+ runtime dependencies on libkrb with some shared library
+ implementations
+
+Fri May 29 00:09:02 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kuser/kinit_options.c: Default options for kinit.
+
+ * kuser/kauth_options.c: Default options for kauth.
+
+ * kuser/kinit.c: Implement lots a new options.
+
+ * kdc/kerberos5.c (check_tgs_flags): make sure kdc-req-body->rtime
+ is not NULL; set endtime to min of new starttime + old_life, and
+ requested endtime
+
+ * lib/krb5/init_creds_pw.c (get_init_creds_common): if the
+ forwardable or proxiable flags are set in options, set the
+ kdc-flags to the value specified, and not always to one
+
+Thu May 28 21:28:06 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kerberos5.c: Optionally compare client address to addresses
+ in ticket.
+
+ * kdc/connect.c: Pass client address to as_rep() and tgs_rep().
+
+ * kdc/config.c: Add check_ticket_addresses, and
+ allow_null_ticket_addresses variables.
+
+Tue May 26 14:03:42 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/kadm5/create_s.c: possibly make DES keys version 4 salted
+
+ * lib/kadm5/set_keys.c: check config file for kadmin/use_v4_salt
+ before zapping version 4 salts
+
+Sun May 24 05:22:17 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.0q
+
+ * lib/krb5/aname_to_localname.c: new file
+
+ * lib/gssapi/init_sec_context.c (repl_mutual): no output token
+
+ * lib/gssapi/display_name.c (gss_display_name): zero terminate
+ output.
+
+Sat May 23 19:11:07 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/gssapi/display_status.c: new file
+
+ * Makefile.am: send -I to aclocal
+
+ * configure.in: remove duplicate setenv
+
+Sat May 23 04:55:19 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kadmin/util.c (foreach_principal): Check for expression before
+ wading through the whole database.
+
+ * kadmin/kadmin.c: Pass NULL password to
+ kadm5_*_init_with_password.
+
+ * lib/kadm5/init_c.c: Implement init_with_{skey,creds}*. Make use
+ of `password' parameter to init_with_password.
+
+ * lib/kadm5/init_s.c: implement init_with_{skey,creds}*
+
+ * lib/kadm5/server.c: Better arguments for
+ kadm5_init_with_password.
+
+Sat May 16 07:10:36 1998 Assar Westerlund <assar@sics.se>
+
+ * kdc/hprop.c: conditionalize ka-server reading support on
+ KASERVER_DB
+
+ * configure.in: new option `--enable-kaserver-db'
+
+Fri May 15 19:39:18 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/get_cred.c: Better error if local tgt couldn't be
+ found.
+
+Tue May 12 21:11:02 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.0p
+
+ * lib/krb5/mk_req_ext.c (krb5_mk_req_extended): only set
+ encryption type in auth_context if it's compatible with the type
+ of the session key
+
+Mon May 11 21:11:14 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/hprop.c: add support for ka-server databases
+
+ * appl/ftp/ftpd: link with -lcrypt, if needed
+
+Fri May 1 07:29:52 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: don't test for winsock.h
+
+Sat Apr 18 21:43:11 1998 Johan Danielsson <joda@puffer.pdc.kth.se>
+
+ * Release 0.0o
+
+Sat Apr 18 00:31:11 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/sock_principal.c: Save hostname.
+
+Sun Apr 5 11:29:45 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/mk_req_ext.c: Use same enctype as in ticket.
+
+ * kdc/hprop.c (v4_prop): Check for null key.
+
+Fri Apr 3 03:54:54 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/str2key.c: Fix DES3 string-to-key.
+
+ * lib/krb5/keytab.c: Get default keytab name from context.
+
+ * lib/krb5/context.c: Get `default_keytab_name' value.
+
+ * kadmin/util.c (foreach_principal): Print error message if
+ `kadm5_get_principals' fails.
+
+ * kadmin/kadmind.c: Use `kadmind_loop'.
+
+ * lib/kadm5/server.c: Replace several other functions with
+ `kadmind_loop'.
+
+Sat Mar 28 09:49:18 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/keytab.c (fkt_add_entry): use an explicit seek instead
+ of O_APPEND
+
+ * configure.in: generate ftp Makefiles
+
+ * kuser/klist.c (print_cred_verbose): print IPv4-address in a
+ portable way.
+
+ * admin/srvconvert.c (srvconv): return 0 if successful
+
+Tue Mar 24 00:40:33 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/keytab.c: MIT compatible changes: add and use sizes to
+ keytab entries, and change default keytab to `/etc/krb5.keytab'.
+
+Mon Mar 23 23:43:59 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/gssapi/wrap.c: Use `gss_krb5_getsomekey'.
+
+ * lib/gssapi/unwrap.c: Implement and use `gss_krb5_getsomekey'.
+ Fix bug in checking of pad.
+
+ * lib/gssapi/{un,}wrap.c: Add support for just integrity
+ protecting data.
+
+ * lib/gssapi/accept_sec_context.c: Use
+ `gssapi_krb5_verify_8003_checksum'.
+
+ * lib/gssapi/8003.c: Implement `gssapi_krb5_verify_8003_checksum'.
+
+ * lib/gssapi/init_sec_context.c: Zero cred, and store session key
+ properly in auth-context.
+
+Sun Mar 22 00:47:22 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/kadm5/delete_s.c: Check immutable bit.
+
+ * kadmin/kadmin.c: Pass client name to kadm5_init.
+
+ * lib/kadm5/init_c.c: Get creds for client name passed in.
+
+ * kdc/hprop.c (v4_prop): Check for `changepw.kerberos'.
+
+Sat Mar 21 22:57:13 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/mk_error.c: Verify that error_code is in the range
+ [0,127].
+
+ * kdc/kerberos5.c: Move checking of principal flags to new
+ function `check_flags'.
+
+Sat Mar 21 14:38:51 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/kadm5/get_s.c (kadm5_s_get_principal): handle an empty salt
+
+ * configure.in: define SunOS if running solaris
+
+Sat Mar 21 00:26:34 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/kadm5/server.c: Unifdef test for same principal when
+ changing password.
+
+ * kadmin/util.c: If kadm5_get_principals failes, we might still be
+ able to perform the requested opreration (for instance someone if
+ trying to change his own password).
+
+ * lib/kadm5/init_c.c: Try to get ticket via initial request, if
+ not possible via tgt.
+
+ * lib/kadm5/server.c: Check for principals changing their own
+ passwords.
+
+ * kdc/kerberos5.c (tgs_rep2): check for interesting flags on
+ involved principals.
+
+ * kadmin/util.c: Fix order of flags.
+
+Thu Mar 19 16:54:10 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kerberos4.c: Return sane error code if krb_rd_req fails.
+
+Wed Mar 18 17:11:47 1998 Assar Westerlund <assar@sics.se>
+
+ * acconfig.h: rename HAVE_STRUCT_SOCKADDR_IN6 to HAVE_IPV6
+
+Wed Mar 18 09:58:18 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/get_in_tkt_with_keytab.c (krb5_keytab_key_proc): don't
+ free keyseed; use correct keytab
+
+Tue Mar 10 09:56:16 1998 Assar Westerlund <assar@sics.se>
+
+ * acinclude.m4 (AC_KRB_IPV6): rewrote to avoid false positives
+
+Mon Mar 16 23:58:23 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Release 0.0n
+
+Fri Mar 6 00:41:30 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/gssapi/{accept_sec_context,release_cred}.c: Use
+ krb5_kt_close/krb5_kt_resolve.
+
+ * lib/krb5/principal.c (krb5_425_conv_principal_ext): Use resolver
+ to lookup hosts, so CNAMEs can be ignored.
+
+ * lib/krb5/send_to_kdc.c (krb5_sendto_kdc, send_and_recv_http):
+ Add support for using proxy.
+
+ * lib/krb5/context.c: Initialize `http_proxy' from
+ `libdefaults/http_proxy'.
+
+ * lib/krb5/krb5.h: Add `http_proxy' to context.
+
+ * lib/krb5/send_to_kdc.c: Recognize `http/' and `udp/' as protocol
+ specifications.
+
+Wed Mar 4 01:47:29 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * admin/ktutil.c: Implement `add' and `remove' functions. Make
+ `--keytab' a global option.
+
+ * lib/krb5/keytab.c: Implement remove with files. Add memory
+ operations.
+
+Tue Mar 3 20:09:59 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/keytab.c: Use function pointers.
+
+ * admin: Remove kdb_edit.
+
+Sun Mar 1 03:28:42 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/kadm5/dump_log.c: print operation names
+
+Sun Mar 1 03:04:12 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: add X-tests, and {bin,...}dir appl/{kx,kauth}
+
+ * lib/krb5/build_auth.c,mk_priv.c,rd_safe.c,mk_safe.c,mk_rep.c:
+ remove arbitrary limit
+
+ * kdc/hprop-common.c: use krb5_{read,write}_message
+
+ * lib/kadm5/ipropd_master.c (send_diffs): more careful use
+ krb5_{write,read}_message
+
+ * lib/kadm5/ipropd_slave.c (get_creds): get credentials for
+ `iprop/master' directly.
+ (main): use `krb5_read_message'
+
+Sun Mar 1 02:05:11 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kadmin/kadmin.c: Cleanup commands list, and add help strings.
+
+ * kadmin/get.c: Add long, short, and terse (equivalent to `list')
+ output formats. Short is the default.
+
+ * kadmin/util.c: Add `include_time' flag to timeval2str.
+
+ * kadmin/init.c: Max-life and max-renew can, infact, be zero.
+
+ * kadmin/{cpw,del,ext,get}.c: Use `foreach_principal'.
+
+ * kadmin/util.c: Add function `foreach_principal', that loops over
+ all principals matching an expression.
+
+ * kadmin/kadmin.c: Add usage string to `privileges'.
+
+ * lib/kadm5/get_princs_s.c: Also try to match aganist the
+ expression appended with `@default-realm'.
+
+ * lib/krb5/principal.c: Add `krb5_unparse_name_fixed_short', that
+ excludes the realm if it's the same as the default realm.
+
+Fri Feb 27 05:02:21 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: more WFLAGS and WFLAGS_NOUNUSED added missing
+ headers and functions error -> com_err
+
+ (krb5_get_init_creds_keytab): use krb5_keytab_key_proc
+
+ * lib/krb5/get_in_tkt_with_keytab.c: make `krb5_keytab_key_proc'
+ global
+
+ * lib/kadm5/marshall.c (ret_principal_ent): set `n_tl_data'
+
+ * lib/hdb/ndbm.c: use `struct ndbm_db' everywhere.
+
+Fri Feb 27 04:49:24 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/mk_priv.c (krb5_mk_priv): bump static limit to 10240.
+ This should be fixed the correct way.
+
+ * lib/kadm5/ipropd_master.c (check_acl:) truncate buf correctly
+ (send_diffs): compare versions correctly
+ (main): reorder handling of events
+
+ * lib/kadm5/log.c (kadm5_log_previous): avoid bad type conversion
+
+Thu Feb 26 02:22:35 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/kadm5/ipropd_{slave,master}.c: new files
+
+ * lib/kadm5/log.c (kadm5_log_get_version): take an `fd' as
+ argument
+
+ * lib/krb5/krb5.h (krb5_context_data): `et_list' should be `struct
+ et_list *'
+
+ * aux/make-proto.pl: Should work with perl4
+
+Mon Feb 16 17:20:22 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/krb5_locl.h: Remove <error.h> (it gets included via
+ {asn1,krb5}_err.h).
+
+Thu Feb 12 03:28:40 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_in_tkt.c (_krb5_extract_ticket): if time difference
+ is larger than max_skew, return KRB5KRB_AP_ERR_SKEW
+
+ * lib/kadm5/log.c (get_version): globalize
+
+ * lib/kadm5/kadm5_locl.h: include <sys/file.h>
+
+ * lib/asn1/Makefile.am: add PA_KEY_INFO and PA_KEY_INFO_ENTRY
+
+ * kdc/kerberos5.c (get_pa_etype_info): remove gcc-ism of
+ initializing local struct in declaration.
+
+Sat Jan 31 17:28:58 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/524.c: Use krb5_decode_EncTicketPart.
+
+ * kdc/kerberos5.c: Check at runtime whether to use enctypes
+ instead of keytypes. If so use the same value to encrypt ticket,
+ and kdc-rep as well as `keytype' for session key. Fix some obvious
+ bugs with the handling of additional tickets.
+
+ * lib/krb5/rd_req.c: Use krb5_decode_EncTicketPart, and
+ krb5_decode_Authenticator.
+
+ * lib/krb5/rd_rep.c: Use krb5_decode_EncAPRepPart.
+
+ * lib/krb5/rd_cred.c: Use krb5_decode_EncKrbCredPart.
+
+ * lib/krb5/mk_rep.c: Make sure enc_part.etype is an encryption
+ type, and not a key type. Use krb5_encode_EncAPRepPart.
+
+ * lib/krb5/init_creds_pw.c: Use krb5_decode_PA_KEY_INFO.
+
+ * lib/krb5/get_in_tkt.c: Use krb5_decode_Enc{AS,TGS}RepPart.
+
+ * lib/krb5/get_for_creds.c: Use krb5_encode_EncKrbCredPart.
+
+ * lib/krb5/get_cred.c: Use krb5_decode_Enc{AS,TGS}RepPart.
+
+ * lib/krb5/build_auth.c: Use krb5_encode_Authenticator.
+
+ * lib/krb5/codec.c: Enctype conversion stuff.
+
+ * lib/krb5/context.c: Ignore KRB5_CONFIG if *not* running
+ setuid. Get configuration for libdefaults ktype_is_etype, and
+ default_etypes.
+
+ * lib/krb5/encrypt.c: Add krb5_string_to_etype, rename
+ krb5_convert_etype to krb5_decode_keytype, and add
+ krb5_decode_keyblock.
+
+Fri Jan 23 00:32:09 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/{get_in_tkt,rd_req}.c: Use krb5_convert_etype.
+
+ * lib/krb5/encrypt.c: Add krb5_convert_etype function - converts
+ from protocol keytypes (that really are enctypes) to internal
+ representation.
+
+Thu Jan 22 21:24:36 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/asn1/k5.asn1: Add PA-KEY-INFO structure to hold information
+ on keys in the database; and also a new `pa-key-info' padata-type.
+
+ * kdc/kerberos5.c: If pre-authentication fails, return a list of
+ keytypes, salttypes, and salts.
+
+ * lib/krb5/init_creds_pw.c: Add better support for
+ pre-authentication, by looking at hints from the KDC.
+
+ * lib/krb5/get_in_tkt.c: Add better support for specifying what
+ pre-authentication to use.
+
+ * lib/krb5/str2key.c: Merge entries for KEYTYPE_DES and
+ KEYTYPE_DES_AFS3.
+
+ * lib/krb5/krb5.h: Add pre-authentication structures.
+
+ * kdc/connect.c: Don't fail if realloc(X, 0) returns NULL.
+
+Wed Jan 21 06:20:40 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/kadm5/init_s.c (kadm5_s_init_with_password_ctx): initialize
+ `log_context.socket_name' and `log_context.socket_fd'
+
+ * lib/kadm5/log.c (kadm5_log_flush): send a unix domain datagram
+ to inform the possible running ipropd of an update.
+
+Wed Jan 21 01:34:09 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/get_in_tkt.c: Return error-packet to caller.
+
+ * lib/krb5/free.c (krb5_free_kdc_rep): Free krb5_kdc_rep->error.
+
+ * kdc/kerberos5.c: Add some support for using enctypes instead of
+ keytypes.
+
+ * lib/krb5/get_cred.c: Fixes to send authorization-data to the
+ KDC.
+
+ * lib/krb5/build_auth.c: Only generate local subkey if there is
+ none.
+
+ * lib/krb5/krb5.h: Add krb5_authdata type.
+
+ * lib/krb5/auth_context.c: Add
+ krb5_auth_con_set{,localsub,remotesub}key.
+
+ * lib/krb5/init_creds_pw.c: Return some error if prompter
+ functions return failure.
+
+Wed Jan 21 01:16:13 1998 Assar Westerlund <assar@sics.se>
+
+ * kpasswd/kpasswd.c: detect bad password. use krb5_err.
+
+ * kadmin/util.c (edit_entry): remove unused variables
+
+Tue Jan 20 22:58:31 1998 Assar Westerlund <assar@sics.se>
+
+ * kuser/kinit.c: rename `-s' to `-S' to be MIT-compatible.
+
+ * lib/kadm5/kadm5_locl.h: add kadm5_log_context and
+ kadm5_log*-functions
+
+ * lib/kadm5/create_s.c (kadm5_s_create_principal): add change to
+ log
+
+ * lib/kadm5/rename_s.c (kadm5_s_rename_principal): add change to
+ log
+
+ * lib/kadm5/init_s.c (kadm5_s_init_with_password_ctx): initialize
+ log_context
+
+ * lib/kadm5/delete_s.c (kadm5_s_delete_principal): add change to
+ log
+
+ * lib/kadm5/modify_s.c (kadm5_s_modify_principal): add change to
+ log
+
+ * lib/kadm5/randkey_s.c (kadm5_s_randkey_principal): add change to
+ log
+
+ * lib/kadm5/chpass_s.c (kadm5_s_chpass_principal): add change to
+ log
+
+ * lib/kadm5/Makefile.am: add log.c, dump_log and replay_log
+
+ * lib/kadm5/replay_log.c: new file
+
+ * lib/kadm5/dump_log.c: new file
+
+ * lib/kadm5/log.c: new file
+
+ * lib/krb5/str2key.c (get_str): initialize pad space to zero
+
+ * lib/krb5/config_file.c (krb5_config_vget_next): handle c == NULL
+
+ * kpasswd/kpasswdd.c: rewritten to use the kadm5 API
+
+ * kpasswd/Makefile.am: link with kadm5srv
+
+ * kdc/kerberos5.c (tgs_rep): initialize `i'
+
+ * kadmin/kadmind.c (main): use kadm5_server_{send,recv}_sp
+
+ * include/Makefile.am: added admin.h
+
+Sun Jan 18 01:41:34 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/asn1/gen_copy.c: Don't return ENOMEM if allocating 0 bytes.
+
+ * lib/krb5/mcache.c (mcc_store_cred): restore linked list if
+ copy_creds fails.
+
+Tue Jan 6 04:17:56 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/kadm5/server.c: add kadm5_server_{send,recv}{,_sp}
+
+ * lib/kadm5/marshall.c: add kadm5_{store,ret}_principal_ent_mask.
+
+ * lib/kadm5/init_c.c (kadm5_c_init_with_password_ctx): use
+ krb5_getportbyname
+
+ * kadmin/kadmind.c (main): htons correctly.
+ moved kadm5_server_{recv,send}
+
+ * kadmin/kadmin.c (main): only set admin_server if explicitly
+ given
+
+Mon Jan 5 23:34:44 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/hdb/ndbm.c: Implement locking of database.
+
+ * kdc/kerberos5.c: Process AuthorizationData.
+
+Sat Jan 3 22:07:07 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * kdc/string2key.c: Use AFS string-to-key from libkrb5.
+
+ * lib/krb5/get_in_tkt.c: Handle pa-afs3-salt case.
+
+ * lib/krb5/krb5.h: Add value for AFS salts.
+
+ * lib/krb5/str2key.c: Add support for AFS string-to-key.
+
+ * lib/kadm5/rename_s.c: Use correct salt.
+
+ * lib/kadm5/ent_setup.c: Always enable client. Only set max-life
+ and max-renew if != 0.
+
+ * lib/krb5/config_file.c: Add context to all krb5_config_*get_*.
+
+Thu Dec 25 17:03:25 1997 Assar Westerlund <assar@sics.se>
+
+ * kadmin/ank.c (ank): don't zero password if --random-key was
+ given.
+
+Tue Dec 23 01:56:45 1997 Assar Westerlund <assar@sics.se>
+
+ * Release 0.0m
+
+ * lib/kadm5/ent_setup.c (attr_to_flags): try to set `client'
+
+ * kadmin/util.c (edit_time): only set mask if != 0
+ (edit_attributes): only set mask if != 0
+
+ * kadmin/init.c (init): create `default'
+
+Sun Dec 21 09:44:05 1997 Assar Westerlund <assar@sics.se>
+
+ * kadmin/util.c (str2deltat, str2attr, get_deltat): return value
+ as pointer and have return value indicate success.
+
+ (get_response): check NULL from fgets
+
+ (edit_time, edit_attributes): new functions for reading values and
+ offering list of answers on '?'
+
+ (edit_entry): use edit_time and edit_attributes
+
+ * kadmin/ank.c (add_new_key): test the return value of
+ `krb5_parse_name'
+
+ * kdc/kerberos5.c (tgs_check_authenticator): RFC1510 doesn't say
+ that the checksum has to be keyed, even though later drafts do.
+ Accept unkeyed checksums to be compatible with MIT.
+
+ * kadmin/kadmin_locl.h: add some prototypes.
+
+ * kadmin/util.c (edit_entry): return a value
+
+ * appl/afsutil/afslog.c (main): return a exit code.
+
+ * lib/krb5/get_cred.c (init_tgs_req): use krb5_keytype_to_enctypes
+
+ * lib/krb5/encrypt.c (krb5_keytype_to_enctypes): new function.
+
+ * lib/krb5/build_auth.c (krb5_build_authenticator): use
+ krb5_{free,copy}_keyblock instead of the _contents versions
+
+Fri Dec 12 14:20:58 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/{mk,rd}_priv.c: fix check for local/remote subkey
+
+Mon Dec 8 08:48:09 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/context.c: don't look at KRB5_CONFIG if running setuid
+
+Sat Dec 6 10:09:40 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/keyblock.c (krb5_free_keyblock): check for NULL
+ keyblock
+
+Sat Dec 6 08:26:10 1997 Assar Westerlund <assar@sics.se>
+
+ * Release 0.0l
+
+Thu Dec 4 03:38:12 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/send_to_kdc.c: Add TCP client support.
+
+ * lib/krb5/store.c: Add k_{put,get}_int.
+
+ * kadmin/ank.c: Set initial kvno to 1.
+
+ * kdc/connect.c: Send version 5 TCP-reply as length+data.
+
+Sat Nov 29 07:10:11 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/rd_req.c (krb5_rd_req): fixed obvious bug
+
+ * kdc/kaserver.c (create_reply_ticket): use a random nonce in the
+ reply packet.
+
+ * kdc/connect.c (init_sockets): less reallocing.
+
+ * **/*.c: changed `struct fd_set' to `fd_set'
+
+Sat Nov 29 05:12:01 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/get_default_principal.c: More guessing.
+
+Thu Nov 20 02:55:09 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/rd_req.c: Use principal from ticket if no server is
+ given.
+
+Tue Nov 18 02:58:02 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kuser/klist.c: Use krb5_err*().
+
+Sun Nov 16 11:57:43 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kadmin/kadmin.c: Add local `init', `load', `dump', and `merge'
+ commands.
+
+Sun Nov 16 02:52:20 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/mk_req_ext.c (krb5_mk_req_ext): figure out the correct
+ `enctype'
+
+ * lib/krb5/mk_req.c (krb5_mk_req): use `(*auth_context)->enctype'
+ if set.
+
+ * lib/krb5/get_cred.c: handle the case of a specific keytype
+
+ * lib/krb5/build_auth.c (krb5_build_authenticator): enctype as a
+ parameter instead of guessing it.
+
+ * lib/krb5/build_ap_req.c (krb5_build_ap_req): new parameter
+ `enctype'
+
+ * appl/test/common.c (common_setup): don't use `optarg'
+
+ * lib/krb5/keytab.c (krb5_kt_copy_entry_contents): new function
+ (krb5_kt_get_entry): retrieve the latest version if kvno == 0
+
+ * lib/krb5/krb5.h: define KRB5_TC_MATCH_KEYTYPE
+
+ * lib/krb5/creds.c (krb5_compare_creds): check for
+ KRB5_TC_MATCH_KEYTYPE
+
+ * lib/gssapi/8003.c (gssapi_krb5_create_8003_checksum): remove
+ unused variable
+
+ * lib/krb5/creds.c (krb5_copy_creds_contents): only free the
+ contents if we fail.
+
+Sun Nov 16 00:32:48 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kpasswd/kpasswdd.c: Get password expiration time from config
+ file.
+
+ * lib/asn1/{der_get,gen_decode}.c: Allow passing NULL size.
+
+Wed Nov 12 02:35:57 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_for_creds.c (krb5_get_forwarded_creds):
+ restructured and fixed.
+
+ * lib/krb5/addr_families.c (krb5_h_addr2addr): new function.
+
+Wed Nov 12 01:36:01 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/get_addrs.c: Fall back to hostname's addresses if other
+ methods fail.
+
+Tue Nov 11 22:22:12 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kadmin/kadmin.c: Add `-l' flag to use local database.
+
+ * lib/kadm5/acl.c: Use KADM5_PRIV_ALL.
+
+ * lib/kadm5: Use function pointer trampoline for easier dual use
+ (without radiation-hardening capability).
+
+Tue Nov 11 05:15:22 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/encrypt.c (krb5_etype_valid): new function
+
+ * lib/krb5/creds.c (krb5_copy_creds_contents): zero target
+
+ * lib/krb5/context.c (valid_etype): remove
+
+ * lib/krb5/checksum.c: remove dead code
+
+ * lib/krb5/changepw.c (send_request): free memory on error.
+
+ * lib/krb5/build_ap_req.c (krb5_build_ap_req): check return value
+ from malloc.
+
+ * lib/krb5/auth_context.c (krb5_auth_con_init): free memory on
+ failure correctly.
+ (krb5_auth_con_setaddrs_from_fd): return error correctly.
+
+ * lib/krb5/get_in_tkt_with_{keytab,skey}.c: new files
+
+Tue Nov 11 02:53:19 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/auth_context.c: Implement auth_con_setuserkey.
+
+ * lib/gssapi/init_sec_context.c: Use krb5_auth_con_getkey.
+
+ * lib/krb5/keyblock.c: Rename krb5_free_keyblock to
+ krb5_free_keyblock_contents, and reimplement krb5_free_keyblock.
+
+ * lib/krb5/rd_req.c: Use auth_context->keyblock if
+ ap_options.use_session_key.
+
+Tue Nov 11 02:35:17 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/net_{read,write}.c: change `int fd' to `void *p_fd'.
+ fix callers.
+
+ * lib/krb5/krb5_locl.h: include <asn1.h> and <der.h>
+
+ * include/Makefile.am: add xdbm.h
+
+Tue Nov 11 01:58:22 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/get_cred.c: Implement krb5_get_cred_from_kdc.
+
+Mon Nov 10 22:41:53 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/ticket.c: Implement copy_ticket.
+
+ * lib/krb5/get_in_tkt.c: Make `options' parameter MIT-compatible.
+
+ * lib/krb5/data.c: Implement free_data and copy_data.
+
+Sun Nov 9 02:17:27 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/kadm5: Implement kadm5_get_privs, and kadm5_get_principals.
+
+ * kadmin/kadmin.c: Add get_privileges function.
+
+ * lib/kadm5: Rename KADM5_ACL_* -> KADM5_PRIV_* to conform with
+ specification.
+
+ * kdc/connect.c: Exit if no sockets could be bound.
+
+ * kadmin/kadmind.c: Check return value from krb5_net_read().
+
+ * lib/kadm5,kadmin: Fix memory leaks.
+
+Fri Nov 7 02:45:26 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/kadm5/create_s.c: Get some default values from `default'
+ principal.
+
+ * lib/kadm5/ent_setup.c: Add optional default entry to get some
+ values from.
+
+Thu Nov 6 00:20:41 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/error/compile_et.awk: Remove generated destroy_*_error_table
+ prototype
+
+ * kadmin/kadmind.c: Crude admin server.
+
+ * kadmin/kadmin.c: Update to use remote protocol.
+
+ * kadmin/get.c: Fix principal formatting.
+
+ * lib/kadm5: Add client support.
+
+ * lib/kadm5/error.c: Error code mapping.
+
+ * lib/kadm5/server.c: Kadmind support function.
+
+ * lib/kadm5/marshall.c: Kadm5 marshalling.
+
+ * lib/kadm5/acl.c: Simple acl system.
+
+ * lib/kadm5/kadm5_locl.h: Add client stuff.
+
+ * lib/kadm5/init_s.c: Initialize acl.
+
+ * lib/kadm5/*: Return values.
+
+ * lib/kadm5/create_s.c: Correct kvno.
+
+Wed Nov 5 22:06:50 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/log.c: Fix parsing of log destinations.
+
+Mon Nov 3 20:33:55 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/principal.c: Reduce number of reallocs in unparse_name.
+
+Sat Nov 1 01:40:53 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kadmin: Simple kadmin utility.
+
+ * admin/ktutil.c: Print keytype.
+
+ * lib/kadm5/get_s.c: Set correct n_key_data.
+
+ * lib/kadm5/init_s.c: Add kadm5_s_init_with_password_ctx. Use
+ master key.
+
+ * lib/kadm5/destroy_s.c: Check for allocated context.
+
+ * lib/kadm5/{create,chpass}_s.c: Use _kadm5_set_keys().
+
+Sat Nov 1 00:21:00 1997 Assar Westerlund <assar@sics.se>
+
+ * configure.in: test for readv, writev
+
+Wed Oct 29 23:41:26 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/warn.c (_warnerr): handle the case of an illegal error
+ code
+
+ * kdc/kerberos5.c (encode_reply): return success
+
+Wed Oct 29 18:01:59 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kerberos5.c (find_etype) Return correct index of selected
+ etype.
+
+Wed Oct 29 04:07:06 1997 Assar Westerlund <assar@sics.se>
+
+ * Release 0.0k
+
+ * lib/krb5/context.c (krb5_init_context): support `KRB5_CONFIG'
+ environment variable
+
+ * *: use the roken_get*-macros from roken.h for the benefit of
+ Crays.
+
+ * configure.in: add --{enable,disable}-otp. check for compatible
+ prototypes for gethostbyname, gethostbyaddr, getservbyname, and
+ openlog (they have strange prototypes on Crays)
+
+ * acinclude.m4: new macro `AC_PROTO_COMPAT'
+
+Tue Oct 28 00:11:22 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/connect.c: Log bad requests.
+
+ * kdc/kerberos5.c: Move stuff that's in common between as_rep and
+ tgs_rep to separate functions.
+
+ * kdc/kerberos5.c: Fix user-to-user authentication.
+
+ * lib/krb5/get_cred.c: Some restructuring of krb5_get_credentials:
+ - add a kdc-options argument to krb5_get_credentials, and rename
+ it to krb5_get_credentials_with_flags
+ - honour the KRB5_GC_CACHED, and KRB5_GC_USER_USER options
+ - add some more user-to-user glue
+
+ * lib/krb5/rd_req.c: Move parts of krb5_verify_ap_req into a new
+ function, krb5_decrypt_ticket, so it is easier to decrypt and
+ check a ticket without having an ap-req.
+
+ * lib/krb5/krb5.h: Add KRB5_GC_CACHED, and KRB5_GC_USER_USER
+ flags.
+
+ * lib/krb5/crc.c (crc_init_table): Check if table is already
+ inited.
+
+Sun Oct 26 04:51:02 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/asn1/der_get.c (der_get_length, fix_dce): Special-case
+ indefinite encoding.
+
+ * lib/asn1/gen_glue.c (generate_units): Check for empty
+ member-list.
+
+Sat Oct 25 07:24:57 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/error/compile_et.awk: Allow specifying table-base.
+
+Tue Oct 21 20:21:40 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kerberos5.c: Check version number of krbtgt.
+
+Mon Oct 20 01:14:53 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/prompter_posix.c (krb5_prompter_posix): implement the
+ case of unhidden prompts.
+
+ * lib/krb5/str2key.c (string_to_key_internal): return error
+ instead of aborting. always free memory
+
+ * admin/ktutil.c: add `help' command
+
+ * admin/kdb_edit.c: implement new commands: add_random_key(ark),
+ change_password(cpw), change_random_key(crk)
+
+Thu Oct 16 05:16:36 1997 Assar Westerlund <assar@sics.se>
+
+ * kpasswd/kpasswdd.c: change all the keys in the database
+
+ * kdc: removed all unsealing, now done by the hdb layer
+
+ * lib/hdb/hdb.c: new functions `hdb_create', `hdb_set_master_key'
+ and `hdb_clear_master_key'
+
+ * admin/misc.c: removed
+
+Wed Oct 15 22:47:31 1997 Assar Westerlund <assar@sics.se>
+
+ * kuser/klist.c: print year as YYYY iff verbose
+
+Wed Oct 15 20:02:13 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kuser/klist.c: print etype from ticket
+
+Mon Oct 13 17:18:57 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Release 0.0j
+
+ * lib/krb5/get_cred.c: Get the subkey from mk_req so it can be
+ used to decrypt the reply from DCE secds.
+
+ * lib/krb5/auth_context.c: Add {get,set}enctype.
+
+ * lib/krb5/get_cred.c: Fix for DCE secd.
+
+ * lib/krb5/store.c: Store keytype twice, as MIT does.
+
+ * lib/krb5/get_in_tkt.c: Use etype from reply.
+
+Fri Oct 10 00:39:48 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/connect.c: check for leading '/' in http request
+
+Tue Sep 30 21:50:18 1997 Assar Westerlund <assar@assaris.pdc.kth.se>
+
+ * Release 0.0i
+
+Mon Sep 29 15:58:43 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/rd_req.c (krb5_rd_req): redone because we don't know
+ the kvno or keytype before receiving the AP-REQ
+
+ * lib/krb5/mk_safe.c (krb5_mk_safe): figure out what cksumtype to
+ use from the keytype.
+
+ * lib/krb5/mk_req_ext.c (krb5_mk_req_extended): figure out what
+ cksumtype to use from the keytype.
+
+ * lib/krb5/mk_priv.c (krb5_mk_priv): figure out what etype to use
+ from the keytype.
+
+ * lib/krb5/keytab.c (krb5_kt_get_entry): check the keytype
+
+ * lib/krb5/get_for_creds.c (krb5_get_forwarded_creds): figure out
+ what etype to use from the keytype.
+
+ * lib/krb5/generate_seq_number.c (krb5_generate_seq_number):
+ handle other key types than DES
+
+ * lib/krb5/encrypt.c (key_type): add `best_cksumtype'
+ (krb5_keytype_to_cksumtype): new function
+
+ * lib/krb5/build_auth.c (krb5_build_authenticator): figure out
+ what etype to use from the keytype.
+
+ * lib/krb5/auth_context.c (krb5_auth_con_init): set `cksumtype'
+ and `enctype' to 0
+
+ * admin/extkeytab.c (ext_keytab): extract all keys
+
+ * appl/telnet/telnet/commands.c: INET6_ADDRSTRLEN kludge
+
+ * configure.in: check for <netinet6/in6.h>. check for -linet6
+
+Tue Sep 23 03:00:53 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/encrypt.c: fix checksumtype for des3-cbc-sha1
+
+ * lib/krb5/rd_safe.c: fix check for keyed and collision-proof
+ checksum
+
+ * lib/krb5/context.c (valid_etype): remove hard-coded constants
+ (default_etypes): include DES3
+
+ * kdc/kerberos5.c: fix check for keyed and collision-proof
+ checksum
+
+ * admin/util.c (init_des_key, set_password): DES3 keys also
+
+ * lib/krb/send_to_kdc.c (krb5_sendto_kdc): no data returned means
+ no contact?
+
+ * lib/krb5/addr_families.c: fix typo in `ipv6_anyaddr'
+
+Mon Sep 22 11:44:27 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * kdc/kerberos5.c: Somewhat fix the etype usage. The list sent by
+ the client is used to select wich key to encrypt the kdc rep with
+ (in case of as-req), and with the server info to select the
+ session key type. The server key the ticket is encrypted is based
+ purely on the keys in the database.
+
+ * kdc/string2key.c: Add keytype support. Default to version 5
+ keys.
+
+ * lib/krb5/get_in_tkt.c: Fix a lot of etype/keytype misuse.
+
+ * lib/krb5/encrypt.c: Add des3-cbc-md5, and des3-cbc-sha1. Add
+ many *_to_* functions.
+
+ * lib/krb5/str2key.c: Add des3 string-to-key. Add ktype argument
+ to krb5_string_to_key().
+
+ * lib/krb5/checksum.c: Some cleanup, and added:
+ - rsa-md5-des3
+ - hmac-sha1-des3
+ - keyed and collision proof flags to each checksum method
+ - checksum<->string functions.
+
+ * lib/krb5/generate_subkey.c: Use krb5_generate_random_keyblock.
+
+Sun Sep 21 15:19:23 1997 Assar Westerlund <assar@sics.se>
+
+ * kdc/connect.c: use new addr_families functions
+
+ * kpasswd/kpasswdd.c: use new addr_families functions. Now works
+ over IPv6
+
+ * kuser/klist.c: use correct symbols for address families
+
+ * lib/krb5/sock_principal.c: use new addr_families functions
+
+ * lib/krb5/send_to_kdc.c: use new addr_families functions
+
+ * lib/krb5/krb5.h: add KRB5_ADDRESS_INET6
+
+ * lib/krb5/get_addrs.c: use new addr_families functions
+
+ * lib/krb5/changepw.c: use new addr_families functions. Now works
+ over IPv6
+
+ * lib/krb5/auth_context.c: use new addr_families functions
+
+ * lib/krb5/addr_families.c: new file
+
+ * acconfig.h: AC_SOCKADDR_IN6 -> AC_STRUCT_SOCKADDR_IN6. Updated
+ uses.
+
+ * acinclude.m4: new macro `AC_KRB_IPV6'. Use it.
+
+Sat Sep 13 23:04:23 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/hprop.c: Don't encrypt twice. Complain on non-convertable
+ principals.
+
+Sat Sep 13 00:59:36 1997 Assar Westerlund <assar@sics.se>
+
+ * Release 0.0h
+
+ * appl/telnet/telnet/commands.c: AF_INET6 support
+
+ * admin/misc.c: new file
+
+ * lib/krb5/context.c: new configuration variable `max_retries'
+
+ * lib/krb5/get_addrs.c: fixes and better #ifdef's
+
+ * lib/krb5/config_file.c: implement krb5_config_get_int
+
+ * lib/krb5/auth_context.c, send_to_kdc.c, sock_principal.c:
+ AF_INET6 support
+
+ * kuser/klist.c: support for printing IPv6-addresses
+
+ * kdc/connect.c: support AF_INET6
+
+ * configure.in: test for gethostbyname2 and struct sockaddr_in6
+
+Thu Sep 11 07:25:28 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/k5.asn1: Use `METHOD-DATA' instead of `SEQUENCE OF
+ PA-DATA'
+
+Wed Sep 10 21:20:17 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kerberos5.c: Fixes for cross-realm, including (but not
+ limited to):
+ - allow client to be non-existant (should probably check for
+ "local realm")
+ - if server isn't found and it is a request for a krbtgt, try to
+ find a realm on the way to the requested realm
+ - update the transited encoding iff
+ client-realm != server-realm != tgt-realm
+
+ * lib/krb5/get_cred.c: Several fixes for cross-realm.
+
+Tue Sep 9 15:59:20 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/string2key.c: Fix password handling.
+
+ * lib/krb5/encrypt.c: krb5_key_to_string
+
+Tue Sep 9 07:46:05 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_addrs.c: rewrote. Now should be able to handle
+ aliases and IPv6 addresses
+
+ * kuser/klist.c: try printing IPv6 addresses
+
+ * kdc/kerberos5.c: increase the arbitrary limit from 1024 to 8192
+
+ * configure.in: check for <netinet/in6_var.h>
+
+Mon Sep 8 02:57:14 1997 Assar Westerlund <assar@sics.se>
+
+ * doc: fixes
+
+ * admin/util.c (init_des_key): increase kvno
+ (set_password): return -1 if `des_read_pw_string' failed
+
+ * admin/mod.c (doit2): check the return value from `set_password'
+
+ * admin/ank.c (doit): don't add a new entry if `set_password'
+ failed
+
+Mon Sep 8 02:20:16 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/verify_init.c: fix ap_req_nofail semantics
+
+ * lib/krb5/transited.c: something that might resemble
+ domain-x500-compress
+
+Mon Sep 8 01:24:42 1997 Assar Westerlund <assar@sics.se>
+
+ * kdc/hpropd.c (main): check number of arguments
+
+ * appl/popper/pop_init.c (pop_init): check number of arguments
+
+ * kpasswd/kpasswd.c (main): check number of arguments
+
+ * kdc/string2key.c (main): check number of arguments
+
+ * kuser/kdestroy.c (main): check number of arguments
+
+ * kuser/kinit.c (main): check number of arguments
+
+ * kpasswd/kpasswdd.c (main): use sigaction without SA_RESTART to
+ break out of select when a signal arrives
+
+ * kdc/main.c (main): use sigaction without SA_RESTART to break out
+ of select when a signal arrives
+
+ * kdc/kstash.c: default to HDB_DB_DIR "/m-key"
+
+ * kdc/config.c (configure): add `--version'. Check the number of
+ arguments. Handle the case of there being no specification of port
+ numbers.
+
+ * admin/util.c: seal and unseal key at appropriate places
+
+ * admin/kdb_edit.c (main): parse arguments, config file and read
+ master key iff there's one.
+
+ * admin/extkeytab.c (ext_keytab): unseal key while extracting
+
+Sun Sep 7 20:41:01 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/roken/roken.h: include <fcntl.h>
+
+ * kdc/kerberos5.c (set_salt_padata): new function
+
+ * appl/telnet/telnetd/telnetd.c: Rename some variables that
+ conflict with cpp symbols on HP-UX 10.20
+
+ * change all calls of `gethostbyaddr' to cast argument 1 to `const
+ char *'
+
+ * acconfig.h: only use SGTTY on nextstep
+
+Sun Sep 7 14:33:50 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kerberos5.c: Check invalid flag.
+
+Fri Sep 5 14:19:38 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/verify_user.c: Use get_init_creds/verify_init_creds.
+
+ * lib/kafs: Move functions common to krb/krb5 modules to new file,
+ and make things more modular.
+
+ * lib/krb5/krb5.h: rename STRING -> krb5_config_string, and LIST
+ -> krb5_config_list
+
+Thu Sep 4 23:39:43 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/get_addrs.c: Fix loopback test.
+
+Thu Sep 4 04:45:49 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/roken/roken.h: fallback definition of `O_ACCMODE'
+
+ * lib/krb5/get_in_tkt.c (krb5_get_in_cred): be more careful when
+ checking for a v4 reply
+
+Wed Sep 3 18:20:14 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/hprop.c: Add `--decrypt' and `--encrypt' flags.
+
+ * lib/hdb/hdb.c: new {seal,unseal}_keys functions
+
+ * kdc/{hprop,hpropd}.c: Add support to dump database to stdout.
+
+ * kdc/hprop.c: Don't use same master key as version 4.
+
+ * admin/util.c: Don't dump core if no `default' is found.
+
+Wed Sep 3 16:01:07 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * kdc/connect.c: Allow run time port specification.
+
+ * kdc/config.c: Add flags for http support, and port
+ specifications.
+
+Tue Sep 2 02:00:03 1997 Assar Westerlund <assar@sics.se>
+
+ * include/bits.c: Don't generate ifndef's in bits.h. Instead, use
+ them when building the program. This makes it possible to include
+ bits.h without having defined all HAVE_INT17_T symbols.
+
+ * configure.in: test for sigaction
+
+ * doc: updated documentation.
+
+Tue Sep 2 00:20:31 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Release 0.0g
+
+Mon Sep 1 17:42:14 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/data.c: don't return ENOMEM if len == 0
+
+Sun Aug 31 17:15:49 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/hdb/hdb.asn1: Include salt type in salt.
+
+ * kdc/hprop.h: Change port to 754.
+
+ * kdc/hpropd.c: Verify who tries to transmit a database.
+
+ * appl/popper: Use getarg and krb5_log.
+
+ * lib/krb5/get_port.c: Add context parameter. Now takes port in
+ host byte order.
+
+Sat Aug 30 18:48:19 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/connect.c: Add timeout to select, and log about expired tcp
+ connections.
+
+ * kdc/config.c: Add `database' option.
+
+ * kdc/hpropd.c: Log about duplicate entries.
+
+ * lib/hdb/{db,ndbm}.c: Use common routines.
+
+ * lib/hdb/common.c: Implement more generic fetch/store/delete
+ functions.
+
+ * lib/hdb/hdb.h: Add `replace' parameter to store.
+
+ * kdc/connect.c: Set filedecriptor to -1 on allocated decriptor
+ entries.
+
+Fri Aug 29 03:13:23 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_in_tkt.c: extract_ticket -> _krb5_extract_ticket
+
+ * aux/make-proto.pl: fix __P for stone age mode
+
+Fri Aug 29 02:45:46 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/45/mk_req.c: implementation of krb_mk_req that uses 524
+ protocol
+
+ * lib/krb5/init_creds_pw.c: make change_password and
+ get_init_creds_common static
+
+ * lib/krb5/krb5.h: Merge stuff from removed headerfiles.
+
+ * lib/krb5/fcache.c: fcc_ops -> krb5_fcc_ops
+
+ * lib/krb5/mcache.c: mcc_ops -> krb5_mcc_ops
+
+Fri Aug 29 01:45:25 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/krb5.h: Remove all prototypes.
+
+ * lib/krb5/convert_creds.c: Use `struct credentials' instead of
+ `CREDENTIALS'.
+
+Fri Aug 29 00:08:18 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/gen_glue.c: new file. generates 2int and int2 functions
+ and units for bit strings.
+
+ * admin/util.c: flags2int, int2flags, and flag_units are now
+ generated by asn1_compile
+
+ * lib/roken/parse_units.c: generalised `parse_units' and
+ `unparse_units' and added new functions `parse_flags' and
+ `unparse_flags' that use these
+
+ * lib/krb5/krb5_locl.h: moved krb5_data* functions to krb5.h
+
+ * admin/util.c: Use {un,}parse_flags for printing and parsing
+ hdbflags.
+
+Thu Aug 28 03:26:12 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_addrs.c: restructured
+
+ * lib/krb5/warn.c (_warnerr): leak less memory
+
+ * lib/hdb/hdb.c (hdb_free_entry): zero keys
+ (hdb_check_db_format): leak less memory
+
+ * lib/hdb/ndbm.c (NDBM_seq): check for valid hdb_entries implement
+ NDBM__get, NDBM__put
+
+ * lib/hdb/db.c (DB_seq): check for valid hdb_entries
+
+Thu Aug 28 02:06:58 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/send_to_kdc.c: Don't use sendto on connected sockets.
+
+Thu Aug 28 01:13:17 1997 Assar Westerlund <assar@sics.se>
+
+ * kuser/kinit.1, klist.1, kdestroy.1: new man pages
+
+ * kpasswd/kpasswd.1, kpasswdd.8: new man pages
+
+ * kdc/kstash.8, hprop.8, hpropd.8: new man pages
+
+ * admin/ktutil.8, admin/kdb_edit.8: new man pages
+
+ * admin/mod.c: new file
+
+ * admin/life.c: renamed gettime and puttime to getlife and putlife
+ and moved them to life.c
+
+ * admin/util.c: add print_flags, parse_flags, init_entry,
+ set_created_by, set_modified_by, edit_entry, set_password. Use
+ them.
+
+ * admin/get.c: use print_flags
+
+ * admin: removed unused stuff. use krb5_{warn,err}*
+
+ * admin/ank.c: re-organized and abstracted.
+
+ * admin/gettime.c: removed
+
+Thu Aug 28 00:37:39 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/{get_cred,get_in_tkt}.c: Check for v4 reply.
+
+ * lib/roken/base64.c: Add base64 functions.
+
+ * kdc/connect.c lib/krb5/send_to_kdc.c: Add http support.
+
+Wed Aug 27 00:29:20 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * include/Makefile.am: Don't make links to built files.
+
+ * admin/kdb_edit.c: Add command to set the database path.
+
+ * lib/hdb: Include version number in database.
+
+Tue Aug 26 20:14:54 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * admin/ktutil: Merged v4 srvtab conversion.
+
+Mon Aug 25 23:02:18 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/roken/roken.h: add F_OK
+
+ * lib/gssapi/acquire_creds.c: fix typo
+
+ * configure.in: call AC_TYPE_MODE_T
+
+ * acinclude.m4: Add AC_TYPE_MODE_T
+
+Sun Aug 24 16:46:53 1997 Assar Westerlund <assar@sics.se>
+
+ * Release 0.0f
+
+Sun Aug 24 08:06:54 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/popper/pop_pass.c: log poppers
+
+ * kdc/kaserver.c: some more checks
+
+ * kpasswd/kpasswd.c: removed `-p'
+
+ * kuser/kinit.c: removed `-p'
+
+ * lib/krb5/init_creds_pw.c (krb5_get_init_creds_password): If
+ KDC_ERR_PREUATH_REQUIRED, add preauthentication and try again.
+
+ * lib/krb5/get_in_tkt.c (krb5_get_in_cred): don't print out
+ krb-error text
+
+ * lib/gssapi/import_name.c (input_name): more names types.
+
+ * admin/load.c (parse_keys): handle the case of an empty salt
+
+ * kdc/kaserver.c: fix up memory deallocation
+
+ * kdc/kaserver.c: quick hack at talking kaserver protocol
+
+ * kdc/kerberos4.c: Make `db-fetch4' global
+
+ * configure.in: add --enable-kaserver
+
+ * kdc/rx.h, kdc/kerberos4.h: new header files
+
+ * lib/krb5/principal.c: fix krb5_build_principal_ext & c:o
+
+Sun Aug 24 03:52:44 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/{get_in_tkt,mk_safe,mk_priv}.c: Fix some Cray specific
+ type conflicts.
+
+ * lib/krb5/{get_cred,get_in_tkt}.c: Mask nonce to 32 bits.
+
+ * lib/des/{md4,md5,sha}.c: Now works on Crays.
+
+Sat Aug 23 18:15:01 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * appl/afsutil/afslog.c: If no cells or files specified, get
+ tokens for all local cells. Better test for files.
+
+Thu Aug 21 23:33:38 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/gssapi/v1.c: new file with v1 compatibility functions.
+
+Thu Aug 21 20:36:13 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/kafs/afskrb5.c: Don't check ticket file for afs ticket.
+
+ * kdc/kerberos4.c: Check database when converting v4 principals.
+
+ * kdc/kerberos5.c: Include kvno in Ticket.
+
+ * lib/krb5/encrypt.c: Add kvno parameter to encrypt_EncryptedData.
+
+ * kuser/klist.c: Print version number of ticket, include more
+ flags.
+
+Wed Aug 20 21:26:58 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/kafs/afskrb5.c (get_cred): Check cached afs tickets for
+ expiration.
+
+Wed Aug 20 17:40:31 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/recvauth.c (krb5_recvauth): Send a KRB-ERROR iff
+ there's an error.
+
+ * lib/krb5/sendauth.c (krb5_sendauth): correct the protocol
+ documentation and process KRB-ERROR's
+
+Tue Aug 19 20:41:30 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kerberos4.c: Fix memory leak in v4 protocol handler.
+
+Mon Aug 18 05:15:09 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/gssapi/accept_sec_context.c: Added
+ `gsskrb5_register_acceptor_identity'
+
+Sun Aug 17 01:40:20 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/gssapi/accept_sec_context.c (gss_accept_sec_context): don't
+ always pass server == NULL to krb5_rd_req.
+
+ * lib/gssapi: new files: canonicalize_name.c export_name.c
+ context_time.c compare_name.c release_cred.c acquire_cred.c
+ inquire_cred.c, from Luke Howard <lukeh@xedoc.com.au>
+
+ * lib/krb5/config_file.c: Add netinfo support from Luke Howard
+ <lukeh@xedoc.com.au>
+
+ * lib/editline/sysunix.c: sgtty-support from Luke Howard
+ <lukeh@xedoc.com.au>
+
+ * lib/krb5/principal.c: krb5_sname_to_principal fix from Luke
+ Howard <lukeh@xedoc.com.au>
+
+Sat Aug 16 00:44:47 1997 Assar Westerlund <assar@koi.pdc.kth.se>
+
+ * Release 0.0e
+
+Sat Aug 16 00:23:46 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * appl/afsutil/afslog.c: Use new libkafs.
+
+ * lib/kafs/afskrb5.c: Get AFS tokens via 524 protocol.
+
+ * lib/krb5/warn.c: Fix format string for *x type.
+
+Fri Aug 15 22:15:01 1997 Assar Westerlund <assar@sics.se>
+
+ * admin/get.c (get_entry): print more information about the entry
+
+ * lib/des/Makefile.am: build destest, mdtest, des, rpw, speed
+
+ * lib/krb5/config_file.c: new functions `krb5_config_get_time' and
+ `krb5_config_vget_time'. Use them.
+
+Fri Aug 15 00:09:37 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * admin/ktutil.c: Keytab manipulation program.
+
+ * lib/krb5/keytab.c: Return sane values from resolve and
+ start_seq_get.
+
+ * kdc/kerberos5.c: Fix for old clients passing 0 for `no endtime'.
+
+ * lib/45/get_ad_tkt.c: Kerberos 4 get_ad_tkt using
+ krb524_convert_creds_kdc.
+
+ * lib/krb5/convert_creds.c: Implementation of
+ krb524_convert_creds_kdc.
+
+ * lib/asn1/k5.asn1: Make kdc-req-body.till OPTIONAL
+
+ * kdc/524.c: A somewhat working 524-protocol module.
+
+ * kdc/kerberos4.c: Add version 4 ticket encoding and encryption
+ functions.
+
+ * lib/krb5/context.c: Fix kdc_timeout.
+
+ * lib/hdb/{ndbm,db}.c: Free name in close.
+
+ * kdc/kerberos5.c (tgs_check_autenticator): Return error code
+
+Thu Aug 14 21:29:03 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kerberos5.c (tgs_make_reply): Fix endtime in reply.
+
+ * lib/krb5/store_emem.c: Fix reallocation bug.
+
+Tue Aug 12 01:29:46 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/telnet/libtelnet/kerberos5.c, appl/popper/pop_init.c: Use
+ `krb5_sock_to_principal'. Send server parameter to
+ krb5_rd_req/krb5_recvauth. Set addresses in auth_context.
+
+ * lib/krb5/recvauth.c: Set addresses in auth_context if there
+ aren't any
+
+ * lib/krb5/auth_context.c: New function
+ `krb5_auth_con_setaddrs_from_fd'
+
+ * lib/krb5/sock_principal.c: new function
+ `krb5_sock_to_principal'
+
+ * lib/krb5/time.c: new file with `krb5_timeofday' and
+ `krb5_us_timeofday'. Use these functions.
+
+ * kuser/klist.c: print KDC offset iff verbose
+
+ * lib/krb5/get_in_tkt.c: implement KDC time offset and use it if
+ [libdefaults]kdc_timesync is set.
+
+ * lib/krb5/fcache.c: Implement version 4 of the ccache format.
+
+Mon Aug 11 05:34:43 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/rd_rep.c (krb5_free_ap_rep_enc_part): free all memory
+
+ * lib/krb5/principal.c (krb5_unparse_name): allocate memory
+ properly
+
+ * kpasswd/kpasswd.c: Use `krb5_change_password'
+
+ * lib/krb5/init_creds_pw.c (init_cred): set realm of server
+ correctly.
+
+ * lib/krb5/init_creds_pw.c: support changing of password when it
+ has expired
+
+ * lib/krb5/changepw.c: new file
+
+ * kuser/klist.c: use getarg
+
+ * admin/init.c (init): add `kadmin/changepw'
+
+Mon Aug 11 04:30:47 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/get_cred.c: Make get_credentials handle cross-realm.
+
+Mon Aug 11 00:03:24 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/config_file.c: implement support for #-comments
+
+Sat Aug 9 02:21:46 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/hprop*.c: Add database propagation programs.
+
+ * kdc/connect.c: Max request size.
+
+Sat Aug 9 00:47:28 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/otp: resurrected from krb4
+
+ * appl/push: new program for fetching mail with POP.
+
+ * appl/popper/popper.h: new include files. new fields in `POP'
+
+ * appl/popper/pop_pass.c: Implement both v4 and v5.
+
+ * appl/popper/pop_init.c: Implement both v4 and v5.
+
+ * appl/popper/pop_debug.c: use getarg. Talk both v4 and v5
+
+ * appl/popper: Popper from krb4.
+
+ * configure.in: check for inline and <netinet/tcp.h> generate
+ files in appl/popper, appl/push, and lib/otp
+
+Fri Aug 8 05:51:02 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_cred.c: clean-up and try to free memory even when
+ there're errors
+
+ * lib/krb5/get_cred.c: adapt to new `extract_ticket'
+
+ * lib/krb5/get_in_tkt.c: reorganize. check everything and try to
+ return memory even if there are errors.
+
+ * kuser/kverify.c: new file
+
+ * lib/krb5/free_host_realm.c: new file
+
+ * lib/krb5/principal.c (krb5_sname_to_principal): implement
+ different nametypes. Also free memory.
+
+ * lib/krb5/verify_init.c: more functionality
+
+ * lib/krb5/mk_req_ext.c (krb5_mk_req_extended): free the checksum
+
+ * lib/krb5/get_in_tkt.c (extract_ticket): don't copy over the
+ principals in creds. Should also compare them with that received
+ from the KDC
+
+ * lib/krb5/cache.c (krb5_cc_gen_new): copy the newly allocated
+ krb5_ccache
+ (krb5_cc_destroy): call krb5_cc_close
+ (krb5_cc_retrieve_cred): delete the unused creds
+
+Fri Aug 8 02:30:40 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/log.c: Allow better control of destinations of logging
+ (like passing explicit destinations, and log-functions).
+
+Fri Aug 8 01:20:39 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_default_principal.c: new file
+
+ * kpasswd/kpasswdd.c: use krb5_log*
+
+Fri Aug 8 00:37:47 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/init_creds_pw.c: Implement krb5_get_init_creds_keytab.
+
+Fri Aug 8 00:37:17 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/init_creds_pw.c: Use `krb5_get_default_principal'.
+ Print password expire information.
+
+ * kdc/config.c: new variable `kdc_warn_pwexpire'
+
+ * kpasswd/kpasswd.c: converted to getarg and get_init_creds
+
+Thu Aug 7 22:17:09 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/mcache.c: new file
+
+ * admin/gettime.c: new function puttime. Use it.
+
+ * lib/krb5/keyblock.c: Added krb5_free_keyblock and
+ krb5_copy_keyblock
+
+ * lib/krb5/init_creds_pw.c: more functionality
+
+ * lib/krb5/creds.c: Added krb5_free_creds_contents and
+ krb5_copy_creds. Changed callers.
+
+ * lib/krb5/config_file.c: new functions krb5_config_get and
+ krb5_config_vget
+
+ * lib/krb5/cache.c: cleanup added mcache
+
+ * kdc/kerberos5.c: include last-req's of type 6 and 7, if
+ applicable
+
+Wed Aug 6 20:38:23 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/log.c: New parameter `log-level'. Default to `SYSLOG'.
+
+Tue Aug 5 22:53:54 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/verify_init.c, init_creds_pw.c, init_creds.c,
+ prompter_posix.c: the beginning of an implementation of the cygnus
+ initial-ticket API.
+
+ * lib/krb5/get_in_tkt_pw.c: make `krb5_password_key_proc' global
+
+ * lib/krb5/get_in_tkt.c (krb5_get_in_cred): new function that is
+ almost krb5_get_in_tkt but doesn't write the creds to the ccache.
+ Small fixes in krb5_get_in_tkt
+
+ * lib/krb5/get_addrs.c (krb5_get_all_client_addrs): don't include
+ loopback.
+
+Mon Aug 4 20:20:48 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc: Make context global.
+
+Fri Aug 1 17:23:56 1997 Assar Westerlund <assar@sics.se>
+
+ * Release 0.0d
+
+ * lib/roken/flock.c: new file
+
+ * kuser/kinit.c: check for and print expiry information in the
+ `kdc_rep'
+
+ * lib/krb5/get_in_tkt.c: Set `ret_as_reply' if != NULL
+
+ * kdc/kerberos5.c: Check the valid times on client and server.
+ Check the password expiration.
+ Check the require_preauth flag.
+ Send an lr_type == 6 with pw_end.
+ Set key.expiration to min(valid_end, pw_end)
+
+ * lib/hdb/hdb.asn1: new flags `require_preauth' and `change_pw'
+
+ * admin/util.c, admin/load.c: handle the new flags.
+
+Fri Aug 1 16:56:12 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/hdb: Add some simple locking.
+
+Sun Jul 27 04:44:31 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/log.c: Add some general logging functions.
+
+ * kdc/kerberos4.c: Add version 4 protocol handler. The requrement
+ for this to work is that all involved principals has a des key in
+ the database, and that the client has a version 4 (un-)salted
+ key. Furthermore krb5_425_conv_principal has to do it's job, as
+ present it's not very clever.
+
+ * lib/krb5/principal.c: Quick patch to make 425_conv work
+ somewhat.
+
+ * lib/hdb/hdb.c: Add keytype->key and next key functions.
+
+Fri Jul 25 17:32:12 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/build_auth.c (krb5_build_authenticator): don't free
+ `cksum'. It's allocated and freed by the caller
+
+ * lib/krb5/get_cred.c (krb5_get_kdc_cred): Don't free `addresses'.
+
+ * kdc/kerberos5.c (tgs_rep2): make sure we also have an defined
+ `client' to return as part of the KRB-ERROR
+
+Thu Jul 24 08:13:59 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kerberos5.c: Unseal keys from database before use.
+
+ * kdc/misc.c: New functions set_master_key, unseal_key and
+ free_key.
+
+ * lib/roken/getarg.c: Handle `-f arg' correctly.
+
+Thu Jul 24 01:54:43 1997 Assar Westerlund <assar@sics.se>
+
+ * kuser/kinit.c: implement `-l' aka `--lifetime'
+
+ * lib/roken/parse_units.c, parse_time.c: new files
+
+ * admin/gettime.c (gettime): use `parse_time'
+
+ * kdc/kerberos5.c (as_rep): Use `METHOD-DATA' when sending
+ KRB5KDC_ERR_PREAUTH_REQUIRED, not PA-DATA.
+
+ * kpasswd/kpasswdd.c: fix freeing bug use sequence numbers set
+ addresses in auth_context bind one socket per interface.
+
+ * kpasswd/kpasswd.c: use sequence numbers
+
+ * lib/krb5/rd_req.c (krb5_verify_ap_req): do abs when verifying
+ the timestamps
+
+ * lib/krb5/rd_priv.c (krb5_rd_priv): Fetch the correct session key
+ from auth_context
+
+ * lib/krb5/mk_priv.c (krb5_mk_priv): Fetch the correct session key
+ from auth_context
+
+ * lib/krb5/mk_error.c (krb5_mk_error): return an error number and
+ not a comerr'd number.
+
+ * lib/krb5/get_in_tkt.c (krb5_get_in_tkt): interpret the error
+ number in KRB-ERROR correctly.
+
+ * lib/krb5/get_cred.c (krb5_get_kdc_cred): interpret the error
+ number in KRB-ERROR correctly.
+
+ * lib/asn1/k5.asn1: Add `METHOD-DATA'
+
+ * removed some memory leaks.
+
+Wed Jul 23 07:53:18 1997 Assar Westerlund <assar@sics.se>
+
+ * Release 0.0c
+
+ * lib/krb5/rd_cred.c, get_for_creds.c: new files
+
+ * lib/krb5/get_host_realm.c: try default realm as last chance
+
+ * kpasswd/kpasswdd.c: updated to hdb changes
+
+ * appl/telnet/libtelnet/kerberos5.c: Implement forwarding
+
+ * appl/telnet/libtelnet: removed totally unused files
+
+ * admin/ank.c: fix prompts and generation of random keys
+
+Wed Jul 23 04:02:32 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * admin/dump.c: Include salt in dump.
+
+ * admin: Mostly updated for new db-format.
+
+ * kdc/kerberos5.c: Update to use new db format. Better checking of
+ flags and such. More logging.
+
+ * lib/hdb/hdb.c: Use generated encode and decode functions.
+
+ * lib/hdb/hdb.h: Get hdb_entry from ASN.1 generated code.
+
+ * lib/krb5/get_cred.c: Get addresses from krbtgt if there are none
+ in the reply.
+
+Sun Jul 20 16:22:30 1997 Assar Westerlund <assar@sics.se>
+
+ * kuser/kinit.c: break if des_read_pw_string() != 0
+
+ * kpasswd/kpasswdd.c: send a reply
+
+ * kpasswd/kpasswd.c: restructured code. better report on
+ krb-error break if des_read_pw_string() != 0
+
+ * kdc/kerberos5.c: Check `require_enc_timestamp' malloc space for
+ starttime and renew_till
+
+ * appl/telnet/libtelnet/kerberos5.c (kerberos5_is): Send a
+ keyblock to krb5_verify_chekcsum
+
+Sun Jul 20 06:35:46 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Release 0.0b
+
+ * kpasswd/kpasswd.c: Avoid using non-standard struct names.
+
+Sat Jul 19 19:26:23 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/keytab.c (krb5_kt_get_entry): check return from
+ `krb5_kt_start_seq_get'. From <map@stacken.kth.se>
+
+Sat Jul 19 04:07:39 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/asn1/k5.asn1: Update with more pa-data types from
+ draft-ietf-cat-kerberos-revisions-00.txt
+
+ * admin/load.c: Update to match current db-format.
+
+ * kdc/kerberos5.c (as_rep): Try all valid pa-datas before giving
+ up. Send back an empty pa-data if the client has the v4 flag set.
+
+ * lib/krb5/get_in_tkt.c: Pass both version5 and version4 salted
+ pa-data. DTRT if there is any pa-data in the reply.
+
+ * lib/krb5/str2key.c: XOR with some sane value.
+
+ * lib/hdb/hdb.h: Add `version 4 salted key' flag.
+
+ * kuser/kinit.c: Ask for password before calling get_in_tkt. This
+ makes it possible to call key_proc more than once.
+
+ * kdc/string2key.c: Add flags to output version 5 (DES only),
+ version 4, and AFS string-to-key of a password.
+
+ * lib/asn1/gen_copy.c: copy_* functions now returns an int (0 or
+ ENOMEM).
+
+Fri Jul 18 02:54:58 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_host_realm.c (krb5_get_host_realm): do the
+ name2name thing
+
+ * kdc/misc.c: check result of hdb_open
+
+ * admin/kdb_edit: updated to new sl
+
+ * lib/sl: sl_func now returns an int. != 0 means to exit.
+
+ * kpasswd/kpasswdd: A crude (but somewhat working) implementation
+ of `draft-ietf-cat-kerb-chg-password-00.txt'
+
+Fri Jul 18 00:55:39 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * kuser/krenew.c: Crude ticket renewing program.
+
+ * kdc/kerberos5.c: Rewritten flags parsing, it now might work to
+ get forwarded and renewed tickets.
+
+ * kuser/kinit.c: Add `-r' flag.
+
+ * lib/krb5/get_cred.c: Move most of contents of get_creds to new
+ function get_kdc_cred, that always contacts the kdc and doesn't
+ save in the cache. This is a hack.
+
+ * lib/krb5/get_in_tkt.c: Pass starttime and renew_till in request
+ (a bit kludgy).
+
+ * lib/krb5/mk_req_ext.c: Make an auth_context if none passed in.
+
+ * lib/krb5/send_to_kdc.c: Get timeout from context.
+
+ * lib/krb5/context.c: Add kdc_timeout to context struct.
+
+Thu Jul 17 20:35:45 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * kuser/klist.c: Print start time of ticket if available.
+
+ * lib/krb5/get_host_realm.c: Return error if no realm was found.
+
+Thu Jul 17 20:28:21 1997 Assar Westerlund <assar@sics.se>
+
+ * kpasswd: non-working kpasswd added
+
+Thu Jul 17 00:21:22 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * Release 0.0a
+
+ * kdc/main.c: Add -p flag to disable pa-enc-timestamp requirement.
+
+Wed Jul 16 03:37:41 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/kerberos5.c (tgs_rep2): Free ticket and ap_req.
+
+ * lib/krb5/auth_context.c (krb5_auth_con_free): Free remote
+ subkey.
+
+ * lib/krb5/principal.c (krb5_free_principal): Check for NULL.
+
+ * lib/krb5/send_to_kdc.c: Check for NULL return from
+ gethostbyname.
+
+ * lib/krb5/set_default_realm.c: Try to get realm of local host if
+ no default realm is available.
+
+ * Remove non ASN.1 principal code.
+
+Wed Jul 16 03:17:30 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * kdc/kerberos5.c: Split tgs_rep in smaller functions. Add better
+ error handing. Do some logging.
+
+ * kdc/log.c: Some simple logging facilities.
+
+ * kdc/misc.c (db_fetch): Take a krb5_principal.
+
+ * kdc/connect.c: Pass address of request to as_rep and
+ tgs_rep. Send KRB-ERROR.
+
+ * lib/krb5/mk_error.c: Add more fields.
+
+ * lib/krb5/get_cred.c: Print normal error code if no e_text is
+ available.
+
+Wed Jul 16 03:07:50 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_in_tkt.c: implement `krb5_init_etype'.
+ Change encryption type of pa_enc_timestamp to DES-CBC-MD5
+
+ * lib/krb5/context.c: recognize all encryption types actually
+ implemented
+
+ * lib/krb5/auth_context.c (krb5_auth_con_init): Change default
+ encryption type to `DES_CBC_MD5'
+
+ * lib/krb5/read_message.c, write_message.c: new files
+
+Tue Jul 15 17:14:21 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1: replaced asn1_locl.h by `der_locl.h' and `gen_locl.h'.
+
+ * lib/error/compile_et.awk: generate a prototype for the
+ `destroy_foo_error_table' function.
+
+Mon Jul 14 12:24:40 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/krbhst.c (krb5_get_krbhst): Get all kdc's and try also
+ with `kerberos.REALM'
+
+ * kdc/kerberos5.c, lib/krb5/rd_priv.c, lib/krb5/rd_safe.c: use
+ `max_skew'
+
+ * lib/krb5/rd_req.c (krb5_verify_ap_req): record authenticator
+ subkey
+
+ * lib/krb5/build_auth.c (krb5_build_authenticator): always
+ generate a subkey.
+
+ * lib/krb5/address.c: implement `krb5_address_order'
+
+ * lib/gssapi/import_name.c: Implement `gss_import_name'
+
+ * lib/gssapi/external.c: Use new OID
+
+ * lib/gssapi/encapsulate.c: New functions
+ `gssapi_krb5_encap_length' and `gssapi_krb5_make_header'. Changed
+ callers.
+
+ * lib/gssapi/decapsulate.c: New function
+ `gssaspi_krb5_verify_header'. Changed callers.
+
+ * lib/asn1/gen*.c: Give tags to generated structs.
+ Use `err' and `asprintf'
+
+ * appl/test/gss_common.c: new file
+
+ * appl/test/gssapi_server.c: removed all krb5 calls
+
+ * appl/telnet/libtelnet/kerberos5.c: Add support for genering and
+ verifying checksums. Also start using session subkeys.
+
+Mon Jul 14 12:08:25 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/rd_req.c (krb5_rd_req_with_keyblock): Split up.
+
+Sun Jul 13 03:07:44 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/rd_safe.c, mk_safe.c: made bug-compatible with MIT
+
+ * lib/krb5/encrypt.c: new functions `DES_encrypt_null_ivec' and
+ `DES_encrypt_key_ivec'
+
+ * lib/krb5/checksum.c: implement rsa-md4-des and rsa-md5-des
+
+ * kdc/kerberos5.c (tgs_rep): support keyed checksums
+
+ * lib/krb5/creds.c: new file
+
+ * lib/krb5/get_in_tkt.c: better freeing
+
+ * lib/krb5/context.c (krb5_free_context): more freeing
+
+ * lib/krb5/config_file.c: New function `krb5_config_file_free'
+
+ * lib/error/compile_et.awk: Generate a `destroy_' function.
+
+ * kuser/kinit.c, klist.c: Don't leak memory.
+
+Sun Jul 13 02:46:27 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kdc/connect.c: Check filedescriptor in select.
+
+ * kdc/kerberos5.c: Remove most of the most common memory leaks.
+
+ * lib/krb5/rd_req.c: Free allocated data.
+
+ * lib/krb5/auth_context.c (krb5_auth_con_free): Free a lot of
+ fields.
+
+Sun Jul 13 00:32:16 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/telnet: Conditionalize the krb4-support.
+
+ * configure.in: Test for krb4
+
+Sat Jul 12 17:14:12 1997 Assar Westerlund <assar@sics.se>
+
+ * kdc/kerberos5.c: check if the pre-auth was decrypted properly.
+ set the `pre_authent' flag
+
+ * lib/krb5/get_cred.c, lib/krb5/get_in_tkt.c: generate a random nonce.
+
+ * lib/krb5/encrypt.c: Made `generate_random_block' global.
+
+ * appl/test: Added gssapi_client and gssapi_server.
+
+ * lib/krb5/data.c: Add `krb5_data_zero'
+
+ * appl/test/tcp_client.c: try `mk_safe' and `mk_priv'
+
+ * appl/test/tcp_server.c: try `rd_safe' and `rd_priv'
+
+Sat Jul 12 16:45:58 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/get_addrs.c: Fix for systems that has sa_len, but
+ returns zero length from SIOCGIFCONF.
+
+Sat Jul 12 16:38:34 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/test: new programs
+
+ * lib/krb5/rd_req.c: add address compare
+
+ * lib/krb5/mk_req_ext.c: allow no checksum
+
+ * lib/krb5/keytab.c (krb5_kt_ret_string): 0-terminate string
+
+ * lib/krb5/address.c: fix `krb5_address_compare'
+
+Sat Jul 12 15:03:16 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/get_addrs.c: Fix ip4 address extraction.
+
+ * kuser/klist.c: Add verbose flag, and split main into smaller
+ pieces.
+
+ * lib/krb5/fcache.c: Save ticket flags.
+
+ * lib/krb5/get_in_tkt.c (extract_ticket): Extract addresses and
+ flags.
+
+ * lib/krb5/krb5.h: Add ticket_flags to krb5_creds.
+
+Sat Jul 12 13:12:48 1997 Assar Westerlund <assar@sics.se>
+
+ * configure.in: Call `AC_KRB_PROG_LN_S'
+
+ * acinclude.m4: Add `AC_KRB_PROG_LN_S' from krb4
+
+Sat Jul 12 00:57:01 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/get_in_tkt.c: Use union of krb5_flags and KDCOptions to
+ pass options.
+
+Fri Jul 11 15:04:22 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/telnet: telnet & telnetd seems to be working.
+
+ * lib/krb5/config_file.c: Added krb5_config_v?get_list Fixed
+ krb5_config_vget_next
+
+ * appl/telnet/libtelnet/kerberos5.c: update to current API
+
+Thu Jul 10 14:54:39 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/telnet/libtelnet/kerberos5.c (kerberos5_status): call
+ `krb5_kuserok'
+
+ * appl/telnet: Added.
+
+Thu Jul 10 05:09:25 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/error/compile_et.awk: Remove usage of sub, gsub, and
+ functions for compatibility with awk.
+
+ * include/bits.c: Must use signed char.
+
+ * lib/krb5/context.c: Move krb5_get_err_text, and krb5_init_ets
+ here.
+
+ * lib/error/error.c: Replace krb5_get_err_text with new function
+ com_right.
+
+ * lib/error/compile_et.awk: Avoid using static variables.
+
+ * lib/error/error.c: Don't use krb5_locl.h
+
+ * lib/error/error.h: Move definitions of error_table and
+ error_list from krb5.h.
+
+ * lib/error: Moved from lib/krb5.
+
+Wed Jul 9 07:42:04 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/encrypt.c: Temporary hack to avoid des_rand_data.
+
+Wed Jul 9 06:58:00 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/{rd,mk}_{*}.c: more checking for addresses and stuff
+ according to pseudocode from 1510
+
+Wed Jul 9 06:06:06 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/hdb/hdb.c: Add hdb_etype2key.
+
+ * kdc/kerberos5.c: Check authenticator. Use more general etype
+ functions.
+
+Wed Jul 9 03:51:12 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/k5.asn1: Made all `s_address' OPTIONAL according to
+ draft-ietf-cat-kerberos-r-00.txt
+
+ * lib/krb5/principal.c (krb5_parse_name): default to local realm
+ if none given
+
+ * kuser/kinit.c: New option `-p' and prompt
+
+Wed Jul 9 02:30:06 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/keyblock.c: Keyblock generation functions.
+
+ * lib/krb5/encrypt.c: Use functions from checksum.c.
+
+ * lib/krb5/checksum.c: Move checksum functions here. Add
+ krb5_cksumsize function.
+
+Wed Jul 9 01:15:38 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/get_host_realm.c: implemented
+
+ * lib/krb5/config_file.c: Redid part. New functions:
+ krb5_config_v?get_next
+
+ * kuser/kdestroy.c: new program
+
+ * kuser/kinit.c: new flag `-f'
+
+ * lib/asn1/k5.asn1: Made HostAddresses = SEQUENCE OF HostAddress
+
+ * acinclude.m4: Added AC_KRB_STRUCT_SOCKADDR_SA_LEN
+
+ * lib/krb5/krb5.h: krb5_addresses == HostAddresses. Changed all
+ users.
+
+ * lib/krb5/get_addrs.c: figure out all local addresses, possibly
+ even IPv6!
+
+ * lib/krb5/checksum.c: table-driven checksum
+
+Mon Jul 7 21:13:28 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/encrypt.c: Make krb5_decrypt use the same struct as
+ krb5_encrypt.
+
+Mon Jul 7 11:15:51 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/roken/vsyslog.c: new file
+
+ * lib/krb5/encrypt.c: add des-cbc-md4.
+ adjust krb5_encrypt and krb5_decrypt to reality
+
+Mon Jul 7 02:46:31 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/encrypt.c: Implement as a vector of function pointers.
+
+ * lib/krb5/{decrypt,encrypt}.c: Implement des-cbc-crc, and
+ des-cbc-md5 in separate functions.
+
+ * lib/krb5/krb5.h: Add more checksum and encryption types.
+
+ * lib/krb5/krb5_locl.h: Add etype to krb5_decrypt.
+
+Sun Jul 6 23:02:59 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/[gs]et_default_realm.c, kuserok.c: new files
+
+ * lib/krb5/config_file.[ch]: new c-based configuration reading
+ stuff
+
+Wed Jul 2 23:12:56 1997 Assar Westerlund <assar@sics.se>
+
+ * configure.in: Set WFLAGS if using gcc
+
+Wed Jul 2 17:47:03 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/asn1/der_put.c (der_put_int): Return size correctly.
+
+ * admin/ank.c: Be compatible with the asn1 principal format.
+
+Wed Jul 1 23:52:20 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/asn1: Now all decode_* and encode_* functions now take a
+ final size_t* argument, that they return the size in. Return
+ values are zero for success, and anything else (such as some
+ ASN1_* constant) for error.
+
+Mon Jun 30 06:08:14 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/keytab.c (krb5_kt_add_entry): change open mode to
+ O_WRONLY | O_APPEND
+
+ * lib/krb5/get_cred.c: removed stale prototype for
+ `extract_ticket' and corrected call.
+
+ * lib/asn1/gen_length.c (length_type): Make the length functions
+ for SequenceOf non-destructive
+
+ * admin/ank.c (doit): Fix reading of `y/n'.
+
+Mon Jun 16 05:41:43 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/gssapi/wrap.c, unwrap.c: do encrypt and add sequence number
+
+ * lib/gssapi/get_mic.c, verify_mic.c: Add sequence number.
+
+ * lib/gssapi/accept_sec_context.c (gss_accept_sec_context): Set
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE. Verify 8003 checksum.
+
+ * lib/gssapi/8003.c: New file.
+
+ * lib/krb/krb5.h: Define a `krb_authenticator' as an ASN.1
+ Authenticator.
+
+ * lib/krb5/auth_context.c: New functions
+ `krb5_auth_setlocalseqnumber' and `krb5_auth_setremoteseqnumber'
+
+Tue Jun 10 00:35:54 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5: Preapre for use of some asn1-types.
+
+ * lib/asn1/*.c (copy_*): Constness.
+
+ * lib/krb5/krb5.h: Include asn1.h; krb5_data is now an
+ octet_string.
+
+ * lib/asn1/der*,gen.c: krb5_data -> octet_string, char * ->
+ general_string
+
+ * lib/asn1/libasn1.h: Moved stuff from asn1_locl.h that doesn't
+ have anything to do with asn1_compile.
+
+ * lib/asn1/asn1_locl.h: Remove der.h. Add some prototypes.
+
+Sun Jun 8 03:51:55 1997 Assar Westerlund <assar@sics.se>
+
+ * kdc/kerberos5.c: Fix PA-ENC-TS-ENC
+
+ * kdc/connect.c(process_request): Set `new'
+
+ * lib/krb5/get_in_tkt.c: Do PA-ENC-TS-ENC the correct way.
+
+ * lib: Added editline,sl,roken.
+
+Mon Jun 2 00:37:48 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/fcache.c: Move file cache from cache.c.
+
+ * lib/krb5/cache.c: Allow more than one cache type.
+
+Sun Jun 1 23:45:33 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * admin/extkeytab.c: Merged with kdb_edit.
+
+Sun Jun 1 23:23:08 1997 Assar Westerlund <assar@sics.se>
+
+ * kdc/kdc.c: more support for ENC-TS-ENC
+
+ * lib/krb5/get_in_tkt.c: redone to enable pre-authentication
+
+Sun Jun 1 22:45:11 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/hdb/db.c: Merge fetch and store.
+
+ * admin: Merge to one program.
+
+ * lib/krb5/str2key.c: Fill in keytype and length.
+
+Sun Jun 1 16:31:23 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/rd_safe.c, lib/krb5/rd_priv.c, lib/krb5/mk_rep.c,
+ lib/krb5/mk_priv.c, lib/krb5/build_auth.c: Some support for
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE
+
+ * lib/krb5/get_in_tkt.c (get_in_tkt): be prepared to parse an
+ KRB_ERROR. Some support for PA_ENC_TS_ENC.
+
+ * lib/krb5/auth_context.c: implemented seq_number functions
+
+ * lib/krb5/generate_subkey.c, generate_seq_number.c: new files
+
+ * lib/gssapi/gssapi.h: avoid including <krb5.h>
+
+ * lib/asn1/Makefile.am: SUFFIXES as a variable to make automake
+ happy
+
+ * kdc/kdc.c: preliminary PREAUTH_ENC_TIMESTAMP
+
+ * configure.in: adapted to automake 1.1p
+
+Mon May 26 22:26:21 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/principal.c: Add contexts to many functions.
+
+Thu May 15 20:25:37 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/verify_user.c: First stab at a verify user.
+
+ * lib/auth/sia/sia5.c: SIA module for Kerberos 5.
+
+Mon Apr 14 00:09:03 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/gssapi: Enough of a gssapi-over-krb5 implementation to be
+ able to (mostly) run gss-client and gss-server.
+
+ * lib/krb5/keytab.c: implemented krb5_kt_add_entry,
+ krb5_kt_store_principal, krb5_kt_store_keyblock
+
+ * lib/des/md5.[ch], sha.[ch]: new files
+
+ * lib/asn1/der_get.c (generalizedtime2time): use `timegm'
+
+ * lib/asn1/timegm.c: new file
+
+ * admin/extkeytab.c: new program
+
+ * admin/admin_locl.h: new file
+
+ * admin/Makefile.am: Added extkeytab
+
+ * configure.in: moved config to include
+ removed timezone garbage
+ added lib/gssapi and admin
+
+ * Makefile.am: Added admin
+
+Mon Mar 17 11:34:05 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * kdc/kdc.c: Use new copying functions, and free some data.
+
+ * lib/asn1/Makefile.am: Try to not always rebuild generated files.
+
+ * lib/asn1/der_put.c: Add fix_dce().
+
+ * lib/asn1/der_{get,length,put}.c: Fix include files.
+
+ * lib/asn1/der_free.c: Remove unused functions.
+
+ * lib/asn1/gen.c: Split into gen_encode, gen_decode, gen_free,
+ gen_length, and gen_copy.
+
+Sun Mar 16 18:13:52 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/sendauth.c: implemented functionality
+
+ * lib/krb5/rd_rep.c: Use `krb5_decrypt'
+
+ * lib/krb5/cache.c (krb5_cc_get_name): return default if `id' ==
+ NULL
+
+ * lib/krb5/principal.c (krb5_free_principal): added `context'
+ argument. Changed all callers.
+
+ (krb5_sname_to_principal): new function
+
+ * lib/krb5/auth_context.c (krb5_free_authenticator): add `context'
+ argument. Changed all callers
+
+ * lib/krb5/{net_write.c,net_read.c,recvauth.c}: new files
+
+ * lib/asn1/gen.c: Fix encoding and decoding of BitStrings
+
+Fri Mar 14 11:29:00 1997 Assar Westerlund <assar@sics.se>
+
+ * configure.in: look for *dbm?
+
+ * lib/asn1/gen.c: Fix filename in generated files. Check fopens.
+ Put trailing newline in asn1_files.
+
+Fri Mar 14 05:06:44 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/get_in_tkt.c: Fix some memory leaks.
+
+ * lib/krb5/krbhst.c: Properly free hostlist.
+
+ * lib/krb5/decrypt.c: CRCs are 32 bits.
+
+Fri Mar 14 04:39:15 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/asn1/gen.c: Generate one file for each type.
+
+Fri Mar 14 04:13:47 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/gen.c: Generate `length_FOO' functions
+
+ * lib/asn1/der_length.c: new file
+
+ * kuser/klist.c: renamed stime -> printable_time to avoid conflict
+ on HP/UX
+
+Fri Mar 14 03:37:23 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/hdb/ndbm.c: Return NOENTRY if fetch fails. Don't free
+ datums. Don't add .db to filename.
+
+Fri Mar 14 02:49:51 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * kdc/dump.c: Database dump program.
+
+ * kdc/ank.c: Trivial database editing program.
+
+ * kdc/{kdc.c, load.c}: Use libhdb.
+
+ * lib/hdb: New database routine library.
+
+ * lib/krb5/error/Makefile.am: Add hdb_err.
+
+Wed Mar 12 17:41:14 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * kdc/kdc.c: Rewritten AS, and somewhat more working TGS support.
+
+ * lib/asn1/gen.c: Generate free functions.
+
+ * Some specific free functions.
+
+Wed Mar 12 12:30:13 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/krb5_mk_req_ext.c: new file
+
+ * lib/asn1/gen.c: optimize the case with a simple type
+
+ * lib/krb5/get_cred.c (krb5_get_credentials): Use
+ `mk_req_extended' and remove old code.
+
+ * lib/krb5/get_in_tkt.c (decrypt_tkt): First try with an
+ EncASRepPart, then with an EncTGSRepPart.
+
+Wed Mar 12 08:26:04 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/store_emem.c: New resizable memory storage.
+
+ * lib/krb5/{store.c, store_fd.c, store_mem.c}: Split of store.c
+
+ * lib/krb5/krb5.h: Add free entry to krb5_storage.
+
+ * lib/krb5/decrypt.c: Make keyblock const.
+
+Tue Mar 11 20:22:17 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/krb5.h: Add EncTicketPart to krb5_ticket.
+
+ * lib/krb5/rd_req.c: Return whole asn.1 ticket in
+ krb5_ticket->tkt.
+
+ * lib/krb5/get_in_tkt.c: TGS -> AS
+
+ * kuser/kfoo.c: Print error string rather than number.
+
+ * kdc/kdc.c: Some kind of non-working TGS support.
+
+Mon Mar 10 01:43:22 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/asn1/gen.c: reduced generated code by 1/5
+
+ * lib/asn1/der_put.c: (der_put_length_and_tag): new function
+
+ * lib/asn1/der_get.c (der_match_tag_and_length): new function
+
+ * lib/asn1/der.h: added prototypes
+
+Mon Mar 10 01:15:43 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/krb5.h: Include <asn1_err.h>. Add prototype for
+ krb5_rd_req_with_keyblock.
+
+ * lib/krb5/rd_req.c: Add function krb5_rd_req_with_keyblock that
+ takes a precomputed keyblock.
+
+ * lib/krb5/get_cred.c: Use krb5_mk_req rather than inlined code.
+
+ * lib/krb5/mk_req.c: Calculate checksum of in_data.
+
+Sun Mar 9 21:17:58 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/error/compile_et.awk: Add a declaration of struct
+ error_list, and multiple inclusion block to header files.
+
+Sun Mar 9 21:01:12 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/rd_req.c: do some checks on times
+
+ * lib/krb/{mk_priv.c, rd_priv.c, sendauth.c, decrypt.c,
+ address.c}: new files
+
+ * lib/krb5/auth_context.c: more code
+
+ * configure.in: try to figure out timezone
+
+Sat Mar 8 11:41:07 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/error/error.c: Try strerror if error code wasn't found.
+
+ * lib/krb5/get_in_tkt.c: Remove realm parameter from
+ krb5_get_salt.
+
+ * lib/krb5/context.c: Initialize error table.
+
+ * kdc: The beginnings of a kdc.
+
+Sat Mar 8 08:16:28 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/rd_safe.c: new file
+
+ * lib/krb5/checksum.c (krb5_verify_checksum): New function
+
+ * lib/krb5/get_cred.c: use krb5_create_checksum
+
+ * lib/krb5/checksum.c: new file
+
+ * lib/krb5/store.c: no more arithmetic with void*
+
+ * lib/krb5/cache.c: now seems to work again
+
+Sat Mar 8 06:58:09 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/Makefile.am: Add asn1_glue.c and error/*.c to libkrb5.
+
+ * lib/krb5/get_in_tkt.c: Moved some functions to asn1_glue.c.
+
+ * lib/krb5/asn1_glue.c: Moved some asn1-stuff here.
+
+ * lib/krb5/{cache,keytab}.c: Use new storage functions.
+
+ * lib/krb5/krb5.h: Protypes for new storage functions.
+
+ * lib/krb5/krb5.h: Make krb5_{ret,store}_* functions able to write
+ data to more than file descriptors.
+
+Sat Mar 8 01:01:17 1997 Assar Westerlund <assar@sics.se>
+
+ * lib/krb5/encrypt.c: New file.
+
+ * lib/krb5/Makefile.am: More -I
+
+ * configure.in: Test for big endian, random, rand, setitimer
+
+ * lib/asn1/gen.c: perhaps even decodes bitstrings
+
+Thu Mar 6 19:05:29 1997 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * lib/krb5/config_file.y: Better return values on error.
+
+Sat Feb 8 15:59:56 1997 Assar Westerlund <assar@pdc.kth.se>
+
+ * lib/asn1/parse.y: ifdef HAVE_STRDUP
+
+ * lib/asn1/lex.l: ifdef strdup
+ brange-dead version of list of special characters to make stupid
+ lex accept it.
+
+ * lib/asn1/gen.c: A DER integer should really be a `unsigned'
+
+ * lib/asn1/der_put.c: A DER integer should really be a `unsigned'
+
+ * lib/asn1/der_get.c: A DER integer should really be a `unsigned'
+
+ * lib/krb5/error/Makefile.am: It seems "$(SHELL) ./compile_et" is
+ needed.
+
+ * lib/krb/mk_rep.c, lib/krb/rd_req.c, lib/krb/store.c,
+ lib/krb/store.h: new files.
+
+ * lib/krb5/keytab.c: now even with some functionality.
+
+ * lib/asn1/gen.c: changed paramater from void * to Foo *
+
+ * lib/asn1/der_get.c (der_get_octet_string): Fixed bug with empty
+ string.
+
+Sun Jan 19 06:17:39 1997 Assar Westerlund <assar@pdc.kth.se>
+
+ * lib/krb5/get_cred.c (krb5_get_credentials): Check for creds in
+ cc before getting new ones.
+
+ * lib/krb5/krb5.h (krb5_free_keyblock): Fix prototype.
+
+ * lib/krb5/build_auth.c (krb5_build_authenticator): It seems the
+ CRC should be stored LSW first. (?)
+
+ * lib/krb5/auth_context.c: Implement `krb5_auth_con_getkey' and
+ `krb5_free_keyblock'
+
+ * lib/**/Makefile.am: Rename foo libfoo.a
+
+ * include/Makefile.in: Use test instead of [
+ -e does not work with /bin/sh on psoriasis
+
+ * configure.in: Search for awk
+ create lib/krb/error/compile_et
+
+Tue Jan 14 03:46:26 1997 Assar Westerlund <assar@pdc.kth.se>
+
+ * lib/krb5/Makefile.am: replaced mit-crc.c by crc.c
+
+Wed Dec 18 00:53:55 1996 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kuser/kinit.c: Guess principal.
+
+ * lib/krb5/error/compile_et.awk: Don't include krb5.h. Fix some
+ warnings.
+
+ * lib/krb5/error/asn1_err.et: Add ASN.1 error messages.
+
+ * lib/krb5/mk_req.c: Get client from cache.
+
+ * lib/krb5/cache.c: Add better error checking some useful return
+ values.
+
+ * lib/krb5/krb5.h: Fix krb5_auth_context.
+
+ * lib/asn1/der.h: Make krb5_data compatible with krb5.h
+
+Tue Dec 17 01:32:36 1996 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/error: Add primitive error library.
+
+Mon Dec 16 16:30:20 1996 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lib/krb5/cache.c: Get correct address type from cache.
+
+ * lib/krb5/krb5.h: Change int16 to int to be compatible with asn1.
+
diff --git a/crypto/heimdal/Makefile.am b/crypto/heimdal/Makefile.am
new file mode 100644
index 000000000000..919d69cee3e8
--- /dev/null
+++ b/crypto/heimdal/Makefile.am
@@ -0,0 +1,9 @@
+# $Id: Makefile.am,v 1.14 1999/08/12 02:21:43 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+SUBDIRS = include lib kuser kdc admin kadmin kpasswd appl doc
+
+ACLOCAL = @ACLOCAL@ -I cf
+
+EXTRA_DIST = Makefile.am.common krb5.conf
diff --git a/crypto/heimdal/Makefile.am.common b/crypto/heimdal/Makefile.am.common
new file mode 100644
index 000000000000..d8452bd4a30d
--- /dev/null
+++ b/crypto/heimdal/Makefile.am.common
@@ -0,0 +1,35 @@
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+include $(top_srcdir)/cf/Makefile.am.common
+
+SUFFIXES += .x
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+CHECK_LOCAL = $(PROGRAMS)
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
diff --git a/crypto/heimdal/Makefile.in b/crypto/heimdal/Makefile.in
new file mode 100644
index 000000000000..28684cb824ba
--- /dev/null
+++ b/crypto/heimdal/Makefile.in
@@ -0,0 +1,645 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.14 1999/08/12 02:21:43 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+SUBDIRS = include lib kuser kdc admin kadmin kpasswd appl doc
+
+ACLOCAL = @ACLOCAL@ -I cf
+
+EXTRA_DIST = Makefile.am.common krb5.conf
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ./include/config.h
+CONFIG_CLEAN_FILES =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in NEWS TODO acinclude.m4 \
+aclocal.m4 config.guess config.sub configure configure.in install-sh \
+ltconfig ltmain.sh missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .et .h .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-recursive
+
+install-data-am: install-data-local
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile all-local
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/NEWS b/crypto/heimdal/NEWS
new file mode 100644
index 000000000000..a4a9a7b4c5fa
--- /dev/null
+++ b/crypto/heimdal/NEWS
@@ -0,0 +1,272 @@
+Changes in release 0.2m:
+
+ * handle glibc's getaddrinfo() that returns several ai_canonname
+
+ * new endian test
+
+ * man pages fixes
+
+Changes in release 0.2l:
+
+ * bug fixes
+
+Changes in release 0.2k:
+
+ * better IPv6 test
+
+ * make struct sockaddr_storage in roken work better on alphas
+
+ * some missing [hn]to[hn]s fixed.
+
+ * allow users to change their own passwords with kadmin (with initial
+ tickets)
+
+ * fix stupid bug in parsing KDC specification
+
+ * add `ktutil change' and `ktutil purge'
+
+Changes in release 0.2j:
+
+ * builds on Irix
+
+ * ftpd works in passive mode
+
+ * should build on cygwin
+
+ * work around broken IPv6-code on OpenBSD 2.6, also add configure
+ option --disable-ipv6
+
+Changes in release 0.2i:
+
+ * use getaddrinfo in the missing places.
+
+ * fix SRV lookup for admin server
+
+ * use get{addr,name}info everywhere. and implement it in terms of
+ getipnodeby{name,addr} (which uses gethostbyname{,2} and
+ gethostbyaddr)
+
+Changes in release 0.2h:
+
+ * fix typo in kx (now compiles)
+
+Changes in release 0.2g:
+
+ * lots of bug fixes:
+ * push works
+ * repair appl/test programs
+ * sockaddr_storage works on solaris (alignment issues)
+ * works better with non-roken getaddrinfo
+ * rsh works
+ * some non standard C constructs removed
+
+Changes in release 0.2f:
+
+ * support SRV records for kpasswd
+ * look for both _kerberos and krb5-realm when doing host -> realm mapping
+
+Changes in release 0.2e:
+
+ * changed copyright notices to remove `advertising'-clause.
+ * get{addr,name}info added to roken and used in the other code
+ (this makes things work much better with hosts with both v4 and v6
+ addresses, among other things)
+ * do pre-auth for both password and key-based get_in_tkt
+ * support for having several databases
+ * new command `del_enctype' in kadmin
+ * strptime (and new strftime) add to roken
+ * more paranoia about finding libdb
+ * bug fixes
+
+Changes in release 0.2d:
+
+ * new configuration option [libdefaults]default_etypes_des
+ * internal ls in ftpd builds without KRB4
+ * kx/rsh/push/pop_debug tries v5 and v4 consistenly
+ * build bug fixes
+ * other bug fixes
+
+Changes in release 0.2c:
+
+ * bug fixes (see ChangeLog's for details)
+
+Changes in release 0.2b:
+
+ * bug fixes
+ * actually bump shared library versions
+
+Changes in release 0.2a:
+
+ * a new program verify_krb5_conf for checking your /etc/krb5.conf
+ * add 3DES keys when changing password
+ * support null keys in database
+ * support multiple local realms
+ * implement a keytab backend for AFS KeyFile's
+ * implement a keytab backend for v4 srvtabs
+ * implement `ktutil copy'
+ * support password quality control in v4 kadmind
+ * improvements in v4 compat kadmind
+ * handle the case of having the correct cred in the ccache but with
+ the wrong encryption type better
+ * v6-ify the remaining programs.
+ * internal ls in ftpd
+ * rename strcpy_truncate/strcat_truncate to strlcpy/strlcat
+ * add `ank --random-password' and `cpw --random-password' in kadmin
+ * some programs and documentation for trying to talk to a W2K KDC
+ * bug fixes
+
+Changes in release 0.1m:
+
+ * support for getting default from krb5.conf for kinit/kf/rsh/telnet.
+ From Miroslav Ruda <ruda@ics.muni.cz>
+ * v6-ify hprop and hpropd
+ * support numeric addresses in krb5_mk_req
+ * shadow support in login and su. From Miroslav Ruda <ruda@ics.muni.cz>
+ * make rsh/rshd IPv6-aware
+ * make the gssapi sample applications better at reporting errors
+ * lots of bug fixes
+ * handle systems with v6-aware libc and non-v6 kernels (like Linux
+ with glibc 2.1) better
+ * hide failure of ERPT in ftp
+ * lots of bug fixes
+
+Changes in release 0.1l:
+
+ * make ftp and ftpd IPv6-aware
+ * add inet_pton to roken
+ * more IPv6-awareness
+ * make mini_inetd v6 aware
+
+Changes in release 0.1k:
+
+ * bump shared libraries versions
+ * add roken version of inet_ntop
+ * merge more changes to rshd
+
+Changes in release 0.1j:
+
+ * restore back to the `old' 3DES code. This was supposed to be done
+ in 0.1h and 0.1i but I did a CVS screw-up.
+ * make telnetd handle v6 connections
+
+Changes in release 0.1i:
+
+ * start using `struct sockaddr_storage' which simplifies the code
+ (with a fallback definition if it's not defined)
+ * bug fixes (including in hprop and kf)
+ * don't use mawk which seems to mishandle roken.awk
+ * get_addrs should be able to handle v6 addresses on Linux (with the
+ required patch to the Linux kernel -- ask within)
+ * rshd builds with shadow passwords
+
+Changes in release 0.1h:
+
+ * kf: new program for forwarding credentials
+ * portability fixes
+ * make forwarding credentials work with MIT code
+ * better conversion of ka database
+ * add etc/services.append
+ * correct `modified by' from kpasswdd
+ * lots of bug fixes
+
+Changes in release 0.1g:
+
+ * kgetcred: new program for explicitly obtaining tickets
+ * configure fixes
+ * krb5-aware kx
+ * bug fixes
+
+Changes in release 0.1f;
+
+ * experimental support for v4 kadmin protokoll in kadmind
+ * bug fixes
+
+Changes in release 0.1e:
+
+ * try to handle old DCE and MIT kdcs
+ * support for older versions of credential cache files and keytabs
+ * postdated tickets work
+ * support for password quality checks in kpasswdd
+ * new flag --enable-kaserver for kdc
+ * renew fixes
+ * prototype su program
+ * updated (some) manpages
+ * support for KDC resource records
+ * should build with --without-krb4
+ * bug fixes
+
+Changes in release 0.1d:
+
+ * Support building with DB2 (uses 1.85-compat API)
+ * Support krb5-realm.DOMAIN in DNS
+ * new `ktutil srvcreate'
+ * v4/kafs support in klist/kdestroy
+ * bug fixes
+
+Changes in release 0.1c:
+
+ * fix ASN.1 encoding of signed integers
+ * somewhat working `ktutil get'
+ * some documentation updates
+ * update to Autoconf 2.13 and Automake 1.4
+ * the usual bug fixes
+
+Changes in release 0.1b:
+
+ * some old -> new crypto conversion utils
+ * bug fixes
+
+Changes in release 0.1a:
+
+ * new crypto code
+ * more bug fixes
+ * make sure we ask for DES keys in gssapi
+ * support signed ints in ASN1
+ * IPv6-bug fixes
+
+Changes in release 0.0u:
+
+ * lots of bug fixes
+
+Changes in release 0.0t:
+
+ * more robust parsing of krb5.conf
+ * include net{read,write} in lib/roken
+ * bug fixes
+
+Changes in release 0.0s:
+
+ * kludges for parsing options to rsh
+ * more robust parsing of krb5.conf
+ * removed some arbitrary limits
+ * bug fixes
+
+Changes in release 0.0r:
+
+ * default options for some programs
+ * bug fixes
+
+Changes in release 0.0q:
+
+ * support for building shared libraries with libtool
+ * bug fixes
+
+Changes in release 0.0p:
+
+ * keytab moved to /etc/krb5.keytab
+ * avoid false detection of IPv6 on Linux
+ * Lots of more functionality in the gssapi-library
+ * hprop can now read ka-server databases
+ * bug fixes
+
+Changes in release 0.0o:
+
+ * FTP with GSSAPI support.
+ * Bug fixes.
+
+Changes in release 0.0n:
+
+ * Incremental database propagation.
+ * Somewhat improved kadmin ui; the stuff in admin is now removed.
+ * Some support for using enctypes instead of keytypes.
+ * Lots of other improvement and bug fixes, see ChangeLog for details.
diff --git a/crypto/heimdal/TODO b/crypto/heimdal/TODO
new file mode 100644
index 000000000000..95d5caad2770
--- /dev/null
+++ b/crypto/heimdal/TODO
@@ -0,0 +1,103 @@
+-*- indented-text -*-
+
+$Id: TODO,v 1.39 1999/12/05 01:08:19 assar Exp $
+
+* configure
+
+use more careful checking before starting to use berkeley db. it only
+makes sense to do so if we have the appropriate library and the header
+file.
+
+* appl
+
+more programs here
+
+** appl/login
+
+/etc/environment etc.
+
+** appl/popper
+
+Implement RFC1731 and 1734, pop over GSS-API
+
+** appl/test
+
+should test more stuff
+
+** appl/rsh
+
+add rcp program
+
+** appl/ftp
+
+* doc
+
+there's some room for improvement here.
+
+* kdc
+
+* kadmin
+
+is in need of a major cleanup
+
+* lib
+
+** lib/asn1
+
+prepend a prefix on all generated symbols
+
+make asn1_compile use enum types where applicable
+
+** lib/auth
+
+PAM
+
+** lib/des
+
+** lib/gssapi
+
+process_context_token, display_status, add_cred, inquire_cred_by_mech,
+export_sec_context, import_sec_context, inquire_names_for_mech, and
+inquire_mechs_for_name not implemented.
+
+only DES MAC MD5 and DES implemented.
+
+set minor_status in all functions
+
+init_sec_context: `initiator_cred_handle' and `time_req' ignored.
+
+input channel bindings are not supported
+
+delegation not implemented
+
+anonymous credentials not implemented
+
+** lib/hdb
+
+** lib/kadm5
+
+add policies?
+
+fix to use rpc?
+
+** lib/krb5
+
+the replay cache is, in its current state, not very useful
+
+the following encryption types have been implemented: DES-CBC-CRC,
+DES-CBC-MD4, DES-CBC-MD5, DES3-CBC-MD5, DES3-CBC-SHA1
+
+supports the following checksums: CRC32, RSA-MD4, RSA-MD5,
+RSA-MD4-DES, RSA-MD5-DES, RSA-MD5-DES3, SHA1, HMAC-SHA1-DES3
+
+always generates a new subkey in an authenticator
+
+should the sequence numbers be XORed?
+
+fix pre-authentication with pa-afs3-salt
+
+OTP?
+
+** lib/roken
+
+** lib/sl
diff --git a/crypto/heimdal/acconfig.h b/crypto/heimdal/acconfig.h
new file mode 100644
index 000000000000..c94b3637bb40
--- /dev/null
+++ b/crypto/heimdal/acconfig.h
@@ -0,0 +1,96 @@
+@BOTTOM@
+
+#undef BINDIR
+#undef LIBDIR
+#undef LIBEXECDIR
+#undef SBINDIR
+
+#undef HAVE_INT8_T
+#undef HAVE_INT16_T
+#undef HAVE_INT32_T
+#undef HAVE_INT64_T
+#undef HAVE_U_INT8_T
+#undef HAVE_U_INT16_T
+#undef HAVE_U_INT32_T
+#undef HAVE_U_INT64_T
+
+#if defined(HAVE_FOUR_VALUED_KRB_PUT_INT) || !defined(KRB4)
+#define KRB_PUT_INT(F, T, L, S) krb_put_int((F), (T), (L), (S))
+#else
+#define KRB_PUT_INT(F, T, L, S) krb_put_int((F), (T), (S))
+#endif
+
+#ifdef BROKEN_REALLOC
+#define realloc(X, Y) isoc_realloc((X), (Y))
+#define isoc_realloc(X, Y) ((X) ? realloc((X), (Y)) : malloc(Y))
+#endif
+
+#ifdef VOID_RETSIGTYPE
+#define SIGRETURN(x) return
+#else
+#define SIGRETURN(x) return (RETSIGTYPE)(x)
+#endif
+
+#define RCSID(msg) \
+static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg }
+
+#undef PROTOTYPES
+
+/* Maximum values on all known systems */
+#define MaxHostNameLen (64+4)
+#define MaxPathLen (1024+4)
+
+#if defined(HAVE_SGTTY_H) && defined(__NeXT__)
+#define SGTTY
+#endif
+
+/*
+ * Define NDBM if you are using the 4.3 ndbm library (which is part of
+ * libc). If not defined, 4.2 dbm will be assumed.
+ */
+#if defined(HAVE_DBM_FIRSTKEY)
+#define NDBM
+#endif
+
+/* telnet stuff ----------------------------------------------- */
+
+#if defined(ENCRYPTION) && !defined(AUTHENTICATION)
+#define AUTHENTICATION 1
+#endif
+
+/* Set this to the default system lead string for telnetd
+ * can contain %-escapes: %s=sysname, %m=machine, %r=os-release
+ * %v=os-version, %t=tty, %h=hostname, %d=date and time
+ */
+#undef USE_IM
+
+/* Used with login -p */
+#undef LOGIN_ARGS
+
+/* set this to a sensible login */
+#ifndef LOGIN_PATH
+#define LOGIN_PATH BINDIR "/login"
+#endif
+
+/* random defines */
+
+/*
+ * Defining this enables lots of useful (and used) extensions on
+ * glibc-based systems such as Linux
+ */
+
+#define _GNU_SOURCE
+
+/*
+ * this assumes that KRB_C_BIGENDIAN is used.
+ * if we can find out endianess at compile-time, do so,
+ * otherwise WORDS_BIGENDIAN should already have been defined
+ */
+
+#if ENDIANESS_IN_SYS_PARAM_H
+# include <sys/types.h>
+# include <sys/param.h>
+# if BYTE_ORDER == BIG_ENDIAN
+# define WORDS_BIGENDIAN 1
+# endif
+#endif
diff --git a/crypto/heimdal/acinclude.m4 b/crypto/heimdal/acinclude.m4
new file mode 100644
index 000000000000..ff8704275cfb
--- /dev/null
+++ b/crypto/heimdal/acinclude.m4
@@ -0,0 +1,9 @@
+dnl $Id: acinclude.m4,v 1.15 1998/05/23 14:54:53 joda Exp $
+dnl
+dnl Only put things that for some reason can't live in the `cf'
+dnl directory in this file.
+dnl
+
+dnl $xId: misc.m4,v 1.1 1997/12/14 15:59:04 joda Exp $
+dnl
+define(upcase,`echo $1 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`)dnl
diff --git a/crypto/heimdal/aclocal.m4 b/crypto/heimdal/aclocal.m4
new file mode 100644
index 000000000000..9d1c0a175ed7
--- /dev/null
+++ b/crypto/heimdal/aclocal.m4
@@ -0,0 +1,1615 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+dnl $Id: acinclude.m4,v 1.15 1998/05/23 14:54:53 joda Exp $
+dnl
+dnl Only put things that for some reason can't live in the `cf'
+dnl directory in this file.
+dnl
+
+dnl $xId: misc.m4,v 1.1 1997/12/14 15:59:04 joda Exp $
+dnl
+define(upcase,`echo $1 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`)dnl
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+
+dnl AM_PROG_LEX
+dnl Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT
+AC_DEFUN(AM_PROG_LEX,
+[missing_dir=ifelse([$1],,`cd $ac_aux_dir && pwd`,$1)
+AC_CHECK_PROGS(LEX, flex lex, "$missing_dir/missing flex")
+AC_PROG_LEX
+AC_DECL_YYTEXT])
+
+dnl $Id: krb-prog-ln-s.m4,v 1.1 1997/12/14 15:59:01 joda Exp $
+dnl
+dnl
+dnl Better test for ln -s, ln or cp
+dnl
+
+AC_DEFUN(AC_KRB_PROG_LN_S,
+[AC_MSG_CHECKING(for ln -s or something else)
+AC_CACHE_VAL(ac_cv_prog_LN_S,
+[rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ touch conftestdata1
+ if ln conftestdata1 conftestdata2; then
+ rm -f conftestdata*
+ ac_cv_prog_LN_S=ln
+ else
+ ac_cv_prog_LN_S=cp
+ fi
+fi])dnl
+LN_S="$ac_cv_prog_LN_S"
+AC_MSG_RESULT($ac_cv_prog_LN_S)
+AC_SUBST(LN_S)dnl
+])
+
+
+dnl $Id: mips-abi.m4,v 1.4 1998/05/16 20:44:15 joda Exp $
+dnl
+dnl
+dnl Check for MIPS/IRIX ABI flags. Sets $abi and $abilibdirext to some
+dnl value.
+
+AC_DEFUN(AC_MIPS_ABI, [
+AC_ARG_WITH(mips_abi,
+[ --with-mips-abi=abi ABI to use for IRIX (32, n32, or 64)])
+
+case "$host_os" in
+irix*)
+with_mips_abi="${with_mips_abi:-yes}"
+if test -n "$GCC"; then
+
+# GCC < 2.8 only supports the O32 ABI. GCC >= 2.8 has a flag to select
+# which ABI to use, but only supports (as of 2.8.1) the N32 and 64 ABIs.
+#
+# Default to N32, but if GCC doesn't grok -mabi=n32, we assume an old
+# GCC and revert back to O32. The same goes if O32 is asked for - old
+# GCCs doesn't like the -mabi option, and new GCCs can't output O32.
+#
+# Don't you just love *all* the different SGI ABIs?
+
+case "${with_mips_abi}" in
+ 32|o32) abi='-mabi=32'; abilibdirext='' ;;
+ n32|yes) abi='-mabi=n32'; abilibdirext='32' ;;
+ 64) abi='-mabi=64'; abilibdirext='64' ;;
+ no) abi=''; abilibdirext='';;
+ *) AC_ERROR("Invalid ABI specified") ;;
+esac
+if test -n "$abi" ; then
+ac_foo=krb_cv_gcc_`echo $abi | tr =- __`
+dnl
+dnl can't use AC_CACHE_CHECK here, since it doesn't quote CACHE-ID to
+dnl AC_MSG_RESULT
+dnl
+AC_MSG_CHECKING([if $CC supports the $abi option])
+AC_CACHE_VAL($ac_foo, [
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $abi"
+AC_TRY_COMPILE(,int x;, eval $ac_foo=yes, eval $ac_foo=no)
+CFLAGS="$save_CFLAGS"
+])
+ac_res=`eval echo \\\$$ac_foo`
+AC_MSG_RESULT($ac_res)
+if test $ac_res = no; then
+# Try to figure out why that failed...
+case $abi in
+ -mabi=32)
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mabi=n32"
+ AC_TRY_COMPILE(,int x;, ac_res=yes, ac_res=no)
+ CLAGS="$save_CFLAGS"
+ if test $ac_res = yes; then
+ # New GCC
+ AC_ERROR([$CC does not support the $with_mips_abi ABI])
+ fi
+ # Old GCC
+ abi=''
+ abilibdirext=''
+ ;;
+ -mabi=n32|-mabi=64)
+ if test $with_mips_abi = yes; then
+ # Old GCC, default to O32
+ abi=''
+ abilibdirext=''
+ else
+ # Some broken GCC
+ AC_ERROR([$CC does not support the $with_mips_abi ABI])
+ fi
+ ;;
+esac
+fi #if test $ac_res = no; then
+fi #if test -n "$abi" ; then
+else
+case "${with_mips_abi}" in
+ 32|o32) abi='-32'; abilibdirext='' ;;
+ n32|yes) abi='-n32'; abilibdirext='32' ;;
+ 64) abi='-64'; abilibdirext='64' ;;
+ no) abi=''; abilibdirext='';;
+ *) AC_ERROR("Invalid ABI specified") ;;
+esac
+fi #if test -n "$GCC"; then
+;;
+esac
+])
+
+dnl
+dnl $Id: c-attribute.m4,v 1.2 1999/03/01 09:52:23 joda Exp $
+dnl
+
+dnl
+dnl Test for __attribute__
+dnl
+
+AC_DEFUN(AC_C___ATTRIBUTE__, [
+AC_MSG_CHECKING(for __attribute__)
+AC_CACHE_VAL(ac_cv___attribute__, [
+AC_TRY_COMPILE([
+#include <stdlib.h>
+],
+[
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+ exit(1);
+}
+],
+ac_cv___attribute__=yes,
+ac_cv___attribute__=no)])
+if test "$ac_cv___attribute__" = "yes"; then
+ AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
+fi
+AC_MSG_RESULT($ac_cv___attribute__)
+])
+
+
+
+# serial 25 AM_PROG_LIBTOOL
+AC_DEFUN(AM_PROG_LIBTOOL,
+[AC_REQUIRE([AM_ENABLE_SHARED])dnl
+AC_REQUIRE([AM_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AM_PROG_LD])dnl
+AC_REQUIRE([AM_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+# Always use our own libtool.
+LIBTOOL='$(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags=
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ CFLAGS="$CFLAGS -belf"
+ ;;
+esac
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+# AM_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AM_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AM_ENABLE_SHARED,
+[define([AM_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AM_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AM_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AM_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AM_DISABLE_SHARED,
+[AM_ENABLE_SHARED(no)])
+
+# AM_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AM_DISABLE_STATIC,
+[AM_ENABLE_STATIC(no)])
+
+# AM_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AM_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AM_ENABLE_STATIC,
+[define([AM_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AM_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AM_ENABLE_STATIC_DEFAULT)dnl
+])
+
+
+# AM_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AM_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ /* | [A-Za-z]:\\*)
+changequote([,])dnl
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AM_PROG_LD_GNU
+])
+
+AC_DEFUN(AM_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AM_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AM_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ else
+ ac_cv_path_NM="$ac_dir/nm"
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+dnl $Id: wflags.m4,v 1.3 1999/03/11 12:11:41 joda Exp $
+dnl
+dnl set WFLAGS
+
+AC_DEFUN(AC_WFLAGS,[
+WFLAGS_NOUNUSED=""
+WFLAGS_NOIMPLICITINT=""
+if test -z "$WFLAGS" -a "$GCC" = "yes"; then
+ # -Wno-implicit-int for broken X11 headers
+ # leave these out for now:
+ # -Wcast-align doesn't work well on alpha osf/1
+ # -Wmissing-prototypes -Wpointer-arith -Wbad-function-cast
+ # -Wmissing-declarations -Wnested-externs
+ WFLAGS="ifelse($#, 0,-Wall, $1)"
+ WFLAGS_NOUNUSED="-Wno-unused"
+ WFLAGS_NOIMPLICITINT="-Wno-implicit-int"
+fi
+AC_SUBST(WFLAGS)dnl
+AC_SUBST(WFLAGS_NOUNUSED)dnl
+AC_SUBST(WFLAGS_NOIMPLICITINT)dnl
+])
+
+dnl $Id: test-package.m4,v 1.7 1999/04/19 13:33:05 assar Exp $
+dnl
+dnl AC_TEST_PACKAGE_NEW(package,headers,libraries,extra libs,default locations)
+
+AC_DEFUN(AC_TEST_PACKAGE,[AC_TEST_PACKAGE_NEW($1,[#include <$2>],$4,,$5)])
+
+AC_DEFUN(AC_TEST_PACKAGE_NEW,[
+AC_ARG_WITH($1,
+[ --with-$1=dir use $1 in dir])
+AC_ARG_WITH($1-lib,
+[ --with-$1-lib=dir use $1 libraries in dir],
+[if test "$withval" = "yes" -o "$withval" = "no"; then
+ AC_MSG_ERROR([No argument for --with-$1-lib])
+elif test "X$with_$1" = "X"; then
+ with_$1=yes
+fi])
+AC_ARG_WITH($1-include,
+[ --with-$1-include=dir use $1 headers in dir],
+[if test "$withval" = "yes" -o "$withval" = "no"; then
+ AC_MSG_ERROR([No argument for --with-$1-include])
+elif test "X$with_$1" = "X"; then
+ with_$1=yes
+fi])
+
+AC_MSG_CHECKING(for $1)
+
+case "$with_$1" in
+yes) ;;
+no) ;;
+"") ;;
+*) if test "$with_$1_include" = ""; then
+ with_$1_include="$with_$1/include"
+ fi
+ if test "$with_$1_lib" = ""; then
+ with_$1_lib="$with_$1/lib$abilibdirext"
+ fi
+ ;;
+esac
+header_dirs=
+lib_dirs=
+d='$5'
+for i in $d; do
+ header_dirs="$header_dirs $i/include"
+ lib_dirs="$lib_dirs $i/lib$abilibdirext"
+done
+
+case "$with_$1_include" in
+yes) ;;
+no) ;;
+*) header_dirs="$with_$1_include $header_dirs";;
+esac
+case "$with_$1_lib" in
+yes) ;;
+no) ;;
+*) lib_dirs="$with_$1_lib $lib_dirs";;
+esac
+
+save_CFLAGS="$CFLAGS"
+save_LIBS="$LIBS"
+ires= lres=
+for i in $header_dirs; do
+ CFLAGS="-I$i $save_CFLAGS"
+ AC_TRY_COMPILE([$2],,ires=$i;break)
+done
+for i in $lib_dirs; do
+ LIBS="-L$i $3 $4 $save_LIBS"
+ AC_TRY_LINK([$2],,lres=$i;break)
+done
+CFLAGS="$save_CFLAGS"
+LIBS="$save_LIBS"
+
+if test "$ires" -a "$lres" -a "$with_$1" != "no"; then
+ $1_includedir="$ires"
+ $1_libdir="$lres"
+ INCLUDE_$1="-I$$1_includedir"
+ LIB_$1="-L$$1_libdir $3"
+ AC_DEFINE_UNQUOTED(upcase($1),1,[Define if you have the $1 package.])
+ with_$1=yes
+ AC_MSG_RESULT([headers $ires, libraries $lres])
+else
+ INCLUDE_$1=
+ LIB_$1=
+ with_$1=no
+ AC_MSG_RESULT($with_$1)
+fi
+AC_SUBST(INCLUDE_$1)
+AC_SUBST(LIB_$1)
+])
+
+dnl $Id: find-func.m4,v 1.1 1997/12/14 15:58:58 joda Exp $
+dnl
+dnl AC_FIND_FUNC(func, libraries, includes, arguments)
+AC_DEFUN(AC_FIND_FUNC, [
+AC_FIND_FUNC_NO_LIBS([$1], [$2], [$3], [$4])
+if test -n "$LIB_$1"; then
+ LIBS="$LIB_$1 $LIBS"
+fi
+])
+
+dnl $Id: find-func-no-libs.m4,v 1.5 1999/10/30 21:08:18 assar Exp $
+dnl
+dnl
+dnl Look for function in any of the specified libraries
+dnl
+
+dnl AC_FIND_FUNC_NO_LIBS(func, libraries, includes, arguments, extra libs, extra args)
+AC_DEFUN(AC_FIND_FUNC_NO_LIBS, [
+AC_FIND_FUNC_NO_LIBS2([$1], ["" $2], [$3], [$4], [$5], [$6])])
+
+dnl $Id: find-func-no-libs2.m4,v 1.3 1999/10/30 21:09:53 assar Exp $
+dnl
+dnl
+dnl Look for function in any of the specified libraries
+dnl
+
+dnl AC_FIND_FUNC_NO_LIBS2(func, libraries, includes, arguments, extra libs, extra args)
+AC_DEFUN(AC_FIND_FUNC_NO_LIBS2, [
+
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(ac_cv_funclib_$1,
+[
+if eval "test \"\$ac_cv_func_$1\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in $2; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS="$6 $ac_lib $5 $ac_save_LIBS"
+ AC_TRY_LINK([$3],[$1($4)],eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break)
+ done
+ eval "ac_cv_funclib_$1=\${ac_cv_funclib_$1-no}"
+ LIBS="$ac_save_LIBS"
+fi
+])
+
+eval "ac_res=\$ac_cv_funclib_$1"
+
+dnl autoheader tricks *sigh*
+: << END
+@@@funcs="$funcs $1"@@@
+@@@libs="$libs $2"@@@
+END
+
+# $1
+eval "ac_tr_func=HAVE_[]upcase($1)"
+eval "ac_tr_lib=HAVE_LIB[]upcase($ac_res | sed -e 's/-l//')"
+eval "LIB_$1=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_$1=yes"
+ eval "LIB_$1="
+ AC_DEFINE_UNQUOTED($ac_tr_func)
+ AC_MSG_RESULT([yes])
+ ;;
+ no)
+ eval "ac_cv_func_$1=no"
+ eval "LIB_$1="
+ AC_MSG_RESULT([no])
+ ;;
+ *)
+ eval "ac_cv_func_$1=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ AC_DEFINE_UNQUOTED($ac_tr_func)
+ AC_DEFINE_UNQUOTED($ac_tr_lib)
+ AC_MSG_RESULT([yes, in $ac_res])
+ ;;
+esac
+AC_SUBST(LIB_$1)
+])
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
+dnl $Id: osfc2.m4,v 1.2 1999/03/27 17:28:16 joda Exp $
+dnl
+dnl enable OSF C2 stuff
+
+AC_DEFUN(AC_CHECK_OSFC2,[
+AC_ARG_ENABLE(osfc2,
+[ --enable-osfc2 enable some OSF C2 support])
+LIB_security=
+if test "$enable_osfc2" = yes; then
+ AC_DEFINE(HAVE_OSFC2, 1, [Define to enable basic OSF C2 support.])
+ LIB_security=-lsecurity
+fi
+AC_SUBST(LIB_security)
+])
+
+dnl $Id: check-man.m4,v 1.2 1999/03/21 14:30:50 joda Exp $
+dnl check how to format manual pages
+dnl
+
+AC_DEFUN(AC_CHECK_MAN,
+[AC_PATH_PROG(NROFF, nroff)
+AC_PATH_PROG(GROFF, groff)
+AC_CACHE_CHECK(how to format man pages,ac_cv_sys_man_format,
+[cat > conftest.1 << END
+.Dd January 1, 1970
+.Dt CONFTEST 1
+.Sh NAME
+.Nm conftest
+.Nd
+foobar
+END
+
+if test "$NROFF" ; then
+ for i in "-mdoc" "-mandoc"; do
+ if "$NROFF" $i conftest.1 2> /dev/null | \
+ grep Jan > /dev/null 2>&1 ; then
+ ac_cv_sys_man_format="$NROFF $i"
+ break
+ fi
+ done
+fi
+if test "$ac_cv_sys_man_format" = "" -a "$GROFF" ; then
+ for i in "-mdoc" "-mandoc"; do
+ if "$GROFF" -Tascii $i conftest.1 2> /dev/null | \
+ grep Jan > /dev/null 2>&1 ; then
+ ac_cv_sys_man_format="$GROFF -Tascii $i"
+ break
+ fi
+ done
+fi
+if test "$ac_cv_sys_man_format"; then
+ ac_cv_sys_man_format="$ac_cv_sys_man_format \[$]< > \[$]@"
+fi
+])
+if test "$ac_cv_sys_man_format"; then
+ CATMAN="$ac_cv_sys_man_format"
+ AC_SUBST(CATMAN)
+fi
+AM_CONDITIONAL(CATMAN, test "$CATMAN")
+AC_CACHE_CHECK(extension of pre-formatted manual pages,ac_cv_sys_catman_ext,
+[if grep _suffix /etc/man.conf > /dev/null 2>&1; then
+ ac_cv_sys_catman_ext=0
+else
+ ac_cv_sys_catman_ext=number
+fi
+])
+if test "$ac_cv_sys_catman_ext" = number; then
+ CATMANEXT='$$ext'
+else
+ CATMANEXT=0
+fi
+AC_SUBST(CATMANEXT)
+
+])
+dnl
+dnl $Id: krb-bigendian.m4,v 1.5 2000/01/08 10:34:44 assar Exp $
+dnl
+
+dnl check if this computer is little or big-endian
+dnl if we can figure it out at compile-time then don't define the cpp symbol
+dnl otherwise test for it and define it. also allow options for overriding
+dnl it when cross-compiling
+
+AC_DEFUN(KRB_C_BIGENDIAN, [
+AC_ARG_ENABLE(bigendian,
+[ --enable-bigendian the target is big endian],
+krb_cv_c_bigendian=yes)
+AC_ARG_ENABLE(littleendian,
+[ --enable-littleendian the target is little endian],
+krb_cv_c_bigendian=no)
+AC_CACHE_CHECK(whether byte order is known at compile time,
+krb_cv_c_bigendian_compile,
+[AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/param.h>],[
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif], krb_cv_c_bigendian_compile=yes, krb_cv_c_bigendian_compile=no)])
+if test "$krb_cv_c_bigendian_compile" = "no"; then
+ AC_CACHE_CHECK(whether byte ordering is bigendian, krb_cv_c_bigendian,[
+ if test "$krb_cv_c_bigendian" = ""; then
+ krb_cv_c_bigendian=unknown
+ fi
+ AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/param.h>],[
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif], krb_cv_c_bigendian=yes, krb_cv_c_bigendian=no)
+ if test "$krb_cv_c_bigendian" = "unknown"; then
+ AC_TRY_RUN([main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+ }], krb_cv_c_bigendian=no, krb_cv_c_bigendian=yes,
+ AC_MSG_ERROR([specify either --enable-bigendian or --enable-littleendian]))
+ fi
+ ])
+ if test "$krb_cv_c_bigendian" = "yes"; then
+ AC_DEFINE(WORDS_BIGENDIAN, 1, [define if target is big endian])dnl
+ fi
+fi
+if test "$krb_cv_c_bigendian_compile" = "yes"; then
+ AC_DEFINE(ENDIANESS_IN_SYS_PARAM_H, 1, [define if sys/param.h defines the endiness])dnl
+fi
+])
+
+dnl
+dnl See if there is any X11 present
+dnl
+dnl $Id: check-x.m4,v 1.2 1999/11/05 04:25:23 assar Exp $
+
+AC_DEFUN(KRB_CHECK_X,[
+AC_PATH_XTRA
+
+# try to figure out if we need any additional ld flags, like -R
+# and yes, the autoconf X test is utterly broken
+if test "$no_x" != yes; then
+ AC_CACHE_CHECK(for special X linker flags,krb_cv_sys_x_libs_rpath,[
+ ac_save_libs="$LIBS"
+ ac_save_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS $X_CFLAGS"
+ krb_cv_sys_x_libs_rpath=""
+ krb_cv_sys_x_libs=""
+ for rflag in "" "-R" "-R " "-rpath "; do
+ if test "$rflag" = ""; then
+ foo="$X_LIBS"
+ else
+ foo=""
+ for flag in $X_LIBS; do
+ case $flag in
+ -L*)
+ foo="$foo $flag `echo $flag | sed \"s/-L/$rflag/\"`"
+ ;;
+ *)
+ foo="$foo $flag"
+ ;;
+ esac
+ done
+ fi
+ LIBS="$ac_save_libs $foo $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+ AC_TRY_RUN([
+ #include <X11/Xlib.h>
+ foo()
+ {
+ XOpenDisplay(NULL);
+ }
+ main()
+ {
+ return 0;
+ }
+ ], krb_cv_sys_x_libs_rpath="$rflag"; krb_cv_sys_x_libs="$foo"; break,:)
+ done
+ LIBS="$ac_save_libs"
+ CFLAGS="$ac_save_cflags"
+ ])
+ X_LIBS="$krb_cv_sys_x_libs"
+fi
+])
+
+dnl $Id: check-xau.m4,v 1.3 1999/05/14 01:17:06 assar Exp $
+dnl
+dnl check for Xau{Read,Write}Auth and XauFileName
+dnl
+AC_DEFUN(AC_CHECK_XAU,[
+save_CFLAGS="$CFLAGS"
+CFLAGS="$X_CFLAGS $CFLAGS"
+save_LIBS="$LIBS"
+dnl LIBS="$X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS $LIBS"
+LIBS="$X_PRE_LIBS $X_EXTRA_LIBS $LIBS"
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $X_LIBS"
+
+
+AC_FIND_FUNC_NO_LIBS(XauWriteAuth, X11 Xau)
+ac_xxx="$LIBS"
+LIBS="$LIB_XauWriteAuth $LIBS"
+AC_FIND_FUNC_NO_LIBS(XauReadAuth, X11 Xau)
+LIBS="$LIB_XauReadAauth $LIBS"
+AC_FIND_FUNC_NO_LIBS(XauFileName, X11 Xau)
+LIBS="$ac_xxx"
+
+case "$ac_cv_funclib_XauWriteAuth" in
+yes) ;;
+no) ;;
+*) if test "$ac_cv_funclib_XauReadAuth" = yes; then
+ if test "$ac_cv_funclib_XauFileName" = yes; then
+ LIB_XauReadAuth="$LIB_XauWriteAuth"
+ else
+ LIB_XauReadAuth="$LIB_XauWriteAuth $LIB_XauFileName"
+ fi
+ else
+ if test "$ac_cv_funclib_XauFileName" = yes; then
+ LIB_XauReadAuth="$LIB_XauReadAuth $LIB_XauWriteAuth"
+ else
+ LIB_XauReadAuth="$LIB_XauReadAuth $LIB_XauWriteAuth $LIB_XauFileName"
+ fi
+ fi
+ ;;
+esac
+
+if test "$AUTOMAKE" != ""; then
+ AM_CONDITIONAL(NEED_WRITEAUTH, test "$ac_cv_func_XauWriteAuth" != "yes")
+else
+ AC_SUBST(NEED_WRITEAUTH_TRUE)
+ AC_SUBST(NEED_WRITEAUTH_FALSE)
+ if test "$ac_cv_func_XauWriteAuth" != "yes"; then
+ NEED_WRITEAUTH_TRUE=
+ NEED_WRITEAUTH_FALSE='#'
+ else
+ NEED_WRITEAUTH_TRUE='#'
+ NEED_WRITEAUTH_FALSE=
+ fi
+fi
+CFLAGS=$save_CFLAGS
+LIBS=$save_LIBS
+LDFLAGS=$save_LDFLAGS
+])
+
+dnl $Id: check-type-extra.m4,v 1.2 1999/03/01 09:52:23 joda Exp $
+dnl
+dnl ac_check_type + extra headers
+
+dnl AC_CHECK_TYPE_EXTRA(TYPE, DEFAULT, HEADERS)
+AC_DEFUN(AC_CHECK_TYPE_EXTRA,
+[AC_REQUIRE([AC_HEADER_STDC])dnl
+AC_MSG_CHECKING(for $1)
+AC_CACHE_VAL(ac_cv_type_$1,
+[AC_EGREP_CPP(dnl
+changequote(<<,>>)dnl
+<<$1[^a-zA-Z_0-9]>>dnl
+changequote([,]), [#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+$3], ac_cv_type_$1=yes, ac_cv_type_$1=no)])dnl
+AC_MSG_RESULT($ac_cv_type_$1)
+if test $ac_cv_type_$1 = no; then
+ AC_DEFINE($1, $2, [Define this to what the type $1 should be.])
+fi
+])
+
+dnl
+dnl $Id: check-netinet-ip-and-tcp.m4,v 1.2 1999/05/14 13:15:40 assar Exp $
+dnl
+
+dnl extra magic check for netinet/{ip.h,tcp.h} because on irix 6.5.3
+dnl you have to include standards.h before including these files
+
+AC_DEFUN(CHECK_NETINET_IP_AND_TCP,
+[
+AC_CHECK_HEADERS(standards.h)
+for i in netinet/ip.h netinet/tcp.h; do
+
+cv=`echo "$i" | sed 'y%./+-%__p_%'`
+
+AC_MSG_CHECKING([for $i])
+AC_CACHE_VAL([ac_cv_header_$cv],
+[AC_TRY_CPP([\
+#ifdef HAVE_STANDARDS_H
+#include <standards.h>
+#endif
+#include <$i>
+],
+eval "ac_cv_header_$cv=yes",
+eval "ac_cv_header_$cv=no")])
+AC_MSG_RESULT(`eval echo \\$ac_cv_header_$cv`)
+changequote(, )dnl
+if test `eval echo \\$ac_cv_header_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo $i | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+changequote([, ])dnl
+ AC_DEFINE_UNQUOTED($ac_tr_hdr, 1)
+fi
+done
+dnl autoheader tricks *sigh*
+: << END
+@@@headers="$headers netinet/ip.h netinet/tcp.h"@@@
+END
+
+])
+
+dnl $Id: krb-ipv6.m4,v 1.8 2000/01/01 11:44:45 assar Exp $
+dnl
+dnl test for IPv6
+dnl
+AC_DEFUN(AC_KRB_IPV6, [
+AC_ARG_WITH(ipv6,
+[ --without-ipv6 do not enable IPv6 support],[
+if test "$withval" = "no"; then
+ ac_cv_lib_ipv6=no
+fi])
+AC_CACHE_VAL(ac_cv_lib_ipv6,
+[dnl check for different v6 implementations (by itojun)
+v6type=unknown
+v6lib=none
+
+AC_MSG_CHECKING([ipv6 stack type])
+for i in v6d toshiba kame inria zeta linux; do
+ case $i in
+ v6d)
+ AC_EGREP_CPP(yes, [dnl
+#include </usr/local/v6/include/sys/types.h>
+#ifdef __V6D__
+yes
+#endif],
+ [v6type=$i; v6lib=v6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-I/usr/local/v6/include $CFLAGS"])
+ ;;
+ toshiba)
+ AC_EGREP_CPP(yes, [dnl
+#include <sys/param.h>
+#ifdef _TOSHIBA_INET6
+yes
+#endif],
+ [v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ kame)
+ AC_EGREP_CPP(yes, [dnl
+#include <netinet/in.h>
+#ifdef __KAME__
+yes
+#endif],
+ [v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ inria)
+ AC_EGREP_CPP(yes, [dnl
+#include <netinet/in.h>
+#ifdef IPV6_INRIA_VERSION
+yes
+#endif],
+ [v6type=$i; CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ zeta)
+ AC_EGREP_CPP(yes, [dnl
+#include <sys/param.h>
+#ifdef _ZETA_MINAMI_INET6
+yes
+#endif],
+ [v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ linux)
+ if test -d /usr/inet6; then
+ v6type=$i
+ v6lib=inet6
+ v6libdir=/usr/inet6
+ CFLAGS="-DINET6 $CFLAGS"
+ fi
+ ;;
+ esac
+ if test "$v6type" != "unknown"; then
+ break
+ fi
+done
+AC_MSG_RESULT($v6type)
+
+if test "$v6lib" != "none"; then
+ for dir in $v6libdir /usr/local/v6/lib /usr/local/lib; do
+ if test -d $dir -a -f $dir/lib$v6lib.a; then
+ LIBS="-L$dir -l$v6lib $LIBS"
+ break
+ fi
+ done
+fi
+AC_TRY_LINK([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+],
+[
+ struct sockaddr_in6 sin6;
+ int s;
+
+ s = socket(AF_INET6, SOCK_DGRAM, 0);
+
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = htons(17);
+ sin6.sin6_addr = in6addr_any;
+ bind(s, (struct sockaddr *)&sin6, sizeof(sin6));
+],
+ac_cv_lib_ipv6=yes,
+ac_cv_lib_ipv6=no)])
+AC_MSG_CHECKING(for IPv6)
+AC_MSG_RESULT($ac_cv_lib_ipv6)
+if test "$ac_cv_lib_ipv6" = yes; then
+ AC_DEFINE(HAVE_IPV6, 1, [Define if you have IPv6.])
+fi
+])
+
+dnl $Id: broken-snprintf.m4,v 1.3 1999/03/01 09:52:22 joda Exp $
+dnl
+AC_DEFUN(AC_BROKEN_SNPRINTF, [
+AC_CACHE_CHECK(for working snprintf,ac_cv_func_snprintf_working,
+ac_cv_func_snprintf_working=yes
+AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+int main()
+{
+changequote(`,')dnl
+ char foo[3];
+changequote([,])dnl
+ snprintf(foo, 2, "12");
+ return strcmp(foo, "1");
+}],:,ac_cv_func_snprintf_working=no,:))
+
+if test "$ac_cv_func_snprintf_working" = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_SNPRINTF, 1, [define if you have a working snprintf])
+fi
+if test "$ac_cv_func_snprintf_working" = yes; then
+AC_NEED_PROTO([#include <stdio.h>],snprintf)
+fi
+])
+
+AC_DEFUN(AC_BROKEN_VSNPRINTF,[
+AC_CACHE_CHECK(for working vsnprintf,ac_cv_func_vsnprintf_working,
+ac_cv_func_vsnprintf_working=yes
+AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+int foo(int num, ...)
+{
+changequote(`,')dnl
+ char bar[3];
+changequote([,])dnl
+ va_list arg;
+ va_start(arg, num);
+ vsnprintf(bar, 2, "%s", arg);
+ va_end(arg);
+ return strcmp(bar, "1");
+}
+
+
+int main()
+{
+ return foo(0, "12");
+}],:,ac_cv_func_vsnprintf_working=no,:))
+
+if test "$ac_cv_func_vsnprintf_working" = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_VSNPRINTF, 1, [define if you have a working vsnprintf])
+fi
+if test "$ac_cv_func_vsnprintf_working" = yes; then
+AC_NEED_PROTO([#include <stdio.h>],vsnprintf)
+fi
+])
+
+dnl $Id: need-proto.m4,v 1.2 1999/03/01 09:52:24 joda Exp $
+dnl
+dnl
+dnl Check if we need the prototype for a function
+dnl
+
+dnl AC_NEED_PROTO(includes, function)
+
+AC_DEFUN(AC_NEED_PROTO, [
+if test "$ac_cv_func_$2+set" != set -o "$ac_cv_func_$2" = yes; then
+AC_CACHE_CHECK([if $2 needs a prototype], ac_cv_func_$2_noproto,
+AC_TRY_COMPILE([$1],
+[struct foo { int foo; } xx;
+extern int $2 (struct foo*);
+$2(&xx);
+],
+eval "ac_cv_func_$2_noproto=yes",
+eval "ac_cv_func_$2_noproto=no"))
+define([foo], [NEED_]translit($2, [a-z], [A-Z])[_PROTO])
+if test "$ac_cv_func_$2_noproto" = yes; then
+ AC_DEFINE(foo, 1, [define if the system is missing a prototype for $2()])
+fi
+undefine([foo])
+fi
+])
+
+dnl $Id: broken-glob.m4,v 1.2 1999/03/01 09:52:15 joda Exp $
+dnl
+dnl check for glob(3)
+dnl
+AC_DEFUN(AC_BROKEN_GLOB,[
+AC_CACHE_CHECK(for working glob, ac_cv_func_glob_working,
+ac_cv_func_glob_working=yes
+AC_TRY_LINK([
+#include <stdio.h>
+#include <glob.h>],[
+glob(NULL, GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE, NULL, NULL);
+],:,ac_cv_func_glob_working=no,:))
+
+if test "$ac_cv_func_glob_working" = yes; then
+ AC_DEFINE(HAVE_GLOB, 1, [define if you have a glob() that groks
+ GLOB_BRACE, GLOB_NOCHECK, GLOB_QUOTE, and GLOB_TILDE])
+fi
+if test "$ac_cv_func_glob_working" = yes; then
+AC_NEED_PROTO([#include <stdio.h>
+#include <glob.h>],glob)
+fi
+])
+
+dnl
+dnl $Id: krb-func-getlogin.m4,v 1.1 1999/07/13 17:45:30 assar Exp $
+dnl
+dnl test for POSIX (broken) getlogin
+dnl
+
+
+AC_DEFUN(AC_FUNC_GETLOGIN, [
+AC_CHECK_FUNCS(getlogin setlogin)
+if test "$ac_cv_func_getlogin" = yes; then
+AC_CACHE_CHECK(if getlogin is posix, ac_cv_func_getlogin_posix, [
+if test "$ac_cv_func_getlogin" = yes -a "$ac_cv_func_setlogin" = yes; then
+ ac_cv_func_getlogin_posix=no
+else
+ ac_cv_func_getlogin_posix=yes
+fi
+])
+if test "$ac_cv_func_getlogin_posix" = yes; then
+ AC_DEFINE(POSIX_GETLOGIN, 1, [Define if getlogin has POSIX flavour (and not BSD).])
+fi
+fi
+])
+
+dnl
+dnl $Id: capabilities.m4,v 1.2 1999/09/01 11:02:26 joda Exp $
+dnl
+
+dnl
+dnl Test SGI capabilities
+dnl
+
+AC_DEFUN(KRB_CAPABILITIES,[
+
+AC_CHECK_HEADERS(capability.h sys/capability.h)
+
+AC_CHECK_FUNCS(sgi_getcapabilitybyname cap_set_proc)
+])
+
+dnl $Id: check-getpwnam_r-posix.m4,v 1.2 1999/03/23 16:47:31 joda Exp $
+dnl
+dnl check for getpwnam_r, and if it's posix or not
+
+AC_DEFUN(AC_CHECK_GETPWNAM_R_POSIX,[
+AC_FIND_FUNC_NO_LIBS(getpwnam_r,c_r)
+if test "$ac_cv_func_getpwnam_r" = yes; then
+ AC_CACHE_CHECK(if getpwnam_r is posix,ac_cv_func_getpwnam_r_posix,
+ ac_libs="$LIBS"
+ LIBS="$LIBS $LIB_getpwnam_r"
+ AC_TRY_RUN([
+#include <pwd.h>
+int main()
+{
+ struct passwd pw, *pwd;
+ return getpwnam_r("", &pw, NULL, 0, &pwd) < 0;
+}
+],ac_cv_func_getpwnam_r_posix=yes,ac_cv_func_getpwnam_r_posix=no,:)
+LIBS="$ac_libs")
+if test "$ac_cv_func_getpwnam_r_posix" = yes; then
+ AC_DEFINE(POSIX_GETPWNAM_R, 1, [Define if getpwnam_r has POSIX flavour.])
+fi
+fi
+])
+dnl $Id: find-if-not-broken.m4,v 1.2 1998/03/16 22:16:27 joda Exp $
+dnl
+dnl
+dnl Mix between AC_FIND_FUNC and AC_BROKEN
+dnl
+
+AC_DEFUN(AC_FIND_IF_NOT_BROKEN,
+[AC_FIND_FUNC([$1], [$2], [$3], [$4])
+if eval "test \"$ac_cv_func_$1\" != yes"; then
+LIBOBJS[]="$LIBOBJS $1.o"
+fi
+AC_SUBST(LIBOBJS)dnl
+])
+
+dnl $Id: broken.m4,v 1.3 1998/03/16 22:16:19 joda Exp $
+dnl
+dnl
+dnl Same as AC _REPLACE_FUNCS, just define HAVE_func if found in normal
+dnl libraries
+
+AC_DEFUN(AC_BROKEN,
+[for ac_func in $1
+do
+AC_CHECK_FUNC($ac_func, [
+ac_tr_func=HAVE_[]upcase($ac_func)
+AC_DEFINE_UNQUOTED($ac_tr_func)],[LIBOBJS[]="$LIBOBJS ${ac_func}.o"])
+dnl autoheader tricks *sigh*
+: << END
+@@@funcs="$funcs $1"@@@
+END
+done
+AC_SUBST(LIBOBJS)dnl
+])
+
+dnl $Id: proto-compat.m4,v 1.3 1999/03/01 13:03:48 joda Exp $
+dnl
+dnl
+dnl Check if the prototype of a function is compatible with another one
+dnl
+
+dnl AC_PROTO_COMPAT(includes, function, prototype)
+
+AC_DEFUN(AC_PROTO_COMPAT, [
+AC_CACHE_CHECK([if $2 is compatible with system prototype],
+ac_cv_func_$2_proto_compat,
+AC_TRY_COMPILE([$1],
+[$3;],
+eval "ac_cv_func_$2_proto_compat=yes",
+eval "ac_cv_func_$2_proto_compat=no"))
+define([foo], translit($2, [a-z], [A-Z])[_PROTO_COMPATIBLE])
+if test "$ac_cv_func_$2_proto_compat" = yes; then
+ AC_DEFINE(foo, 1, [define if prototype of $2 is compatible with
+ $3])
+fi
+undefine([foo])
+])
+dnl $Id: check-var.m4,v 1.2 1999/03/01 09:52:23 joda Exp $
+dnl
+dnl AC_CHECK_VAR(includes, variable)
+AC_DEFUN(AC_CHECK_VAR, [
+AC_MSG_CHECKING(for $2)
+AC_CACHE_VAL(ac_cv_var_$2, [
+AC_TRY_LINK([extern int $2;
+int foo() { return $2; }],
+ [foo()],
+ ac_cv_var_$2=yes, ac_cv_var_$2=no)
+])
+define([foo], [HAVE_]translit($2, [a-z], [A-Z]))
+
+AC_MSG_RESULT(`eval echo \\$ac_cv_var_$2`)
+if test `eval echo \\$ac_cv_var_$2` = yes; then
+ AC_DEFINE_UNQUOTED(foo, 1, [define if you have $2])
+ AC_CHECK_DECLARATION([$1],[$2])
+fi
+undefine([foo])
+])
+
+dnl $Id: check-declaration.m4,v 1.3 1999/03/01 13:03:08 joda Exp $
+dnl
+dnl
+dnl Check if we need the declaration of a variable
+dnl
+
+dnl AC_HAVE_DECLARATION(includes, variable)
+AC_DEFUN(AC_CHECK_DECLARATION, [
+AC_MSG_CHECKING([if $2 is properly declared])
+AC_CACHE_VAL(ac_cv_var_$2_declaration, [
+AC_TRY_COMPILE([$1
+extern struct { int foo; } $2;],
+[$2.foo = 1;],
+eval "ac_cv_var_$2_declaration=no",
+eval "ac_cv_var_$2_declaration=yes")
+])
+
+define(foo, [HAVE_]translit($2, [a-z], [A-Z])[_DECLARATION])
+
+AC_MSG_RESULT($ac_cv_var_$2_declaration)
+if eval "test \"\$ac_cv_var_$2_declaration\" = yes"; then
+ AC_DEFINE(foo, 1, [define if your system declares $2])
+fi
+undefine([foo])
+])
+
+dnl $Id: have-struct-field.m4,v 1.6 1999/07/29 01:44:32 assar Exp $
+dnl
+dnl check for fields in a structure
+dnl
+dnl AC_HAVE_STRUCT_FIELD(struct, field, headers)
+
+AC_DEFUN(AC_HAVE_STRUCT_FIELD, [
+define(cache_val, translit(ac_cv_type_$1_$2, [A-Z ], [a-z_]))
+AC_CACHE_CHECK([for $2 in $1], cache_val,[
+AC_TRY_COMPILE([$3],[$1 x; x.$2;],
+cache_val=yes,
+cache_val=no)])
+if test "$cache_val" = yes; then
+ define(foo, translit(HAVE_$1_$2, [a-z ], [A-Z_]))
+ AC_DEFINE(foo, 1, [Define if $1 has field $2.])
+ undefine([foo])
+fi
+undefine([cache_val])
+])
+
+dnl $Id: have-type.m4,v 1.5 1999/12/31 03:10:22 assar Exp $
+dnl
+dnl check for existance of a type
+
+dnl AC_HAVE_TYPE(TYPE,INCLUDES)
+AC_DEFUN(AC_HAVE_TYPE, [
+AC_REQUIRE([AC_HEADER_STDC])
+cv=`echo "$1" | sed 'y%./+- %__p__%'`
+AC_MSG_CHECKING(for $1)
+AC_CACHE_VAL([ac_cv_type_$cv],
+AC_TRY_COMPILE(
+[#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+$2],
+[$1 foo;],
+eval "ac_cv_type_$cv=yes",
+eval "ac_cv_type_$cv=no"))dnl
+AC_MSG_RESULT(`eval echo \\$ac_cv_type_$cv`)
+if test `eval echo \\$ac_cv_type_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
+dnl autoheader tricks *sigh*
+define(foo,translit($1, [ ], [_]))
+: << END
+@@@funcs="$funcs foo"@@@
+END
+undefine([foo])
+ AC_DEFINE_UNQUOTED($ac_tr_hdr, 1)
+fi
+])
+
+dnl $Id: krb-struct-winsize.m4,v 1.2 1999/03/01 09:52:23 joda Exp $
+dnl
+dnl
+dnl Search for struct winsize
+dnl
+
+AC_DEFUN(AC_KRB_STRUCT_WINSIZE, [
+AC_MSG_CHECKING(for struct winsize)
+AC_CACHE_VAL(ac_cv_struct_winsize, [
+ac_cv_struct_winsize=no
+for i in sys/termios.h sys/ioctl.h; do
+AC_EGREP_HEADER(
+changequote(, )dnl
+struct[ ]*winsize,dnl
+changequote([,])dnl
+$i, ac_cv_struct_winsize=yes; break)dnl
+done
+])
+if test "$ac_cv_struct_winsize" = "yes"; then
+ AC_DEFINE(HAVE_STRUCT_WINSIZE, 1, [define if struct winsize is declared in sys/termios.h])
+fi
+AC_MSG_RESULT($ac_cv_struct_winsize)
+AC_EGREP_HEADER(ws_xpixel, termios.h,
+ AC_DEFINE(HAVE_WS_XPIXEL, 1, [define if struct winsize has ws_xpixel]))
+AC_EGREP_HEADER(ws_ypixel, termios.h,
+ AC_DEFINE(HAVE_WS_YPIXEL, 1, [define if struct winsize has ws_ypixel]))
+])
+
+dnl $Id: krb-struct-spwd.m4,v 1.3 1999/07/13 21:04:11 assar Exp $
+dnl
+dnl Test for `struct spwd'
+
+AC_DEFUN(AC_KRB_STRUCT_SPWD, [
+AC_MSG_CHECKING(for struct spwd)
+AC_CACHE_VAL(ac_cv_struct_spwd, [
+AC_TRY_COMPILE(
+[#include <pwd.h>
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif],
+[struct spwd foo;],
+ac_cv_struct_spwd=yes,
+ac_cv_struct_spwd=no)
+])
+AC_MSG_RESULT($ac_cv_struct_spwd)
+
+if test "$ac_cv_struct_spwd" = "yes"; then
+ AC_DEFINE(HAVE_STRUCT_SPWD, 1, [define if you have struct spwd])
+fi
+])
+
+dnl $Id: grok-type.m4,v 1.4 1999/11/29 11:16:48 joda Exp $
+dnl
+AC_DEFUN(AC_GROK_TYPE, [
+AC_CACHE_VAL(ac_cv_type_$1,
+AC_TRY_COMPILE([
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#ifdef HAVE_BIND_BITYPES_H
+#include <bind/bitypes.h>
+#endif
+#ifdef HAVE_NETINET_IN6_MACHTYPES_H
+#include <netinet/in6_machtypes.h>
+#endif
+],
+$i x;
+,
+eval ac_cv_type_$1=yes,
+eval ac_cv_type_$1=no))])
+
+AC_DEFUN(AC_GROK_TYPES, [
+for i in $1; do
+ AC_MSG_CHECKING(for $i)
+ AC_GROK_TYPE($i)
+ eval ac_res=\$ac_cv_type_$i
+ if test "$ac_res" = yes; then
+ type=HAVE_[]upcase($i)
+ AC_DEFINE_UNQUOTED($type)
+ fi
+ AC_MSG_RESULT($ac_res)
+done
+])
+
+dnl $Id: auth-modules.m4,v 1.1 1999/03/21 13:48:00 joda Exp $
+dnl
+dnl Figure what authentication modules should be built
+
+AC_DEFUN(AC_AUTH_MODULES,[
+AC_MSG_CHECKING(which authentication modules should be built)
+
+LIB_AUTH_SUBDIRS=
+
+if test "$ac_cv_header_siad_h" = yes; then
+ LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS sia"
+fi
+
+if test "$ac_cv_header_security_pam_modules_h" = yes -a "$enable_shared" = yes; then
+ LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS pam"
+fi
+
+case "${host}" in
+changequote(,)dnl
+*-*-irix[56]*) LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS afskauthlib" ;;
+changequote([,])dnl
+esac
+
+AC_MSG_RESULT($LIB_AUTH_SUBDIRS)
+
+AC_SUBST(LIB_AUTH_SUBDIRS)dnl
+])
+
diff --git a/crypto/heimdal/admin/Makefile.am b/crypto/heimdal/admin/Makefile.am
new file mode 100644
index 000000000000..2b9d5b9c94f1
--- /dev/null
+++ b/crypto/heimdal/admin/Makefile.am
@@ -0,0 +1,29 @@
+# $Id: Makefile.am,v 1.30 2000/01/06 08:02:37 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_readline)
+
+man_MANS = ktutil.8
+
+sbin_PROGRAMS = ktutil
+
+ktutil_SOURCES = add.c \
+ change.c \
+ copy.c \
+ get.c \
+ ktutil.c \
+ list.c \
+ purge.c \
+ remove.c \
+ srvconvert.c \
+ srvcreate.c
+
+LDADD = \
+ $(top_builddir)/lib/kadm5/libkadm5clnt.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(top_builddir)/lib/sl/libsl.la \
+ $(LIB_readline) \
+ $(LIB_roken)
diff --git a/crypto/heimdal/admin/Makefile.in b/crypto/heimdal/admin/Makefile.in
new file mode 100644
index 000000000000..52665a55ff52
--- /dev/null
+++ b/crypto/heimdal/admin/Makefile.in
@@ -0,0 +1,680 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.30 2000/01/06 08:02:37 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_readline)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+man_MANS = ktutil.8
+
+sbin_PROGRAMS = ktutil
+
+ktutil_SOURCES = add.c change.c copy.c get.c ktutil.c list.c purge.c remove.c srvconvert.c srvcreate.c
+
+
+LDADD = $(top_builddir)/lib/kadm5/libkadm5clnt.la $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(top_builddir)/lib/sl/libsl.la $(LIB_readline) $(LIB_roken)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/config.h
+CONFIG_CLEAN_FILES =
+sbin_PROGRAMS = ktutil$(EXEEXT)
+PROGRAMS = $(sbin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ktutil_OBJECTS = add.$(OBJEXT) change.$(OBJEXT) copy.$(OBJEXT) \
+get.$(OBJEXT) ktutil.$(OBJEXT) list.$(OBJEXT) purge.$(OBJEXT) \
+remove.$(OBJEXT) srvconvert.$(OBJEXT) srvcreate.$(OBJEXT)
+ktutil_LDADD = $(LDADD)
+ktutil_DEPENDENCIES = $(top_builddir)/lib/kadm5/libkadm5clnt.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la $(top_builddir)/lib/sl/libsl.la
+ktutil_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man8dir = $(mandir)/man8
+MANS = $(man_MANS)
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(ktutil_SOURCES)
+OBJECTS = $(ktutil_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign admin/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-sbinPROGRAMS:
+
+clean-sbinPROGRAMS:
+ -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
+
+distclean-sbinPROGRAMS:
+
+maintainer-clean-sbinPROGRAMS:
+
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(sbindir)
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+ktutil$(EXEEXT): $(ktutil_OBJECTS) $(ktutil_DEPENDENCIES)
+ @rm -f ktutil$(EXEEXT)
+ $(LINK) $(ktutil_LDFLAGS) $(ktutil_OBJECTS) $(ktutil_LDADD) $(LIBS)
+
+install-man8:
+ $(mkinstalldirs) $(DESTDIR)$(man8dir)
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
+ done
+
+uninstall-man8:
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man8dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man8
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man8
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = admin
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-sbinPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-man install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-sbinPROGRAMS uninstall-man
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(MANS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-sbinPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-sbinPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-sbinPROGRAMS distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-sbinPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS \
+clean-sbinPROGRAMS maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \
+install-sbinPROGRAMS mostlyclean-compile distclean-compile \
+clean-compile maintainer-clean-compile mostlyclean-libtool \
+distclean-libtool clean-libtool maintainer-clean-libtool install-man8 \
+uninstall-man8 install-man uninstall-man tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/admin/add.c b/crypto/heimdal/admin/add.c
new file mode 100644
index 000000000000..954b5f814c26
--- /dev/null
+++ b/crypto/heimdal/admin/add.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ktutil_locl.h"
+
+RCSID("$Id: add.c,v 1.1 2000/01/02 04:41:00 assar Exp $");
+
+int
+kt_add(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_keytab_entry entry;
+ char buf[128];
+ char *principal_string = NULL;
+ int kvno = -1;
+ char *enctype_string = NULL;
+ krb5_enctype enctype;
+ char *password_string = NULL;
+ int salt_flag = 1;
+ int random_flag = 0;
+ int help_flag = 0;
+ struct getargs args[] = {
+ { "principal", 'p', arg_string, NULL, "principal of key", "principal"},
+ { "kvno", 'V', arg_integer, NULL, "key version of key" },
+ { "enctype", 'e', arg_string, NULL, "encryption type of key" },
+ { "password", 'w', arg_string, NULL, "password for key"},
+ { "salt", 's', arg_negative_flag, NULL, "no salt" },
+ { "random", 'r', arg_flag, NULL, "generate random key" },
+ { "help", 'h', arg_flag, NULL }
+ };
+ int num_args = sizeof(args) / sizeof(args[0]);
+ int optind = 0;
+ int i = 0;
+ args[i++].value = &principal_string;
+ args[i++].value = &kvno;
+ args[i++].value = &enctype_string;
+ args[i++].value = &password_string;
+ args[i++].value = &salt_flag;
+ args[i++].value = &random_flag;
+ args[i++].value = &help_flag;
+
+ if(getarg(args, num_args, argc, argv, &optind)) {
+ arg_printusage(args, num_args, "ktutil add", "");
+ return 0;
+ }
+ if(help_flag) {
+ arg_printusage(args, num_args, "ktutil add", "");
+ return 0;
+ }
+ if(principal_string == NULL) {
+ printf("Principal: ");
+ if (fgets(buf, sizeof(buf), stdin) == NULL)
+ return 0;
+ buf[strcspn(buf, "\r\n")] = '\0';
+ principal_string = buf;
+ }
+ ret = krb5_parse_name(context, principal_string, &entry.principal);
+ if(ret) {
+ krb5_warn(context, ret, "%s", principal_string);
+ return 0;
+ }
+ if(enctype_string == NULL) {
+ printf("Encryption type: ");
+ if (fgets(buf, sizeof(buf), stdin) == NULL) {
+ krb5_free_principal (context, entry.principal);
+ return 0;
+ }
+ buf[strcspn(buf, "\r\n")] = '\0';
+ enctype_string = buf;
+ }
+ ret = krb5_string_to_enctype(context, enctype_string, &enctype);
+ if(ret) {
+ int t;
+ if(sscanf(enctype_string, "%d", &t) == 1)
+ enctype = t;
+ else {
+ krb5_warn(context, ret, "%s", enctype_string);
+ krb5_free_principal(context, entry.principal);
+ return 0;
+ }
+ }
+ if(kvno == -1) {
+ printf("Key version: ");
+ if (fgets(buf, sizeof(buf), stdin) == NULL) {
+ krb5_free_principal (context, entry.principal);
+ return 0;
+ }
+ buf[strcspn(buf, "\r\n")] = '\0';
+ kvno = atoi(buf);
+ }
+ if(password_string == NULL && random_flag == 0) {
+ if(des_read_pw_string(buf, sizeof(buf), "Password: ", 1)) {
+ krb5_free_principal (context, entry.principal);
+ return 0;
+ }
+ password_string = buf;
+ }
+ if(password_string) {
+ if (!salt_flag) {
+ krb5_salt salt;
+ krb5_data pw;
+
+ salt.salttype = KRB5_PW_SALT;
+ salt.saltvalue.data = NULL;
+ salt.saltvalue.length = 0;
+ pw.data = (void*)password_string;
+ pw.length = strlen(password_string);
+ krb5_string_to_key_data_salt(context, enctype, pw, salt,
+ &entry.keyblock);
+ } else {
+ krb5_string_to_key(context, enctype, password_string,
+ entry.principal, &entry.keyblock);
+ }
+ memset (password_string, 0, strlen(password_string));
+ } else {
+ krb5_generate_random_keyblock(context, enctype, &entry.keyblock);
+ }
+ entry.vno = kvno;
+ entry.timestamp = time (NULL);
+ ret = krb5_kt_add_entry(context, keytab, &entry);
+ if(ret)
+ krb5_warn(context, ret, "add");
+ krb5_kt_free_entry(context, &entry);
+ return 0;
+}
diff --git a/crypto/heimdal/admin/change.c b/crypto/heimdal/admin/change.c
new file mode 100644
index 000000000000..3de4f86ead3e
--- /dev/null
+++ b/crypto/heimdal/admin/change.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ktutil_locl.h"
+
+RCSID("$Id: change.c,v 1.1 2000/01/02 04:41:00 assar Exp $");
+
+static void
+change_entry (krb5_context context, krb5_keytab_entry *entry,
+ const char *realm, const char *admin_server, int server_port)
+{
+ krb5_error_code ret;
+ kadm5_config_params conf;
+ void *kadm_handle;
+ char *client_name;
+ krb5_keyblock *keys;
+ int num_keys;
+ int i;
+
+ ret = krb5_unparse_name (context, entry->principal, &client_name);
+ if (ret) {
+ krb5_warn (context, ret, "kadm5_c_init_with_skey_ctx");
+ return;
+ }
+
+ memset (&conf, 0, sizeof(conf));
+
+ if(realm)
+ conf.realm = (char *)realm;
+ else
+ conf.realm = *krb5_princ_realm (context, entry->principal);
+ conf.mask |= KADM5_CONFIG_REALM;
+
+ if (admin_server) {
+ conf.admin_server = (char *)admin_server;
+ conf.mask |= KADM5_CONFIG_ADMIN_SERVER;
+ }
+
+ if (server_port) {
+ conf.kadmind_port = htons(server_port);
+ conf.mask |= KADM5_CONFIG_KADMIND_PORT;
+ }
+
+ ret = kadm5_init_with_skey_ctx (context,
+ client_name,
+ keytab_string,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm_handle);
+ free (client_name);
+ if (ret) {
+ krb5_warn (context, ret, "kadm5_c_init_with_skey_ctx");
+ return;
+ }
+ ret = kadm5_randkey_principal (kadm_handle, entry->principal,
+ &keys, &num_keys);
+ kadm5_destroy (kadm_handle);
+ if (ret) {
+ krb5_warn(context, ret, "kadm5_randkey_principal");
+ return;
+ }
+ for (i = 0; i < num_keys; ++i) {
+ krb5_keytab_entry new_entry;
+
+ new_entry = *entry;
+ new_entry.timestamp = time (NULL);
+ ++new_entry.vno;
+ new_entry.keyblock = keys[i];
+
+ ret = krb5_kt_add_entry (context, keytab, &new_entry);
+ if (ret)
+ krb5_warn (context, ret, "krb5_kt_add_entry");
+ krb5_free_keyblock_contents (context, &keys[i]);
+ }
+}
+
+/*
+ * loop over all the entries in the keytab (or those given) and change
+ * their keys, writing the new keys
+ */
+
+int
+kt_change (int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_kt_cursor cursor;
+ krb5_keytab_entry entry;
+ char *realm = NULL;
+ char *admin_server = NULL;
+ int server_port = 0;
+ int help_flag = 0;
+ int optind = 0;
+ int j, max;
+ krb5_principal *princs;
+
+ struct getargs args[] = {
+ { "realm", 'r', arg_string, NULL,
+ "realm to use", "realm"
+ },
+ { "admin-server", 'a', arg_string, NULL,
+ "server to contact", "host"
+ },
+ { "server-port", 's', arg_integer, NULL,
+ "port to contact", "port number"
+ },
+ { "help", 'h', arg_flag, NULL }
+ };
+
+ args[0].value = &realm;
+ args[1].value = &admin_server;
+ args[2].value = &server_port;
+ args[3].value = &help_flag;
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)
+ || help_flag) {
+ arg_printusage(args, sizeof(args) / sizeof(args[0]),
+ "ktutil change", "principal...");
+ return 0;
+ }
+
+ j = 0;
+ max = 10;
+ princs = malloc (max * sizeof(*princs));
+ if (princs == NULL) {
+ krb5_warnx (context, "malloc: out of memory");
+ return 1;
+ }
+
+ ret = krb5_kt_start_seq_get(context, keytab, &cursor);
+ if(ret){
+ krb5_warn(context, ret, "krb5_kt_start_seq_get");
+ return 1;
+ }
+
+ while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
+ int i;
+ int done = 0;
+
+ for (i = 0; i < j; ++i)
+ if (krb5_principal_compare (context, princs[i],
+ entry.principal))
+ break;
+ if (i < j)
+ continue;
+
+ if (optind == argc) {
+ change_entry (context, &entry, realm, admin_server, server_port);
+ done = 1;
+ } else {
+ for (i = optind; i < argc; ++i) {
+ krb5_principal princ;
+
+ ret = krb5_parse_name (context, argv[i], &princ);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_parse_name %s", argv[i]);
+ continue;
+ }
+ if (krb5_principal_compare (context, princ, entry.principal)) {
+ change_entry (context, &entry,
+ realm, admin_server, server_port);
+ done = 1;
+ }
+ krb5_free_principal (context, princ);
+ }
+ }
+ if (done) {
+ if (j >= max) {
+ void *tmp;
+
+ max *= 2;
+ tmp = realloc (princs, max * sizeof(*princs));
+ if (tmp == NULL) {
+ krb5_kt_free_entry (context, &entry);
+ krb5_warnx (context, "realloc: out of memory");
+ break;
+ }
+ princs = tmp;
+ }
+ ret = krb5_copy_principal (context, entry.principal, &princs[j]);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_copy_principal");
+ krb5_kt_free_entry (context, &entry);
+ break;
+ }
+ ++j;
+ }
+ krb5_kt_free_entry (context, &entry);
+ }
+ while (j-- > 0)
+ krb5_free_principal (context, princs[j]);
+ free (princs);
+ ret = krb5_kt_end_seq_get(context, keytab, &cursor);
+ return 0;
+}
diff --git a/crypto/heimdal/admin/copy.c b/crypto/heimdal/admin/copy.c
new file mode 100644
index 000000000000..d8466107eae2
--- /dev/null
+++ b/crypto/heimdal/admin/copy.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ktutil_locl.h"
+
+RCSID("$Id: copy.c,v 1.1 2000/01/02 04:41:01 assar Exp $");
+
+int
+kt_copy (int argc, char **argv)
+{
+ krb5_error_code ret;
+ int help_flag = 0;
+ int optind = 0;
+ krb5_keytab src_keytab, dst_keytab;
+ krb5_kt_cursor cursor;
+ krb5_keytab_entry entry;
+
+ struct getargs args[] = {
+ { "help", 'h', arg_flag, NULL}
+ };
+
+ int num_args = sizeof(args) / sizeof(args[0]);
+ int i = 0;
+
+ args[i++].value = &help_flag;
+
+ if(getarg(args, num_args, argc, argv, &optind)) {
+ arg_printusage(args, num_args, "ktutil copy",
+ "keytab-src keytab-dest");
+ return 0;
+ }
+ if (help_flag) {
+ arg_printusage(args, num_args, "ktutil copy",
+ "keytab-src keytab-dest");
+ return 0;
+ }
+
+ argv += optind;
+ argc -= optind;
+
+ if (argc != 2) {
+ arg_printusage(args, num_args, "ktutil copy",
+ "keytab-src keytab-dest");
+ return 0;
+ }
+
+ ret = krb5_kt_resolve (context, argv[0], &src_keytab);
+ if (ret) {
+ krb5_warn (context, ret, "resolving src keytab `%s'", argv[0]);
+ return 0;
+ }
+
+ ret = krb5_kt_resolve (context, argv[1], &dst_keytab);
+ if (ret) {
+ krb5_kt_close (context, src_keytab);
+ krb5_warn (context, ret, "resolving dst keytab `%s'", argv[1]);
+ return 0;
+ }
+
+ ret = krb5_kt_start_seq_get (context, src_keytab, &cursor);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_kt_start_seq_get");
+ goto fail;
+ }
+
+ while((ret = krb5_kt_next_entry(context, src_keytab,
+ &entry, &cursor)) == 0) {
+ ret = krb5_kt_add_entry (context, dst_keytab, &entry);
+ if (verbose_flag) {
+ char *name_str;
+
+ krb5_unparse_name (context, entry.principal, &name_str);
+ printf ("copying %s\n", name_str);
+ free (name_str);
+ }
+
+ krb5_kt_free_entry (context, &entry);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_kt_add_entry");
+ break;
+ }
+ }
+ krb5_kt_end_seq_get (context, src_keytab, &cursor);
+
+fail:
+ krb5_kt_close (context, src_keytab);
+ krb5_kt_close (context, dst_keytab);
+ return 0;
+}
diff --git a/crypto/heimdal/admin/get.c b/crypto/heimdal/admin/get.c
new file mode 100644
index 000000000000..143ffa2e5765
--- /dev/null
+++ b/crypto/heimdal/admin/get.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ktutil_locl.h"
+
+RCSID("$Id: get.c,v 1.15 2000/01/02 04:41:01 assar Exp $");
+
+int
+kt_get(int argc, char **argv)
+{
+ krb5_error_code ret;
+ kadm5_config_params conf;
+ void *kadm_handle;
+ char *principal = NULL;
+ char *realm = NULL;
+ char *admin_server = NULL;
+ int server_port = 0;
+ int help_flag = 0;
+ int optind = 0;
+ int i, j;
+
+ struct getargs args[] = {
+ { "principal", 'p', arg_string, NULL,
+ "admin principal", "principal"
+ },
+ { "realm", 'r', arg_string, NULL,
+ "realm to use", "realm"
+ },
+ { "admin-server", 'a', arg_string, NULL,
+ "server to contact", "host"
+ },
+ { "server-port", 's', arg_integer, NULL,
+ "port to contact", "port number"
+ },
+ { "help", 'h', arg_flag, NULL }
+ };
+
+ args[0].value = &principal;
+ args[1].value = &realm;
+ args[2].value = &admin_server;
+ args[3].value = &server_port;
+ args[4].value = &help_flag;
+
+ memset(&conf, 0, sizeof(conf));
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)
+ || help_flag) {
+ arg_printusage(args, sizeof(args) / sizeof(args[0]),
+ "ktutil get", "principal...");
+ return 0;
+ }
+
+ if(realm) {
+ krb5_set_default_realm(context, realm); /* XXX should be fixed
+ some other way */
+ conf.realm = realm;
+ conf.mask |= KADM5_CONFIG_REALM;
+ }
+
+ if (admin_server) {
+ conf.admin_server = admin_server;
+ conf.mask |= KADM5_CONFIG_ADMIN_SERVER;
+ }
+
+ if (server_port) {
+ conf.kadmind_port = htons(server_port);
+ conf.mask |= KADM5_CONFIG_KADMIND_PORT;
+ }
+
+ ret = kadm5_init_with_password_ctx(context,
+ principal,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm_handle);
+ if(ret) {
+ krb5_warn(context, ret, "kadm5_init_with_password");
+ return 0;
+ }
+
+
+ for(i = optind; i < argc; i++){
+ krb5_principal princ_ent;
+ kadm5_principal_ent_rec princ;
+ int mask = 0;
+ krb5_keyblock *keys;
+ int n_keys;
+ int created = 0;
+ krb5_keytab_entry entry;
+
+ ret = krb5_parse_name(context, argv[i], &princ_ent);
+ memset(&princ, 0, sizeof(princ));
+ princ.principal = princ_ent;
+ mask |= KADM5_PRINCIPAL;
+ princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
+ mask |= KADM5_ATTRIBUTES;
+ princ.princ_expire_time = 0;
+ mask |= KADM5_PRINC_EXPIRE_TIME;
+
+ ret = kadm5_create_principal(kadm_handle, &princ, mask, "x");
+ if(ret == 0)
+ created++;
+ else if(ret != KADM5_DUP) {
+ krb5_free_principal(context, princ_ent);
+ continue;
+ }
+ ret = kadm5_randkey_principal(kadm_handle, princ_ent, &keys, &n_keys);
+
+ ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
+ KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES);
+ princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
+ mask = KADM5_ATTRIBUTES;
+ if(created) {
+ princ.kvno = 1;
+ mask |= KADM5_KVNO;
+ }
+ ret = kadm5_modify_principal(kadm_handle, &princ, mask);
+ for(j = 0; j < n_keys; j++) {
+ entry.principal = princ_ent;
+ entry.vno = princ.kvno;
+ entry.keyblock = keys[j];
+ entry.timestamp = time (NULL);
+ ret = krb5_kt_add_entry(context, keytab, &entry);
+ krb5_free_keyblock_contents(context, &keys[j]);
+ }
+
+ kadm5_free_principal_ent(kadm_handle, &princ);
+ krb5_free_principal(context, princ_ent);
+ }
+ kadm5_destroy(kadm_handle);
+ return 0;
+}
diff --git a/crypto/heimdal/admin/ktutil.8 b/crypto/heimdal/admin/ktutil.8
new file mode 100644
index 000000000000..b70fc933d250
--- /dev/null
+++ b/crypto/heimdal/admin/ktutil.8
@@ -0,0 +1,119 @@
+.\" $Id: ktutil.8,v 1.6 2000/01/02 05:07:50 assar Exp $
+.\"
+.Dd Aug 27, 1997
+.Dt KTUTIL 8
+.Os HEIMDAL
+.Sh NAME
+.Nm ktutil
+.Ar command
+.Nd
+handle a keytab
+.Sh SYNOPSIS
+.Nm
+.Op Fl k Ar keytab
+.Op Fl -keytab= Ns Ar keytab
+.Op Fl v
+.Op Fl -version
+.Op Fl h
+.Op Fl -help
+.Ar command
+.Sh DESCRIPTION
+.Nm
+is a program for managing keytabs.
+.Ar command
+can be one of the following:
+.Bl -tag -width Ds
+.It add Xo
+.Op Fl p Ar principal
+.Op Fl -principal= Ns Ar principal
+.Op Fl V Ar kvno
+.Op Fl -kvno= Ns Ar kvno
+.Op Fl e Ar encype
+.Op Fl -enctype= Ns Ar enctype
+.Op Fl w Ar password
+.Op Fl -password= Ns Ar password
+.Op Fl r
+.Op Fl -random
+.Op Fl s
+.Op Fl -no-salt
+.Xc
+Adds a key to the keytab. Options that are not specified will be
+prompted for.
+.It change Xo
+.Op Fl r Ar realm
+.Op Fl -realm= Ns Ar realm
+.Op Fl -a Ar host
+.Op Fl -admin-server= Ns Ar hots
+.Op Fl -s Ar port
+.Op Fl -server-port= Ns Ar port
+.Xc
+Update one or several keys to new versions. By default, use the admin
+server for the realm of an keytab entry. Otherwise it will use the
+values specified by the options.
+.Pp
+If no principals are given, all the ones in the keytab are updated.
+.It copy Xo
+.Ar keytab-src
+.Ar keytab-dest
+.Xc
+Copies all the entries from
+.Ar keytab-src
+to
+.Ar keytab-dest .
+.It get Xo
+.Op Fl p Ar admin principal
+.Op Fl -principal= Ns Ar admin principal
+.Op Fl r Ar realm
+.Op Fl -realm= Ns Ar realm
+.Op Fl a Ar admin server
+.Op Fl -admin-server= Ns Ar admin server
+.Op Fl s Ar server port
+.Op Fl -server-port= Ns Ar server port
+.Ar principal
+.Xc
+Get a key for
+.Nm principal
+and store it in a keytab.
+.It list
+List the keys stored in the keytab.
+.It remove Xo
+.Op Fl p Ar principal
+.Op Fl -principal= Ns Ar principal
+.Op Fl V kvno
+.Op Fl -kvno= Ns Ar kvno
+.Op Fl e enctype
+.Op Fl -enctype= Ns Ar enctype
+.Xc
+Removes the specified key or keys. Not specifying a
+.Ar kvno
+removes keys with any version number. Not specifying a
+.Ar enctype
+removes keys of any type.
+.It purge Xo
+.Op Fl -age= Ns Ar age
+.Xc
+Removes all old entries (for which there is a newer version) that are
+older than
+.Ar age
+seconds.
+.It srvconvert
+.It srv2keytab Xo
+.Op Fl s Ar srvtab
+.Op Fl -srvtab= Ns Ar srvtab
+.Xc
+Converts the version 4 srvtab in
+.Ar srvtab
+to a version 5 keytab and stores it in
+.Ar keytab .
+.It srvcreate
+.It key2srvtab Xo
+.Op Fl s Ar srvtab
+.Op Fl -srvtab= Ns Ar srvtab
+.Xc
+Converts the version 5 keytab in
+.Ar keytab
+to a version 4 srvtab and stores it in
+.Ar srvtab .
+.El
+.Sh SEE ALSO
+.Xr kadmin 8
diff --git a/crypto/heimdal/admin/ktutil.c b/crypto/heimdal/admin/ktutil.c
new file mode 100644
index 000000000000..4893f2d53cc6
--- /dev/null
+++ b/crypto/heimdal/admin/ktutil.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ktutil_locl.h"
+
+RCSID("$Id: ktutil.c,v 1.25 2000/01/02 05:07:34 assar Exp $");
+
+int help_flag;
+int version_flag;
+int verbose_flag;
+char *keytab_string;
+
+static int help(int argc, char **argv);
+
+static SL_cmd cmds[] = {
+ { "add", kt_add, "add",
+ "adds key to keytab" },
+ { "change", kt_change, "change [principal...]",
+ "get new key for principals (all)" },
+ { "copy", kt_copy, "copy src dst",
+ "copy one keytab to another" },
+ { "get", kt_get, "get [principal...]",
+ "create key in database and add to keytab" },
+ { "list", kt_list, "list",
+ "shows contents of a keytab" },
+ { "purge", kt_purge, "purge",
+ "remove old and superceeded entries" },
+ { "remove", kt_remove, "remove",
+ "remove key from keytab" },
+ { "srvconvert", srvconv, "srvconvert [flags]",
+ "convert v4 srvtab to keytab" },
+ { "srv2keytab" },
+ { "srvcreate", srvcreate, "srvcreate [flags]",
+ "convert keytab to v4 srvtab" },
+ { "key2srvtab" },
+ { "help", help, "help", "" },
+ { NULL, NULL, NULL, NULL }
+};
+
+static struct getargs args[] = {
+ {
+ "version",
+ 0,
+ arg_flag,
+ &version_flag,
+ NULL,
+ NULL
+ },
+ {
+ "help",
+ 'h',
+ arg_flag,
+ &help_flag,
+ NULL,
+ NULL
+ },
+ {
+ "keytab",
+ 'k',
+ arg_string,
+ &keytab_string,
+ "keytab",
+ "keytab to operate on"
+ },
+ {
+ "verbose",
+ 'v',
+ arg_flag,
+ &verbose_flag,
+ "verbose",
+ "run verbosely"
+ }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+krb5_context context;
+krb5_keytab keytab;
+
+static int
+help(int argc, char **argv)
+{
+ sl_help(cmds, argc, argv);
+ return 0;
+}
+
+static void
+usage(int status)
+{
+ arg_printusage(args, num_args, NULL, "command");
+ exit(status);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+ krb5_error_code ret;
+ set_progname(argv[0]);
+ krb5_init_context(&context);
+ if(getarg(args, num_args, argc, argv, &optind))
+ usage(1);
+ if(help_flag)
+ usage(0);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+ argc -= optind;
+ argv += optind;
+ if(argc == 0)
+ usage(1);
+ if(keytab_string) {
+ ret = krb5_kt_resolve(context, keytab_string, &keytab);
+ } else {
+ ret = krb5_kt_default(context, &keytab);
+ }
+ if(ret)
+ krb5_err(context, 1, ret, "resolving keytab");
+ ret = sl_command(cmds, argc, argv);
+ if(ret == -1)
+ krb5_warnx (context, "unrecognized command: %s", argv[0]);
+ krb5_kt_close(context, keytab);
+ return ret;
+}
diff --git a/crypto/heimdal/admin/ktutil_locl.h b/crypto/heimdal/admin/ktutil_locl.h
new file mode 100644
index 000000000000..6a45f51cb1f5
--- /dev/null
+++ b/crypto/heimdal/admin/ktutil_locl.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*
+ * $Id: ktutil_locl.h,v 1.9 2000/01/06 08:03:06 assar Exp $
+ */
+
+#ifndef __KTUTIL_LOCL_H__
+#define __KTUTIL_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <roken.h>
+
+#include <krb5.h>
+#include <kadm5/admin.h>
+#include <kadm5/kadm5_err.h>
+
+#include <sl.h>
+#include <getarg.h>
+
+extern krb5_context context;
+extern krb5_keytab keytab;
+
+extern int help_flag;
+extern int version_flag;
+extern int verbose_flag;
+extern char *keytab_string;
+
+int kt_add (int argc, char **argv);
+int kt_change (int argc, char **argv);
+int kt_copy (int argc, char **argv);
+int kt_get (int argc, char **argv);
+int kt_list(int argc, char **argv);
+int kt_purge(int argc, char **argv);
+int kt_remove(int argc, char **argv);
+int srvconv(int argc, char **argv);
+int srvcreate(int argc, char **argv);
+
+#endif /* __KTUTIL_LOCL_H__ */
diff --git a/crypto/heimdal/admin/list.c b/crypto/heimdal/admin/list.c
new file mode 100644
index 000000000000..1924a2103270
--- /dev/null
+++ b/crypto/heimdal/admin/list.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ktutil_locl.h"
+
+RCSID("$Id: list.c,v 1.1 2000/01/02 04:41:02 assar Exp $");
+
+int
+kt_list(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_kt_cursor cursor;
+ krb5_keytab_entry entry;
+
+ ret = krb5_kt_start_seq_get(context, keytab, &cursor);
+ if(ret){
+ krb5_warn(context, ret, "krb5_kt_start_seq_get");
+ return 1;
+ }
+ printf("%s", "Version");
+ printf(" ");
+ printf("%-15s", "Type");
+ printf(" ");
+ printf("%s", "Principal");
+ printf("\n");
+ while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0){
+ char *p;
+ printf(" %3d ", entry.vno);
+ printf(" ");
+ ret = krb5_enctype_to_string(context, entry.keyblock.keytype, &p);
+ if (ret != 0)
+ asprintf(&p, "unknown (%d)", entry.keyblock.keytype);
+ printf("%-15s", p);
+ free(p);
+ printf(" ");
+ krb5_unparse_name(context, entry.principal, &p);
+ printf("%s ", p);
+ free(p);
+ printf("\n");
+ if (verbose_flag) {
+ char tstamp[256];
+ struct tm *tm;
+ time_t ts = entry.timestamp;
+
+ tm = gmtime (&ts);
+ strftime (tstamp, sizeof(tstamp), "%Y-%m-%d %H:%M:%S UTC", tm);
+ printf(" Timestamp: %s\n", tstamp);
+ }
+ krb5_kt_free_entry(context, &entry);
+ }
+ ret = krb5_kt_end_seq_get(context, keytab, &cursor);
+ return 0;
+}
diff --git a/crypto/heimdal/admin/purge.c b/crypto/heimdal/admin/purge.c
new file mode 100644
index 000000000000..3e262c5fb62c
--- /dev/null
+++ b/crypto/heimdal/admin/purge.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ktutil_locl.h"
+
+RCSID("$Id: purge.c,v 1.1 2000/01/02 05:06:50 assar Exp $");
+
+/*
+ * keep track of the highest version for every principal.
+ */
+
+struct e {
+ krb5_principal principal;
+ int max_vno;
+ struct e *next;
+};
+
+static struct e *
+get_entry (krb5_principal princ, struct e *head)
+{
+ struct e *e;
+
+ for (e = head; e != NULL; e = e->next)
+ if (krb5_principal_compare (context, princ, e->principal))
+ return e;
+ return NULL;
+}
+
+static void
+add_entry (krb5_principal princ, int vno, struct e **head)
+{
+ krb5_error_code ret;
+ struct e *e;
+
+ e = get_entry (princ, *head);
+ if (e != NULL) {
+ e->max_vno = max (e->max_vno, vno);
+ return;
+ }
+ e = malloc (sizeof (*e));
+ if (e == NULL)
+ krb5_errx (context, 1, "malloc: out of memory");
+ ret = krb5_copy_principal (context, princ, &e->principal);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_copy_principal");
+ e->max_vno = vno;
+ e->next = *head;
+ *head = e;
+}
+
+static void
+delete_list (struct e *head)
+{
+ while (head != NULL) {
+ struct e *next = head->next;
+ krb5_free_principal (context, head->principal);
+ free (head);
+ head = next;
+ }
+}
+
+/*
+ * Remove all entries that have newer versions and that are older
+ * than `age'
+ */
+
+int
+kt_purge(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_kt_cursor cursor;
+ krb5_keytab_entry entry;
+ int help_flag = 0;
+ int age = 7 * 24 * 60 * 60;
+ struct getargs args[] = {
+ { "age", 0, arg_integer, NULL, "age to retire" },
+ { "help", 'h', arg_flag, NULL }
+ };
+ int num_args = sizeof(args) / sizeof(args[0]);
+ int optind = 0;
+ int i = 0;
+ struct e *head = NULL;
+ time_t judgement_day;
+
+ args[i++].value = &age;
+ args[i++].value = &help_flag;
+
+ if(getarg(args, num_args, argc, argv, &optind)) {
+ arg_printusage(args, num_args, "ktutil remove", "");
+ return 0;
+ }
+ if(help_flag) {
+ arg_printusage(args, num_args, "ktutil remove", "");
+ return 0;
+ }
+
+ ret = krb5_kt_start_seq_get(context, keytab, &cursor);
+ if(ret){
+ krb5_warn(context, ret, "krb5_kt_start_seq_get");
+ return 1;
+ }
+
+ while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
+ add_entry (entry.principal, entry.vno, &head);
+ krb5_kt_free_entry(context, &entry);
+ }
+ ret = krb5_kt_end_seq_get(context, keytab, &cursor);
+
+ judgement_day = time (NULL);
+
+ ret = krb5_kt_start_seq_get(context, keytab, &cursor);
+ if(ret){
+ krb5_warn(context, ret, "krb5_kt_start_seq_get");
+ return 1;
+ }
+
+ while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
+ struct e *e = get_entry (entry.principal, head);
+
+ if (e == NULL) {
+ krb5_warnx (context, "ignoring extra entry");
+ continue;
+ }
+
+ if (entry.vno < e->max_vno
+ && judgement_day - entry.timestamp > age) {
+ if (verbose_flag) {
+ char *name_str;
+
+ krb5_unparse_name (context, entry.principal, &name_str);
+ printf ("removing %s vno %d\n", name_str, entry.vno);
+ free (name_str);
+ }
+ ret = krb5_kt_remove_entry (context, keytab, &entry);
+ if (ret)
+ krb5_warn (context, ret, "remove");
+ }
+ krb5_kt_free_entry(context, &entry);
+ }
+ ret = krb5_kt_end_seq_get(context, keytab, &cursor);
+
+ delete_list (head);
+
+ return 0;
+}
diff --git a/crypto/heimdal/admin/remove.c b/crypto/heimdal/admin/remove.c
new file mode 100644
index 000000000000..e19de0a0a108
--- /dev/null
+++ b/crypto/heimdal/admin/remove.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ktutil_locl.h"
+
+RCSID("$Id: remove.c,v 1.1 2000/01/02 04:41:02 assar Exp $");
+
+int
+kt_remove(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_keytab_entry entry;
+ char *principal_string = NULL;
+ krb5_principal principal = NULL;
+ int kvno = 0;
+ char *keytype_string = NULL;
+ krb5_enctype enctype = 0;
+ int help_flag = 0;
+ struct getargs args[] = {
+ { "principal", 'p', arg_string, NULL, "principal to remove" },
+ { "kvno", 'V', arg_integer, NULL, "key version to remove" },
+ { "enctype", 'e', arg_string, NULL, "enctype to remove" },
+ { "help", 'h', arg_flag, NULL }
+ };
+ int num_args = sizeof(args) / sizeof(args[0]);
+ int optind = 0;
+ int i = 0;
+ args[i++].value = &principal_string;
+ args[i++].value = &kvno;
+ args[i++].value = &keytype_string;
+ args[i++].value = &help_flag;
+ if(getarg(args, num_args, argc, argv, &optind)) {
+ arg_printusage(args, num_args, "ktutil remove", "");
+ return 0;
+ }
+ if(help_flag) {
+ arg_printusage(args, num_args, "ktutil remove", "");
+ return 0;
+ }
+ if(principal_string) {
+ ret = krb5_parse_name(context, principal_string, &principal);
+ if(ret) {
+ krb5_warn(context, ret, "%s", principal_string);
+ return 0;
+ }
+ }
+ if(keytype_string) {
+ ret = krb5_string_to_enctype(context, keytype_string, &enctype);
+ if(ret) {
+ int t;
+ if(sscanf(keytype_string, "%d", &t) == 1)
+ enctype = t;
+ else {
+ krb5_warn(context, ret, "%s", keytype_string);
+ if(principal)
+ krb5_free_principal(context, principal);
+ return 0;
+ }
+ }
+ }
+ if (!principal && !enctype && !kvno) {
+ krb5_warnx(context,
+ "You must give at least one of "
+ "principal, enctype or kvno.");
+ return 0;
+ }
+ entry.principal = principal;
+ entry.keyblock.keytype = enctype;
+ entry.vno = kvno;
+ ret = krb5_kt_remove_entry(context, keytab, &entry);
+ if(ret)
+ krb5_warn(context, ret, "remove");
+ if(principal)
+ krb5_free_principal(context, principal);
+ return 0;
+}
+
diff --git a/crypto/heimdal/admin/srvconvert.c b/crypto/heimdal/admin/srvconvert.c
new file mode 100644
index 000000000000..e4a2b1104204
--- /dev/null
+++ b/crypto/heimdal/admin/srvconvert.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ktutil_locl.h"
+
+RCSID("$Id: srvconvert.c,v 1.11 2000/01/02 03:56:21 assar Exp $");
+
+/* convert a version 4 srvtab to a version 5 keytab */
+
+#ifndef KEYFILE
+#define KEYFILE "/etc/srvtab"
+#endif
+
+static char *srvtab = KEYFILE;
+static int help_flag;
+static int verbose;
+
+static struct getargs args[] = {
+ { "srvtab", 's', arg_string, &srvtab, "srvtab to convert", "file" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "verbose", 'v', arg_flag, &verbose },
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+int
+srvconv(int argc, char **argv)
+{
+ krb5_error_code ret;
+ int optind = 0;
+ int fd;
+ krb5_storage *sp;
+
+ if(getarg(args, num_args, argc, argv, &optind)){
+ arg_printusage(args, num_args, "ktutil srvconvert", "");
+ return 1;
+ }
+ if(help_flag){
+ arg_printusage(args, num_args, "ktutil srvconvert", "");
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0) {
+ arg_printusage(args, num_args, "ktutil srvconvert", "");
+ return 1;
+ }
+
+ fd = open(srvtab, O_RDONLY);
+ if(fd < 0){
+ krb5_warn(context, errno, "%s", srvtab);
+ return 1;
+ }
+ sp = krb5_storage_from_fd(fd);
+ if(sp == NULL){
+ close(fd);
+ return 1;
+ }
+ while(1){
+ char *service, *instance, *realm;
+ int8_t kvno;
+ des_cblock key;
+ krb5_keytab_entry entry;
+
+ ret = krb5_ret_stringz(sp, &service);
+ if(ret == KRB5_CC_END) {
+ ret = 0;
+ break;
+ }
+ if(ret) {
+ krb5_warn(context, ret, "reading service");
+ break;
+ }
+ ret = krb5_ret_stringz(sp, &instance);
+ if(ret) {
+ krb5_warn(context, ret, "reading instance");
+ free(service);
+ break;
+ }
+ ret = krb5_ret_stringz(sp, &realm);
+ if(ret) {
+ krb5_warn(context, ret, "reading realm");
+ free(service);
+ free(instance);
+ break;
+ }
+ ret = krb5_425_conv_principal(context, service, instance, realm,
+ &entry.principal);
+ free(service);
+ free(instance);
+ free(realm);
+ if (ret) {
+ krb5_warn(context, ret, "krb5_425_conv_principal (%s.%s@%s)",
+ service, instance, realm);
+ break;
+ }
+
+ ret = krb5_ret_int8(sp, &kvno);
+ if(ret) {
+ krb5_warn(context, ret, "reading kvno");
+ krb5_free_principal(context, entry.principal);
+ break;
+ }
+ ret = sp->fetch(sp, key, 8);
+ if(ret < 0){
+ krb5_warn(context, errno, "reading key");
+ krb5_free_principal(context, entry.principal);
+ break;
+ }
+ if(ret < 8) {
+ krb5_warn(context, errno, "end of file while reading key");
+ krb5_free_principal(context, entry.principal);
+ break;
+ }
+
+ entry.vno = kvno;
+ entry.timestamp = time (NULL);
+ entry.keyblock.keyvalue.data = key;
+ entry.keyblock.keyvalue.length = 8;
+
+ if(verbose){
+ char *p;
+ ret = krb5_unparse_name(context, entry.principal, &p);
+ if(ret){
+ krb5_warn(context, ret, "krb5_unparse_name");
+ krb5_free_principal(context, entry.principal);
+ break;
+ } else{
+ fprintf(stderr, "Storing keytab for %s\n", p);
+ free(p);
+ }
+
+ }
+ entry.keyblock.keytype = ETYPE_DES_CBC_MD5;
+ ret = krb5_kt_add_entry(context, keytab, &entry);
+ entry.keyblock.keytype = ETYPE_DES_CBC_MD4;
+ ret = krb5_kt_add_entry(context, keytab, &entry);
+ entry.keyblock.keytype = ETYPE_DES_CBC_CRC;
+ ret = krb5_kt_add_entry(context, keytab, &entry);
+ krb5_free_principal(context, entry.principal);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_kt_add_entry");
+ break;
+ }
+ }
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+}
diff --git a/crypto/heimdal/admin/srvcreate.c b/crypto/heimdal/admin/srvcreate.c
new file mode 100644
index 000000000000..bc86bc89aa3b
--- /dev/null
+++ b/crypto/heimdal/admin/srvcreate.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ktutil_locl.h"
+
+RCSID("$Id: srvcreate.c,v 1.3 1999/12/02 17:04:53 joda Exp $");
+
+/* convert a version 5 keytab to a version 4 srvtab */
+
+#ifndef KEYFILE
+#define KEYFILE "/etc/srvtab"
+#endif
+
+static char *srvtab = KEYFILE;
+static int help_flag;
+static int verbose;
+
+static struct getargs args[] = {
+ { "srvtab", 's', arg_string, &srvtab, "srvtab to create", "file" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "verbose", 'v', arg_flag, &verbose },
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+int
+srvcreate(int argc, char **argv)
+{
+ krb5_error_code ret;
+ int optind = 0;
+ int fd;
+ krb5_kt_cursor cursor;
+ krb5_keytab_entry entry;
+ char service[100], instance[100], realm[100];
+ int8_t kvno;
+
+ if(getarg(args, num_args, argc, argv, &optind)){
+ arg_printusage(args, num_args, "ktutil srvcreate", "");
+ return 1;
+ }
+ if(help_flag){
+ arg_printusage(args, num_args, "ktutil srvcreate", "");
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0) {
+ arg_printusage(args, num_args, "ktutil srvcreate", "");
+ return 1;
+ }
+
+ ret = krb5_kt_start_seq_get(context, keytab, &cursor);
+ if(ret){
+ krb5_warn(context, ret, "krb5_kt_start_seq_get");
+ return 1;
+ }
+
+ fd = open(srvtab, O_WRONLY |O_APPEND |O_CREAT, 0600);
+ if(fd < 0){
+ krb5_warn(context, errno, "%s", srvtab);
+ return 1;
+ }
+
+ while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0){
+ ret = krb5_524_conv_principal(context, entry.principal,
+ service, instance, realm);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_524_conv_principal");
+ close(fd);
+ return 1;
+ }
+ if ( (entry.keyblock.keyvalue.length == 8) &&
+ (entry.keyblock.keytype == ETYPE_DES_CBC_MD5) ) {
+ if (verbose) {
+ printf ("%s.%s@%s vno %d\n", service, instance, realm,
+ entry.vno);
+ }
+
+ write(fd, service, strlen(service)+1);
+ write(fd, instance, strlen(instance)+1);
+ write(fd, realm, strlen(realm)+1);
+ kvno = entry.vno;
+ write(fd, &kvno, sizeof(kvno));
+ write(fd, entry.keyblock. keyvalue.data, 8);
+ }
+ krb5_kt_free_entry(context, &entry);
+ }
+
+ close(fd);
+ ret = krb5_kt_end_seq_get(context, keytab, &cursor);
+ return ret;
+}
diff --git a/crypto/heimdal/appl/Makefile.am b/crypto/heimdal/appl/Makefile.am
new file mode 100644
index 000000000000..307f450afc94
--- /dev/null
+++ b/crypto/heimdal/appl/Makefile.am
@@ -0,0 +1,22 @@
+# $Id: Makefile.am,v 1.19 1999/10/17 10:51:26 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+if OTP
+dir_otp = otp
+endif
+SUBDIRS = \
+ afsutil \
+ ftp \
+ login \
+ $(dir_otp) \
+ popper \
+ push \
+ rsh \
+ su \
+ xnlock \
+ telnet \
+ test \
+ kx \
+ kf \
+ # kauth
diff --git a/crypto/heimdal/appl/Makefile.in b/crypto/heimdal/appl/Makefile.in
new file mode 100644
index 000000000000..f78cfa3d405b
--- /dev/null
+++ b/crypto/heimdal/appl/Makefile.in
@@ -0,0 +1,602 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.19 1999/10/17 10:51:26 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+@OTP_TRUE@dir_otp = otp
+SUBDIRS = afsutil ftp login $(dir_otp) popper push rsh su xnlock telnet test kx kf # kauth
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/config.h
+CONFIG_CLEAN_FILES =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+DIST_SUBDIRS = afsutil ftp login otp popper push rsh su xnlock telnet \
+test kx kf
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .et .h .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(DIST_SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-recursive
+
+install-data-am: install-data-local
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile all-local
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+
+.PHONY: install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/afsutil/ChangeLog b/crypto/heimdal/appl/afsutil/ChangeLog
new file mode 100644
index 000000000000..5cdc960eac48
--- /dev/null
+++ b/crypto/heimdal/appl/afsutil/ChangeLog
@@ -0,0 +1,23 @@
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * pagsh.c (main): use mkstemp to generate temporary file names.
+ From Miroslav Ruda <ruda@ics.muni.cz>
+
+1999-07-04 Assar Westerlund <assar@sics.se>
+
+ * afslog.c (expand_cell_name): terminate on #. From Miroslav Ruda
+ <ruda@ics.muni.cz>
+
+1999-06-27 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (bin_PROGRAMS): only include pagsh if KRB4
+
+1999-06-26 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: add pagsh
+
+ * pagsh.c: new file. contributed by Miroslav Ruda <ruda@ics.muni.cz>
+
+Sat Mar 27 12:49:43 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * afslog.c: cleanup option parsing
diff --git a/crypto/heimdal/appl/afsutil/Makefile.am b/crypto/heimdal/appl/afsutil/Makefile.am
new file mode 100644
index 000000000000..6d9475876684
--- /dev/null
+++ b/crypto/heimdal/appl/afsutil/Makefile.am
@@ -0,0 +1,21 @@
+# $Id: Makefile.am,v 1.11 1999/06/27 00:45:26 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+if KRB4
+AFSPROGS = afslog pagsh
+endif
+bin_PROGRAMS = $(AFSPROGS)
+
+afslog_SOURCES = afslog.c
+
+pagsh_SOURCES = pagsh.c
+
+LDADD = $(LIB_kafs) \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(top_builddir)/lib/des/libdes.la \
+ $(LIB_roken)
diff --git a/crypto/heimdal/appl/afsutil/Makefile.in b/crypto/heimdal/appl/afsutil/Makefile.in
new file mode 100644
index 000000000000..bf33ad108366
--- /dev/null
+++ b/crypto/heimdal/appl/afsutil/Makefile.in
@@ -0,0 +1,654 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.11 1999/06/27 00:45:26 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+@KRB4_TRUE@AFSPROGS = afslog pagsh
+bin_PROGRAMS = $(AFSPROGS)
+
+afslog_SOURCES = afslog.c
+
+pagsh_SOURCES = pagsh.c
+
+LDADD = $(LIB_kafs) $(LIB_krb4) $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la $(top_builddir)/lib/des/libdes.la $(LIB_roken)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+@KRB4_TRUE@bin_PROGRAMS = afslog$(EXEEXT) pagsh$(EXEEXT)
+@KRB4_FALSE@bin_PROGRAMS =
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+afslog_OBJECTS = afslog.$(OBJEXT)
+afslog_LDADD = $(LDADD)
+@KRB4_TRUE@afslog_DEPENDENCIES = $(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@afslog_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la
+afslog_LDFLAGS =
+pagsh_OBJECTS = pagsh.$(OBJEXT)
+pagsh_LDADD = $(LDADD)
+@KRB4_TRUE@pagsh_DEPENDENCIES = $(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@pagsh_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la
+pagsh_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(afslog_SOURCES) $(pagsh_SOURCES)
+OBJECTS = $(afslog_OBJECTS) $(pagsh_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/afsutil/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+afslog$(EXEEXT): $(afslog_OBJECTS) $(afslog_DEPENDENCIES)
+ @rm -f afslog$(EXEEXT)
+ $(LINK) $(afslog_LDFLAGS) $(afslog_OBJECTS) $(afslog_LDADD) $(LIBS)
+
+pagsh$(EXEEXT): $(pagsh_OBJECTS) $(pagsh_DEPENDENCIES)
+ @rm -f pagsh$(EXEEXT)
+ $(LINK) $(pagsh_LDFLAGS) $(pagsh_OBJECTS) $(pagsh_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/afsutil
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-compile distclean-libtool \
+ distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/afsutil/afslog.c b/crypto/heimdal/appl/afsutil/afslog.c
new file mode 100644
index 000000000000..431231f03299
--- /dev/null
+++ b/crypto/heimdal/appl/afsutil/afslog.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: afslog.c,v 1.11 1999/07/04 23:50:39 assar Exp $");
+#endif
+#include <ctype.h>
+#include <krb5.h>
+#include <kafs.h>
+#include <roken.h>
+#include <getarg.h>
+
+
+static int help_flag;
+static int version_flag;
+#if 0
+static int create_user;
+#endif
+static getarg_strings cells;
+static char *realm;
+static getarg_strings files;
+static int unlog_flag;
+static int verbose;
+
+struct getargs args[] = {
+ { "cell", 'c', arg_strings, &cells, "cell to get tokens for", "cell" },
+ { "file", 'p', arg_strings, &files, "file to get tokens for", "path" },
+ { "realm", 'k', arg_string, &realm, "realm for afs cell", "realm" },
+ { "unlog", 'u', arg_flag, &unlog_flag, "remove tokens" },
+#if 0
+ { "create-user", 0, arg_flag, &create_user, "create user if not found" },
+#endif
+ { "verbose",'v', arg_flag, &verbose },
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 'h', arg_flag, &help_flag },
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static const char *
+expand_cell_name(const char *cell)
+{
+ FILE *f;
+ static char buf[128];
+ char *p;
+
+ f = fopen(_PATH_CELLSERVDB, "r");
+ if(f == NULL)
+ return cell;
+ while (fgets (buf, sizeof(buf), f) != NULL) {
+ if(buf[0] == '>'){
+ for(p=buf; *p && !isspace((unsigned char)*p) && *p != '#'; p++)
+ ;
+ *p = '\0';
+ if(strstr(buf, cell)){
+ fclose(f);
+ return buf + 1;
+ }
+ }
+ buf[0] = 0;
+ }
+ fclose(f);
+ return cell;
+}
+
+#if 0
+static int
+createuser (char *cell)
+{
+ char cellbuf[64];
+ char name[ANAME_SZ];
+ char instance[INST_SZ];
+ char realm[REALM_SZ];
+ char cmd[1024];
+
+ if (cell == NULL) {
+ FILE *f;
+ int len;
+
+ f = fopen (_PATH_THISCELL, "r");
+ if (f == NULL)
+ err (1, "open(%s)", _PATH_THISCELL);
+ if (fgets (cellbuf, sizeof(cellbuf), f) == NULL)
+ err (1, "read cellname from %s", _PATH_THISCELL);
+ len = strlen(cellbuf);
+ if (cellbuf[len-1] == '\n')
+ cellbuf[len-1] = '\0';
+ cell = cellbuf;
+ }
+
+ if(krb_get_default_principal(name, instance, realm))
+ errx (1, "Could not even figure out who you are");
+
+ snprintf (cmd, sizeof(cmd),
+ "pts createuser %s%s%s@%s -cell %s",
+ name, *instance ? "." : "", instance, strlwr(realm),
+ cell);
+ DEBUG("Executing %s", cmd);
+ return system(cmd);
+}
+#endif
+
+static void
+usage(int ecode)
+{
+ arg_printusage(args, num_args, NULL, "[cell]... [path]...");
+ exit(ecode);
+}
+
+static int
+afslog_cell(krb5_context context, krb5_ccache id,
+ const char *cell, int expand)
+{
+ const char *c = cell;
+ if(expand){
+ c = expand_cell_name(cell);
+ if(c == NULL){
+ krb5_warnx(context, "No cell matching \"%s\" found.", cell);
+ return -1;
+ }
+ if(verbose)
+ krb5_warnx(context, "Cell \"%s\" expanded to \"%s\"", cell, c);
+ }
+ return krb5_afslog(context, id, c, realm);
+}
+
+static int
+afslog_file(krb5_context context, krb5_ccache id,
+ const char *path)
+{
+ char cell[64];
+ if(k_afs_cell_of_file(path, cell, sizeof(cell))){
+ krb5_warnx(context, "No cell found for file \"%s\".", path);
+ return -1;
+ }
+ if(verbose)
+ krb5_warnx(context, "File \"%s\" lives in cell \"%s\"", path, cell);
+ return afslog_cell(context, id, cell, 0);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+ krb5_context context;
+ krb5_ccache id;
+ int i;
+ int num;
+ int ret = 0;
+
+ set_progname(argv[0]);
+
+ if(getarg(args, num_args, argc, argv, &optind))
+ usage(1);
+ if(help_flag)
+ usage(0);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ krb5_init_context(&context);
+ if(!k_hasafs())
+ krb5_errx(context, 1,
+ "AFS doesn't seem to be present on this machine");
+
+ if(unlog_flag){
+ k_unlog();
+ exit(0);
+ }
+ krb5_cc_default(context, &id);
+ num = 0;
+ for(i = 0; i < files.num_strings; i++){
+ afslog_file(context, id, files.strings[i]);
+ num++;
+ }
+ for(i = 0; i < cells.num_strings; i++){
+ afslog_cell(context, id, cells.strings[i], 1);
+ num++;
+ }
+ for(i = optind; i < argc; i++){
+ num++;
+ if(strcmp(argv[i], ".") == 0 ||
+ strcmp(argv[i], "..") == 0 ||
+ strchr(argv[i], '/') ||
+ access(argv[i], F_OK) == 0)
+ afslog_file(context, id, argv[i]);
+ else
+ afslog_cell(context, id, argv[i], 1);
+ }
+ if(num == 0) {
+ krb5_afslog(context, id, NULL, NULL);
+ }
+
+ return ret;
+}
diff --git a/crypto/heimdal/appl/afsutil/pagsh.c b/crypto/heimdal/appl/afsutil/pagsh.c
new file mode 100644
index 000000000000..6bddb40125f0
--- /dev/null
+++ b/crypto/heimdal/appl/afsutil/pagsh.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+RCSID("$Id: pagsh.c,v 1.3 1999/12/02 17:04:55 joda Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <time.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef KRB5
+#include <krb5.h>
+#endif
+#ifdef KRB4
+#include <krb.h>
+#endif
+#include <kafs.h>
+
+#include <err.h>
+#include <roken.h>
+
+/*
+ * Run command with a new ticket file / credentials cache / token
+ */
+
+int
+main(int argc, char **argv)
+{
+ int f;
+ char tf[1024];
+ char *p;
+
+ char *path;
+ char **args;
+ int i;
+
+#ifdef KRB5
+ snprintf (tf, sizeof(tf), "%sXXXXXX", KRB5_DEFAULT_CCROOT);
+ f = mkstemp (tf + 5);
+ close (f);
+ unlink (tf + 5);
+ setenv("KRB5CCNAME", tf, 1);
+#endif
+
+#ifdef KRB4
+ snprintf (tf, sizeof(tf), "%s_XXXXXX", TKT_ROOT);
+ f = mkstemp (tf);
+ close (f);
+ unlink (tf);
+ setenv("KRBTKFILE", tf, 1);
+#endif
+
+ i = 0;
+
+ args = (char **) malloc((argc + 10)*sizeof(char *));
+ if (args == NULL)
+ errx (1, "Out of memory allocating %lu bytes",
+ (unsigned long)((argc + 10)*sizeof(char *)));
+
+ argv++;
+
+ if(*argv == NULL) {
+ path = getenv("SHELL");
+ if(path == NULL){
+ struct passwd *pw = k_getpwuid(geteuid());
+ path = strdup(pw->pw_shell);
+ }
+ } else {
+ if(strcmp(*argv, "-c") == 0) argv++;
+ path = strdup(*argv++);
+ }
+ if (path == NULL)
+ errx (1, "Out of memory copying path");
+
+ p=strrchr(path, '/');
+ if(p)
+ args[i] = strdup(p+1);
+ else
+ args[i] = strdup(path);
+
+ if (args[i++] == NULL)
+ errx (1, "Out of memory copying arguments");
+
+ while(*argv)
+ args[i++] = *argv++;
+
+ args[i++] = NULL;
+
+ if(k_hasafs())
+ k_setpag();
+
+ unsetenv("PAGPID");
+ execvp(path, args);
+ if (errno == ENOENT) {
+ char **sh_args = malloc ((i + 2) * sizeof(char *));
+ int j;
+
+ if (sh_args == NULL)
+ errx (1, "Out of memory copying sh arguments");
+ for (j = 1; j < i; ++j)
+ sh_args[j + 2] = args[j];
+ sh_args[0] = "sh";
+ sh_args[1] = "-c";
+ sh_args[2] = path;
+ execv ("/bin/sh", sh_args);
+ }
+ err (1, "execvp");
+}
diff --git a/crypto/heimdal/appl/ftp/ChangeLog b/crypto/heimdal/appl/ftp/ChangeLog
new file mode 100644
index 000000000000..1a55c38da738
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ChangeLog
@@ -0,0 +1,414 @@
+2000-01-08 Assar Westerlund <assar@sics.se>
+
+ * ftp/ftp.c (hookup): handle ai_canonname being set in any of the
+ addresses returnedby getaddrinfo. glibc apparently returns the
+ reverse lookup of every address in ai_canonname.
+ * ftp/ruserpass.c (guess_domain): dito
+
+1999-12-21 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpd.c: don't use sa_len as a parameter, it's defined on
+ Irix
+
+1999-12-21 Johan Danielsson <joda@pdc.kth.se>
+
+ * ftpd/ftpd.c (dataconn): make sure from points to actual data
+
+1999-12-16 Assar Westerlund <assar@sics.se>
+
+ * ftp/ruserpass.c (guess_domain): handle ai_canonname not being
+ set
+ * ftp/ftp.c (hookup): handle ai_canonname not being set
+
+1999-12-06 Assar Westerlund <assar@sics.se>
+
+ * ftp/krb4.c (krb4_auth): the nat-IP address might not be realm
+ bounded.
+
+1999-12-05 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpd.c (dolog): update prototype
+ * ftpd/ftpd.c (dolog): use getnameinfo_verified
+ * ftpd/ftpd.c: replace inaddr2str by getnameinfo
+
+1999-12-04 Assar Westerlund <assar@sics.se>
+
+ * ftp/ruserpass.c (guess_domain): re-write to use getaddrinfo
+ * ftp/ftp.c (hookup): re-write to use getaddrinfo
+
+1999-11-30 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpd.c (getdatasock): make sure to keep the port-number of
+ the outgoing connections. It has to be `ftp-data' or some people
+ might get upset.
+
+ * ftpd/ftpd.c (args): set correct variable when `-l' so that
+ logging actually works
+
+1999-11-29 Assar Westerlund <assar@sics.se>
+
+ * ftp/security.c (sec_login): check return value from realloc
+ (sec_end): set app_data to NULL
+
+1999-11-25 Assar Westerlund <assar@sics.se>
+
+ * ftp/krb4.c (krb4_auth): obtain the `local' address when doing
+ NAT. also turn on passive mode. From <thn@stacken.kth.se>
+
+1999-11-20 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ls.c (make_fileinfo): cast to allow for non-const
+ prototypes of readlink
+
+1999-11-12 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpd.c (args): use arg_counter for `l'
+
+1999-11-04 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ls.c (S_ISSOCK, S_ISLNK): fallback definitions for systems
+ that don't have them (such as ultrix)
+
+1999-10-29 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ls.c (make_fileinfo): cast uid's and gid's to unsigned in
+ printf, we don't know what types they might be.
+ (lstat_file): conditionalize the kafs part on KRB4
+
+ * ftpd/ftpd_locl.h: <sys/ioccom.h> is needed for kafs.h
+
+1999-10-28 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ls.c (lstat_file): don't set st_mode, it should already be
+ correct
+
+ * ftpd/ls.c: don't use warnx to print errors
+
+ * ftpd/ls.c (builtin_ls): fix typo, 'd' shouldn't imply 'f'
+
+ * ftpd/ls.c (lstat_file): new function for avoiding stating AFS
+ mount points. From Love <lha@s3.kth.se>
+ (list_files): use `lstat_file'
+
+ * ftpd/ftpd.c: some const-poisoning
+
+ * ftpd/ftpd.c (args): add `-B' as an alias for `--builtin-ls' to
+ allow for stupid inetds that only support two arguments. From
+ Love <lha@s3.kth.se>
+
+1999-10-26 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpcmd.y (help): it's unnecessary to interpret help strings
+ as printf commands
+
+ * ftpd/ftpd.c (show_issue): don't interpret contents of
+ /etc/issue* as printf commands. From Brian A May
+ <bmay@dgs.monash.edu.au>
+
+1999-10-21 Johan Danielsson <joda@pdc.kth.se>
+
+ * ftpd/kauth.c (kauth): complain if protection level isn't
+ `private'
+
+ * ftp/krb4.c (krb4_decode): syslog failure reason
+
+ * ftp/kauth.c (kauth): set private level earlier
+
+ * ftp/security.c: get_command_prot; (sec_prot): partially match
+ `command' and `data'
+
+1999-10-18 Johan Danielsson <joda@pdc.kth.se>
+
+ * ftpd/ftpd.c: change `-l' flag to use arg_collect (this makes
+ `-ll' work again)
+
+ * ftpd/ftpd.c (list_file): pass filename to ls
+
+1999-10-04 Johan Danielsson <joda@pdc.kth.se>
+
+ * ftpd/ftpcmd.y: FEAT
+
+1999-10-03 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ls.c: fall-back definitions for constans and casts for
+ printfs
+
+1999-10-03 Johan Danielsson <joda@pdc.kth.se>
+
+ * ftpd/ftpd.c (main): make this use getarg; add `list_file'
+
+ * ftpd/ftpcmd.y (LIST): call list_file
+
+ * ftpd/ls.c: add simple built-in ls
+
+ * ftp/security.c: add `sec_vfprintf2' and `sec_fprintf2' that
+ prints to the data stream
+
+ * ftp/kauth.c (kauth): make sure we're using private protection
+ level
+
+ * ftp/security.c (set_command_prot): set command protection level
+
+ * ftp/security.c: make it possible to set the command protection
+ level with `prot'
+
+1999-09-30 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpd_locl.h: add prototype for fclose to make sunos happy
+
+1999-08-19 Johan Danielsson <joda@pdc.kth.se>
+
+ * ftpd/ftpd.c (do_login): show issue-file
+ (send_data): change handling of zero-byte files
+
+1999-08-18 Assar Westerlund <assar@sics.se>
+
+ * ftp/cmds.c (getit): be more suspicious when parsing the result
+ of MDTM. Do the comparison of timestamps correctly.
+
+1999-08-13 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpd.c (send_data): avoid calling mmap with `len == 0'.
+ Some mmap:s rather dislike that (Solaris) and some munmap (Linux)
+ get grumpy later.
+
+ * ftp/ftp.c (copy_stream): avoid calling mmap with `len == 0'.
+ Some mmap:s rather dislike that (Solaris) and some munmap (Linux)
+ get grumpy later.
+
+1999-08-03 Assar Westerlund <assar@sics.se>
+
+ * ftp/ftp.c (active_mode): hide failure of EPRT by setting verbose
+
+ * ftp/gssapi.c (gss_auth): initialize application_data in bindings
+
+1999-08-02 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpcmd.y: save file names when doing commands that might
+ get aborted (and longjmp:ed out of) to avoid overwriting them also
+ remove extra closing brace
+
+1999-08-01 Johan Danielsson <joda@pdc.kth.se>
+
+ * ftpd/ftpcmd.y: change `site find' to `site locate' (to match
+ what it does, and other implementations) keep find as an alias
+
+1999-07-28 Assar Westerlund <assar@sics.se>
+
+ * common/socket.c: moved to roken
+
+ * common/socket.c: new file with generic socket functions
+
+ * ftpd/ftpd.c: make it more AF-neutral and v6-capable
+
+ * ftpd/ftpcmd.y: add EPRT and EPSV
+
+ * ftpd/extern.h: update prototypes and variables
+
+ * ftp/krb4.c: update to new types of addresses
+
+ * ftp/gssapi.c: add support for both AF_INET and AF_INET6
+ addresses
+
+ * ftp/ftp.c: make it more AF-neutral and v6-capable
+
+ * ftp/extern.h (hookup): change prototype
+
+ * common/common.h: add prototypes for functions in socket.c
+
+ * common/Makefile.am (libcommon_a_SOURCES): add socket.c
+
+ * ftp/gssapi.c (gss_auth): check return value from
+ `gss_import_name' and print error messages if it fails
+
+1999-06-15 Assar Westerlund <assar@sics.se>
+
+ * ftp/krb4.c (krb4_auth): type correctness
+
+1999-06-02 Johan Danielsson <joda@pdc.kth.se>
+
+ * ftp/ftp.c (sendrequest): lmode != rmode
+
+1999-05-21 Assar Westerlund <assar@sics.se>
+
+ * ftp/extern.h (sendrequest): update prototype
+
+ * ftp/cmds.c: update calls to sendrequest and recvrequest to send
+ "b" when appropriate
+
+ * ftp/ftp.c (sendrequest): add argument for mode to open file in.
+
+1999-05-08 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpcmd.y: rename getline -> ftpd_getline
+
+ * ftp/main.c (makeargv): fill in unused slots with NULL
+
+Thu Apr 8 15:06:40 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * ftpd/ftpd.c: remove definition of KRB_VERIFY_USER (moved to
+ config.h)
+
+Wed Apr 7 16:15:21 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * ftp/gssapi.c (gss_auth): call gss_display_status to get a sane
+ error message; return AUTH_{CONTINUE,ERROR}, where appropriate
+
+ * ftp/krb4.c: return AUTH_{CONTINUE,ERROR}, where appropriate
+
+ * ftp/security.c (sec_login): if mechanism returns AUTH_CONTINUE,
+ just continue with the next mechanism, this fixes the case of
+ having GSSAPI fail because of non-existant of expired tickets
+
+ * ftp/security.h: add AUTH_{OK,CONTINUE,ERROR}
+
+Thu Apr 1 16:59:04 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * ftpd/Makefile.am: don't run check-local
+
+ * ftp/Makefile.am: don't run check-local
+
+Mon Mar 22 22:15:18 1999 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpd.c (pass): fall-back for KRB_VERIFY_SECURE
+
+ * ftpd/ftpd.c (pass): 1 -> KRB_VERIFY_SECURE
+
+Thu Mar 18 12:07:09 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * ftpd/Makefile.am: clean ftpcmd.c
+
+ * ftpd/ftpd_locl.h: remove krb5.h (breaks in ftpcmd.y)
+
+ * ftpd/ftpd.c: move include of krb5.h here
+
+ * ftpd/Makefile.am: include Makefile.am.common
+
+ * Makefile.am: include Makefile.am.common
+
+ * ftp/Makefile.am: include Makefile.am.common
+
+ * common/Makefile.am: include Makefile.am.common
+
+Tue Mar 16 22:28:37 1999 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpd_locl.h: add krb5.h to get heimdal_version
+
+ * ftpd/ftpd.c: krb_verify_user_multiple -> krb_verify_user
+
+Thu Mar 11 14:54:59 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * ftp/Makefile.in: WFLAGS
+
+ * ftp/ruserpass.c: add some if-braces
+
+Wed Mar 10 20:02:55 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * ftpd/ftpd_locl.h: remove ifdef HAVE_FNMATCH
+
+Mon Mar 8 21:29:24 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * ftpd/ftpd.c: re-add version in greeting message
+
+Mon Mar 1 10:49:38 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * ftpd/logwtmp.c: HAVE_UT_* -> HAVE_STRUCT_UTMP*_UT_*
+
+Mon Feb 22 19:20:51 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * common/Makefile.in: remove glob
+
+Sat Feb 13 17:19:35 1999 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpd.c (match): remove #ifdef HAVE_FNMATCH. We have a
+ fnmatch implementation in roken and therefore always have it.
+
+ * ftp/ftp.c (copy_stream): initialize `werr'
+
+Wed Jan 13 23:52:57 1999 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpcmd.y: moved all check_login and check_login_no_guest to
+ the end of the rules to ensure we don't generate several
+ (independent) error messages. once again, having a yacc-grammar
+ for FTP with embedded actions doesn't strike me as the most
+ optimal way of doing it.
+
+Tue Dec 1 14:44:29 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * ftpd/Makefile.am: link with extra libs for aix
+
+Sun Nov 22 10:28:20 1998 Assar Westerlund <assar@sics.se>
+
+ * ftpd/ftpd.c (retrying): support on-the-fly decompression
+
+ * ftpd/Makefile.in (WFLAGS): set
+
+ * ftp/ruserpass.c (guess_domain): new function
+ (ruserpass): use it
+
+ * common/Makefile.in (WFLAGS): set
+
+ * Makefile.in (WFLAGS): set
+
+Sat Nov 21 23:13:03 1998 Assar Westerlund <assar@sics.se>
+
+ * ftp/security.c: some more type correctness.
+
+ * ftp/gssapi.c (gss_adat): more braces to shut up warnings
+
+Wed Nov 18 21:47:55 1998 Assar Westerlund <assar@sics.se>
+
+ * ftp/main.c (main): new option `-p' for enable passive mode.
+
+Mon Nov 2 01:57:49 1998 Assar Westerlund <assar@sics.se>
+
+ * ftp/ftp.c (getreply): remove extra `break'
+
+ * ftp/gssapi.c (gss_auth): fixo typo(copyo?)
+
+ * ftp/security.c (sec_login): fix loop and return value
+
+Tue Sep 1 16:56:42 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * ftp/cmds.c (quote1): fix % quoting bug
+
+Fri Aug 14 17:10:06 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * ftp/krb4.c: krb_put_int -> KRB_PUT_INT
+
+Tue Jun 30 18:07:15 1998 Assar Westerlund <assar@sics.se>
+
+ * ftp/security.c (auth): free `app_data'
+ (sec_end): only destroy if it was initialized
+
+Tue Jun 9 21:01:59 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * ftp/krb4.c: pass client address to krb_rd_req
+
+Sat May 16 00:02:07 1998 Assar Westerlund <assar@sics.se>
+
+ * ftpd/Makefile.am: link with DBLIB
+
+Tue May 12 14:15:32 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * ftp/gssapi.c: Save client name for userok().
+
+ * ftpd/gss_userok.c: Userok for gssapi.
+
+Fri May 1 07:15:01 1998 Assar Westerlund <assar@sics.se>
+
+ * ftp/ftp.c: unifdef -DHAVE_H_ERRNO
+
+Fri Mar 27 00:46:07 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Make compile w/o krb4.
+
+Thu Mar 26 03:49:12 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * ftp/*, ftpd/*: Changes for new framework.
+
+ * ftp/gssapi.c: GSS-API backend for the new security framework.
+
+ * ftp/krb4.c: Updated for new framework.
+
+ * ftp/security.{c,h}: New unified security framework.
diff --git a/crypto/heimdal/appl/ftp/Makefile.am b/crypto/heimdal/appl/ftp/Makefile.am
new file mode 100644
index 000000000000..f8831a308d03
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/Makefile.am
@@ -0,0 +1,5 @@
+# $Id: Makefile.am,v 1.5 1999/03/20 13:58:14 joda Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+SUBDIRS = common ftp ftpd
diff --git a/crypto/heimdal/appl/ftp/Makefile.in b/crypto/heimdal/appl/ftp/Makefile.in
new file mode 100644
index 000000000000..9c0d09d782c2
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/Makefile.in
@@ -0,0 +1,598 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.5 1999/03/20 13:58:14 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+SUBDIRS = common ftp ftpd
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .et .h .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/ftp/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/ftp
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-recursive
+
+install-data-am: install-data-local
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile all-local
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+
+.PHONY: install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/ftp/common/Makefile.am b/crypto/heimdal/appl/ftp/common/Makefile.am
new file mode 100644
index 000000000000..4fab07b9a1ae
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/common/Makefile.am
@@ -0,0 +1,12 @@
+# $Id: Makefile.am,v 1.9 1999/07/28 21:15:06 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+noinst_LIBRARIES = libcommon.a
+
+libcommon_a_SOURCES = \
+ sockbuf.c \
+ buffer.c \
+ common.h
diff --git a/crypto/heimdal/appl/ftp/common/Makefile.in b/crypto/heimdal/appl/ftp/common/Makefile.in
new file mode 100644
index 000000000000..1dc613ca05c5
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/common/Makefile.in
@@ -0,0 +1,611 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.9 1999/07/28 21:15:06 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+noinst_LIBRARIES = libcommon.a
+
+libcommon_a_SOURCES = sockbuf.c buffer.c common.h
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../../include/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libcommon_a_LIBADD =
+libcommon_a_OBJECTS = sockbuf.$(OBJEXT) buffer.$(OBJEXT)
+AR = ar
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libcommon_a_SOURCES)
+OBJECTS = $(libcommon_a_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/ftp/common/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libcommon.a: $(libcommon_a_OBJECTS) $(libcommon_a_DEPENDENCIES)
+ -rm -f libcommon.a
+ $(AR) cru libcommon.a $(libcommon_a_OBJECTS) $(libcommon_a_LIBADD)
+ $(RANLIB) libcommon.a
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/ftp/common
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LIBRARIES) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstLIBRARIES clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/ftp/common/buffer.c b/crypto/heimdal/appl/ftp/common/buffer.c
new file mode 100644
index 000000000000..0385d494a120
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/common/buffer.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "common.h"
+#include <stdio.h>
+#include <err.h>
+#include "roken.h"
+
+RCSID("$Id: buffer.c,v 1.3 1999/12/02 16:58:29 joda Exp $");
+
+/*
+ * Allocate a buffer enough to handle st->st_blksize, if
+ * there is such a field, otherwise BUFSIZ.
+ */
+
+void *
+alloc_buffer (void *oldbuf, size_t *sz, struct stat *st)
+{
+ size_t new_sz;
+
+ new_sz = BUFSIZ;
+#ifdef HAVE_ST_BLKSIZE
+ if (st)
+ new_sz = max(BUFSIZ, st->st_blksize);
+#endif
+ if(new_sz > *sz) {
+ if (oldbuf)
+ free (oldbuf);
+ oldbuf = malloc (new_sz);
+ if (oldbuf == NULL) {
+ warn ("malloc");
+ *sz = 0;
+ return NULL;
+ }
+ *sz = new_sz;
+ }
+ return oldbuf;
+}
+
diff --git a/crypto/heimdal/appl/ftp/common/common.h b/crypto/heimdal/appl/ftp/common/common.h
new file mode 100644
index 000000000000..5949b25d7bf9
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/common/common.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: common.h,v 1.12 1999/12/02 16:58:29 joda Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include "base64.h"
+
+void set_buffer_size(int, int);
+
+#include <stdlib.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+void *alloc_buffer (void *oldbuf, size_t *sz, struct stat *st);
+
+#endif /* __COMMON_H__ */
diff --git a/crypto/heimdal/appl/ftp/common/sockbuf.c b/crypto/heimdal/appl/ftp/common/sockbuf.c
new file mode 100644
index 000000000000..460cc6fbf554
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/common/sockbuf.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "common.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+RCSID("$Id: sockbuf.c,v 1.3 1999/12/02 16:58:29 joda Exp $");
+
+void
+set_buffer_size(int fd, int read)
+{
+#if defined(SO_RCVBUF) && defined(SO_SNDBUF) && defined(HAVE_SETSOCKOPT)
+ size_t size = 4194304;
+ while(size >= 131072 &&
+ setsockopt(fd, SOL_SOCKET, read ? SO_RCVBUF : SO_SNDBUF,
+ (void *)&size, sizeof(size)) < 0)
+ size /= 2;
+#endif
+}
+
+
diff --git a/crypto/heimdal/appl/ftp/ftp/Makefile.am b/crypto/heimdal/appl/ftp/ftp/Makefile.am
new file mode 100644
index 000000000000..e24025ce4494
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/Makefile.am
@@ -0,0 +1,46 @@
+# $Id: Makefile.am,v 1.13 2000/01/06 15:11:43 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += -I$(srcdir)/../common $(INCLUDE_readline) $(INCLUDE_krb4)
+
+bin_PROGRAMS = ftp
+
+CHECK_LOCAL =
+
+if KRB4
+krb4_sources = krb4.c kauth.c
+endif
+if KRB5
+krb5_sources = gssapi.c
+endif
+
+ftp_SOURCES = \
+ cmds.c \
+ cmdtab.c \
+ extern.h \
+ ftp.c \
+ ftp_locl.h \
+ ftp_var.h \
+ main.c \
+ pathnames.h \
+ ruserpass.c \
+ domacro.c \
+ globals.c \
+ security.c \
+ security.h \
+ $(krb4_sources) \
+ $(krb5_sources)
+
+EXTRA_ftp_SOURCES = krb4.c kauth.c gssapi.c
+
+man_MANS = ftp.1
+
+LDADD = \
+ ../common/libcommon.a \
+ $(LIB_gssapi) \
+ $(LIB_krb5) \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(LIB_roken) \
+ $(LIB_readline)
diff --git a/crypto/heimdal/appl/ftp/ftp/Makefile.in b/crypto/heimdal/appl/ftp/ftp/Makefile.in
new file mode 100644
index 000000000000..6f8603db4b24
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/Makefile.in
@@ -0,0 +1,702 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.13 2000/01/06 15:11:43 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include -I$(srcdir)/../common $(INCLUDE_readline) $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL =
+
+bin_PROGRAMS = ftp
+
+@KRB4_TRUE@krb4_sources = krb4.c kauth.c
+@KRB5_TRUE@krb5_sources = gssapi.c
+
+ftp_SOURCES = cmds.c cmdtab.c extern.h ftp.c ftp_locl.h ftp_var.h main.c pathnames.h ruserpass.c domacro.c globals.c security.c security.h $(krb4_sources) $(krb5_sources)
+
+
+EXTRA_ftp_SOURCES = krb4.c kauth.c gssapi.c
+
+man_MANS = ftp.1
+
+LDADD = ../common/libcommon.a $(LIB_gssapi) $(LIB_krb5) $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(LIB_roken) $(LIB_readline)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../../include/config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = ftp$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+@KRB4_TRUE@@KRB5_FALSE@ftp_OBJECTS = cmds.$(OBJEXT) cmdtab.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_FALSE@ftp.$(OBJEXT) main.$(OBJEXT) ruserpass.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_FALSE@domacro.$(OBJEXT) globals.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_FALSE@security.$(OBJEXT) krb4.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_FALSE@kauth.$(OBJEXT)
+@KRB4_FALSE@@KRB5_TRUE@ftp_OBJECTS = cmds.$(OBJEXT) cmdtab.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_TRUE@ftp.$(OBJEXT) main.$(OBJEXT) ruserpass.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_TRUE@domacro.$(OBJEXT) globals.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_TRUE@security.$(OBJEXT) gssapi.$(OBJEXT)
+@KRB4_FALSE@@KRB5_FALSE@ftp_OBJECTS = cmds.$(OBJEXT) cmdtab.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_FALSE@ftp.$(OBJEXT) main.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_FALSE@ruserpass.$(OBJEXT) domacro.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_FALSE@globals.$(OBJEXT) security.$(OBJEXT)
+@KRB4_TRUE@@KRB5_TRUE@ftp_OBJECTS = cmds.$(OBJEXT) cmdtab.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_TRUE@ftp.$(OBJEXT) main.$(OBJEXT) ruserpass.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_TRUE@domacro.$(OBJEXT) globals.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_TRUE@security.$(OBJEXT) krb4.$(OBJEXT) kauth.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_TRUE@gssapi.$(OBJEXT)
+ftp_LDADD = $(LDADD)
+@KRB5_TRUE@ftp_DEPENDENCIES = ../common/libcommon.a \
+@KRB5_TRUE@$(top_builddir)/lib/gssapi/libgssapi.la \
+@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB5_FALSE@ftp_DEPENDENCIES = ../common/libcommon.a \
+@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+ftp_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man1dir = $(mandir)/man1
+MANS = $(man_MANS)
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(ftp_SOURCES) $(EXTRA_ftp_SOURCES)
+OBJECTS = $(ftp_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/ftp/ftp/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+ftp$(EXEEXT): $(ftp_OBJECTS) $(ftp_DEPENDENCIES)
+ @rm -f ftp$(EXEEXT)
+ $(LINK) $(ftp_LDFLAGS) $(ftp_OBJECTS) $(ftp_LDADD) $(LIBS)
+
+install-man1:
+ $(mkinstalldirs) $(DESTDIR)$(man1dir)
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
+ done
+
+uninstall-man1:
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man1dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man1
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man1
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/ftp/ftp
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-man install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS uninstall-man
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(MANS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-compile distclean-libtool \
+ distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool install-man1 uninstall-man1 \
+install-man uninstall-man tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-local install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/ftp/ftp/cmds.c b/crypto/heimdal/appl/ftp/ftp/cmds.c
new file mode 100644
index 000000000000..7698313c252e
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/cmds.c
@@ -0,0 +1,2116 @@
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+/*
+ * FTP User Program -- Command Routines.
+ */
+
+#include "ftp_locl.h"
+RCSID("$Id: cmds.c,v 1.36 1999/09/16 20:37:28 assar Exp $");
+
+typedef void (*sighand)(int);
+
+jmp_buf jabort;
+char *mname;
+char *home = "/";
+
+/*
+ * `Another' gets another argument, and stores the new argc and argv.
+ * It reverts to the top level (via main.c's intr()) on EOF/error.
+ *
+ * Returns false if no new arguments have been added.
+ */
+int
+another(int *pargc, char ***pargv, char *prompt)
+{
+ int len = strlen(line), ret;
+
+ if (len >= sizeof(line) - 3) {
+ printf("sorry, arguments too long\n");
+ intr(0);
+ }
+ printf("(%s) ", prompt);
+ line[len++] = ' ';
+ if (fgets(&line[len], sizeof(line) - len, stdin) == NULL)
+ intr(0);
+ len += strlen(&line[len]);
+ if (len > 0 && line[len - 1] == '\n')
+ line[len - 1] = '\0';
+ makeargv();
+ ret = margc > *pargc;
+ *pargc = margc;
+ *pargv = margv;
+ return (ret);
+}
+
+/*
+ * Connect to peer server and
+ * auto-login, if possible.
+ */
+void
+setpeer(int argc, char **argv)
+{
+ char *host;
+ short port;
+ struct servent *sp;
+
+ if (connected) {
+ printf("Already connected to %s, use close first.\n",
+ hostname);
+ code = -1;
+ return;
+ }
+ if (argc < 2)
+ another(&argc, &argv, "to");
+ if (argc < 2 || argc > 3) {
+ printf("usage: %s host-name [port]\n", argv[0]);
+ code = -1;
+ return;
+ }
+ sp = getservbyname("ftp", "tcp");
+ if (sp == NULL)
+ errx(1, "You bastard. You removed ftp/tcp from services");
+ port = sp->s_port;
+ if (argc > 2) {
+ port = atoi(argv[2]);
+ if (port <= 0) {
+ printf("%s: bad port number-- %s\n", argv[1], argv[2]);
+ printf ("usage: %s host-name [port]\n", argv[0]);
+ code = -1;
+ return;
+ }
+ port = htons(port);
+ }
+ host = hookup(argv[1], port);
+ if (host) {
+ int overbose;
+
+ connected = 1;
+ /*
+ * Set up defaults for FTP.
+ */
+ strlcpy(typename, "ascii", sizeof(typename));
+ type = TYPE_A;
+ curtype = TYPE_A;
+ strlcpy(formname, "non-print", sizeof(formname));
+ form = FORM_N;
+ strlcpy(modename, "stream", sizeof(modename));
+ mode = MODE_S;
+ strlcpy(structname, "file", sizeof(structname));
+ stru = STRU_F;
+ strlcpy(bytename, "8", sizeof(bytename));
+ bytesize = 8;
+ if (autologin)
+ login(argv[1]);
+
+#if (defined(unix) || defined(__unix__) || defined(__unix) || defined(_AIX) || defined(_CRAY)) && NBBY == 8
+/*
+ * this ifdef is to keep someone form "porting" this to an incompatible
+ * system and not checking this out. This way they have to think about it.
+ */
+ overbose = verbose;
+ if (debug == 0)
+ verbose = -1;
+ if (command("SYST") == COMPLETE && overbose) {
+ char *cp, c;
+ cp = strchr(reply_string+4, ' ');
+ if (cp == NULL)
+ cp = strchr(reply_string+4, '\r');
+ if (cp) {
+ if (cp[-1] == '.')
+ cp--;
+ c = *cp;
+ *cp = '\0';
+ }
+
+ printf("Remote system type is %s.\n",
+ reply_string+4);
+ if (cp)
+ *cp = c;
+ }
+ if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) {
+ if (proxy)
+ unix_proxy = 1;
+ else
+ unix_server = 1;
+ /*
+ * Set type to 0 (not specified by user),
+ * meaning binary by default, but don't bother
+ * telling server. We can use binary
+ * for text files unless changed by the user.
+ */
+ type = 0;
+ strlcpy(typename, "binary", sizeof(typename));
+ if (overbose)
+ printf("Using %s mode to transfer files.\n",
+ typename);
+ } else {
+ if (proxy)
+ unix_proxy = 0;
+ else
+ unix_server = 0;
+ if (overbose &&
+ !strncmp(reply_string, "215 TOPS20", 10))
+ printf(
+"Remember to set tenex mode when transfering binary files from this machine.\n");
+ }
+ verbose = overbose;
+#endif /* unix */
+ }
+}
+
+struct types {
+ char *t_name;
+ char *t_mode;
+ int t_type;
+ char *t_arg;
+} types[] = {
+ { "ascii", "A", TYPE_A, 0 },
+ { "binary", "I", TYPE_I, 0 },
+ { "image", "I", TYPE_I, 0 },
+ { "ebcdic", "E", TYPE_E, 0 },
+ { "tenex", "L", TYPE_L, bytename },
+ { NULL }
+};
+
+/*
+ * Set transfer type.
+ */
+void
+settype(int argc, char **argv)
+{
+ struct types *p;
+ int comret;
+
+ if (argc > 2) {
+ char *sep;
+
+ printf("usage: %s [", argv[0]);
+ sep = " ";
+ for (p = types; p->t_name; p++) {
+ printf("%s%s", sep, p->t_name);
+ sep = " | ";
+ }
+ printf(" ]\n");
+ code = -1;
+ return;
+ }
+ if (argc < 2) {
+ printf("Using %s mode to transfer files.\n", typename);
+ code = 0;
+ return;
+ }
+ for (p = types; p->t_name; p++)
+ if (strcmp(argv[1], p->t_name) == 0)
+ break;
+ if (p->t_name == 0) {
+ printf("%s: unknown mode\n", argv[1]);
+ code = -1;
+ return;
+ }
+ if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
+ comret = command ("TYPE %s %s", p->t_mode, p->t_arg);
+ else
+ comret = command("TYPE %s", p->t_mode);
+ if (comret == COMPLETE) {
+ strlcpy(typename, p->t_name, sizeof(typename));
+ curtype = type = p->t_type;
+ }
+}
+
+/*
+ * Internal form of settype; changes current type in use with server
+ * without changing our notion of the type for data transfers.
+ * Used to change to and from ascii for listings.
+ */
+void
+changetype(int newtype, int show)
+{
+ struct types *p;
+ int comret, oldverbose = verbose;
+
+ if (newtype == 0)
+ newtype = TYPE_I;
+ if (newtype == curtype)
+ return;
+ if (debug == 0 && show == 0)
+ verbose = 0;
+ for (p = types; p->t_name; p++)
+ if (newtype == p->t_type)
+ break;
+ if (p->t_name == 0) {
+ printf("ftp: internal error: unknown type %d\n", newtype);
+ return;
+ }
+ if (newtype == TYPE_L && bytename[0] != '\0')
+ comret = command("TYPE %s %s", p->t_mode, bytename);
+ else
+ comret = command("TYPE %s", p->t_mode);
+ if (comret == COMPLETE)
+ curtype = newtype;
+ verbose = oldverbose;
+}
+
+char *stype[] = {
+ "type",
+ "",
+ 0
+};
+
+/*
+ * Set binary transfer type.
+ */
+/*VARARGS*/
+void
+setbinary(int argc, char **argv)
+{
+
+ stype[1] = "binary";
+ settype(2, stype);
+}
+
+/*
+ * Set ascii transfer type.
+ */
+/*VARARGS*/
+void
+setascii(int argc, char **argv)
+{
+
+ stype[1] = "ascii";
+ settype(2, stype);
+}
+
+/*
+ * Set tenex transfer type.
+ */
+/*VARARGS*/
+void
+settenex(int argc, char **argv)
+{
+
+ stype[1] = "tenex";
+ settype(2, stype);
+}
+
+/*
+ * Set file transfer mode.
+ */
+/*ARGSUSED*/
+void
+setftmode(int argc, char **argv)
+{
+
+ printf("We only support %s mode, sorry.\n", modename);
+ code = -1;
+}
+
+/*
+ * Set file transfer format.
+ */
+/*ARGSUSED*/
+void
+setform(int argc, char **argv)
+{
+
+ printf("We only support %s format, sorry.\n", formname);
+ code = -1;
+}
+
+/*
+ * Set file transfer structure.
+ */
+/*ARGSUSED*/
+void
+setstruct(int argc, char **argv)
+{
+
+ printf("We only support %s structure, sorry.\n", structname);
+ code = -1;
+}
+
+/*
+ * Send a single file.
+ */
+void
+put(int argc, char **argv)
+{
+ char *cmd;
+ int loc = 0;
+ char *oldargv1, *oldargv2;
+
+ if (argc == 2) {
+ argc++;
+ argv[2] = argv[1];
+ loc++;
+ }
+ if (argc < 2 && !another(&argc, &argv, "local-file"))
+ goto usage;
+ if (argc < 3 && !another(&argc, &argv, "remote-file")) {
+usage:
+ printf("usage: %s local-file remote-file\n", argv[0]);
+ code = -1;
+ return;
+ }
+ oldargv1 = argv[1];
+ oldargv2 = argv[2];
+ if (!globulize(&argv[1])) {
+ code = -1;
+ return;
+ }
+ /*
+ * If "globulize" modifies argv[1], and argv[2] is a copy of
+ * the old argv[1], make it a copy of the new argv[1].
+ */
+ if (argv[1] != oldargv1 && argv[2] == oldargv1) {
+ argv[2] = argv[1];
+ }
+ cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
+ if (loc && ntflag) {
+ argv[2] = dotrans(argv[2]);
+ }
+ if (loc && mapflag) {
+ argv[2] = domap(argv[2]);
+ }
+ sendrequest(cmd, argv[1], argv[2],
+ curtype == TYPE_I ? "rb" : "r",
+ argv[1] != oldargv1 || argv[2] != oldargv2);
+}
+
+/* ARGSUSED */
+static RETSIGTYPE
+mabort(int signo)
+{
+ int ointer;
+
+ printf("\n");
+ fflush(stdout);
+ if (mflag && fromatty) {
+ ointer = interactive;
+ interactive = 1;
+ if (confirm("Continue with", mname)) {
+ interactive = ointer;
+ longjmp(jabort,0);
+ }
+ interactive = ointer;
+ }
+ mflag = 0;
+ longjmp(jabort,0);
+}
+
+/*
+ * Send multiple files.
+ */
+void
+mput(int argc, char **argv)
+{
+ int i;
+ RETSIGTYPE (*oldintr)();
+ int ointer;
+ char *tp;
+
+ if (argc < 2 && !another(&argc, &argv, "local-files")) {
+ printf("usage: %s local-files\n", argv[0]);
+ code = -1;
+ return;
+ }
+ mname = argv[0];
+ mflag = 1;
+ oldintr = signal(SIGINT, mabort);
+ setjmp(jabort);
+ if (proxy) {
+ char *cp, *tp2, tmpbuf[MaxPathLen];
+
+ while ((cp = remglob(argv,0)) != NULL) {
+ if (*cp == 0) {
+ mflag = 0;
+ continue;
+ }
+ if (mflag && confirm(argv[0], cp)) {
+ tp = cp;
+ if (mcase) {
+ while (*tp && !islower(*tp)) {
+ tp++;
+ }
+ if (!*tp) {
+ tp = cp;
+ tp2 = tmpbuf;
+ while ((*tp2 = *tp) != '\0') {
+ if (isupper(*tp2)) {
+ *tp2 = 'a' + *tp2 - 'A';
+ }
+ tp++;
+ tp2++;
+ }
+ }
+ tp = tmpbuf;
+ }
+ if (ntflag) {
+ tp = dotrans(tp);
+ }
+ if (mapflag) {
+ tp = domap(tp);
+ }
+ sendrequest((sunique) ? "STOU" : "STOR",
+ cp, tp,
+ curtype == TYPE_I ? "rb" : "r",
+ cp != tp || !interactive);
+ if (!mflag && fromatty) {
+ ointer = interactive;
+ interactive = 1;
+ if (confirm("Continue with","mput")) {
+ mflag++;
+ }
+ interactive = ointer;
+ }
+ }
+ }
+ signal(SIGINT, oldintr);
+ mflag = 0;
+ return;
+ }
+ for (i = 1; i < argc; i++) {
+ char **cpp;
+ glob_t gl;
+ int flags;
+
+ if (!doglob) {
+ if (mflag && confirm(argv[0], argv[i])) {
+ tp = (ntflag) ? dotrans(argv[i]) : argv[i];
+ tp = (mapflag) ? domap(tp) : tp;
+ sendrequest((sunique) ? "STOU" : "STOR",
+ argv[i],
+ curtype == TYPE_I ? "rb" : "r",
+ tp, tp != argv[i] || !interactive);
+ if (!mflag && fromatty) {
+ ointer = interactive;
+ interactive = 1;
+ if (confirm("Continue with","mput")) {
+ mflag++;
+ }
+ interactive = ointer;
+ }
+ }
+ continue;
+ }
+
+ memset(&gl, 0, sizeof(gl));
+ flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+ if (glob(argv[i], flags, NULL, &gl) || gl.gl_pathc == 0) {
+ warnx("%s: not found", argv[i]);
+ globfree(&gl);
+ continue;
+ }
+ for (cpp = gl.gl_pathv; cpp && *cpp != NULL; cpp++) {
+ if (mflag && confirm(argv[0], *cpp)) {
+ tp = (ntflag) ? dotrans(*cpp) : *cpp;
+ tp = (mapflag) ? domap(tp) : tp;
+ sendrequest((sunique) ? "STOU" : "STOR",
+ *cpp, tp,
+ curtype == TYPE_I ? "rb" : "r",
+ *cpp != tp || !interactive);
+ if (!mflag && fromatty) {
+ ointer = interactive;
+ interactive = 1;
+ if (confirm("Continue with","mput")) {
+ mflag++;
+ }
+ interactive = ointer;
+ }
+ }
+ }
+ globfree(&gl);
+ }
+ signal(SIGINT, oldintr);
+ mflag = 0;
+}
+
+void
+reget(int argc, char **argv)
+{
+ getit(argc, argv, 1, curtype == TYPE_I ? "r+wb" : "r+w");
+}
+
+void
+get(int argc, char **argv)
+{
+ char *mode;
+
+ if (restart_point)
+ if (curtype == TYPE_I)
+ mode = "r+wb";
+ else
+ mode = "r+w";
+ else
+ if (curtype == TYPE_I)
+ mode = "wb";
+ else
+ mode = "w";
+
+ getit(argc, argv, 0, mode);
+}
+
+/*
+ * Receive one file.
+ */
+int
+getit(int argc, char **argv, int restartit, char *mode)
+{
+ int loc = 0;
+ int local_given = 1;
+ char *oldargv1, *oldargv2;
+
+ if (argc == 2) {
+ argc++;
+ local_given = 0;
+ argv[2] = argv[1];
+ loc++;
+ }
+ if ((argc < 2 && !another(&argc, &argv, "remote-file")) ||
+ (argc < 3 && !another(&argc, &argv, "local-file"))) {
+ printf("usage: %s remote-file [ local-file ]\n", argv[0]);
+ code = -1;
+ return (0);
+ }
+ oldargv1 = argv[1];
+ oldargv2 = argv[2];
+ if (!globulize(&argv[2])) {
+ code = -1;
+ return (0);
+ }
+ if (loc && mcase) {
+ char *tp = argv[1], *tp2, tmpbuf[MaxPathLen];
+
+ while (*tp && !islower(*tp)) {
+ tp++;
+ }
+ if (!*tp) {
+ tp = argv[2];
+ tp2 = tmpbuf;
+ while ((*tp2 = *tp) != '\0') {
+ if (isupper(*tp2)) {
+ *tp2 = 'a' + *tp2 - 'A';
+ }
+ tp++;
+ tp2++;
+ }
+ argv[2] = tmpbuf;
+ }
+ }
+ if (loc && ntflag)
+ argv[2] = dotrans(argv[2]);
+ if (loc && mapflag)
+ argv[2] = domap(argv[2]);
+ if (restartit) {
+ struct stat stbuf;
+ int ret;
+
+ ret = stat(argv[2], &stbuf);
+ if (restartit == 1) {
+ if (ret < 0) {
+ warn("local: %s", argv[2]);
+ return (0);
+ }
+ restart_point = stbuf.st_size;
+ } else if (ret == 0) {
+ int overbose;
+ int cmdret;
+ int yy, mo, day, hour, min, sec;
+ struct tm *tm;
+
+ overbose = verbose;
+ if (debug == 0)
+ verbose = -1;
+ cmdret = command("MDTM %s", argv[1]);
+ verbose = overbose;
+ if (cmdret != COMPLETE) {
+ printf("%s\n", reply_string);
+ return (0);
+ }
+ if (sscanf(reply_string,
+ "%*s %04d%02d%02d%02d%02d%02d",
+ &yy, &mo, &day, &hour, &min, &sec)
+ != 6) {
+ printf ("bad MDTM result\n");
+ return (0);
+ }
+
+ tm = gmtime(&stbuf.st_mtime);
+ tm->tm_mon++;
+ tm->tm_year += 1900;
+
+ if ((tm->tm_year > yy) ||
+ (tm->tm_year == yy &&
+ tm->tm_mon > mo) ||
+ (tm->tm_mon == mo &&
+ tm->tm_mday > day) ||
+ (tm->tm_mday == day &&
+ tm->tm_hour > hour) ||
+ (tm->tm_hour == hour &&
+ tm->tm_min > min) ||
+ (tm->tm_min == min &&
+ tm->tm_sec > sec))
+ return (1);
+ }
+ }
+
+ recvrequest("RETR", argv[2], argv[1], mode,
+ argv[1] != oldargv1 || argv[2] != oldargv2, local_given);
+ restart_point = 0;
+ return (0);
+}
+
+static int
+suspicious_filename(const char *fn)
+{
+ return strstr(fn, "../") != NULL || *fn == '/';
+}
+
+/*
+ * Get multiple files.
+ */
+void
+mget(int argc, char **argv)
+{
+ sighand oldintr;
+ int ch, ointer;
+ char *cp, *tp, *tp2, tmpbuf[MaxPathLen];
+
+ if (argc < 2 && !another(&argc, &argv, "remote-files")) {
+ printf("usage: %s remote-files\n", argv[0]);
+ code = -1;
+ return;
+ }
+ mname = argv[0];
+ mflag = 1;
+ oldintr = signal(SIGINT, mabort);
+ setjmp(jabort);
+ while ((cp = remglob(argv,proxy)) != NULL) {
+ if (*cp == '\0') {
+ mflag = 0;
+ continue;
+ }
+ if (mflag && suspicious_filename(cp))
+ printf("*** Suspicious filename: %s\n", cp);
+ if (mflag && confirm(argv[0], cp)) {
+ tp = cp;
+ if (mcase) {
+ for (tp2 = tmpbuf; (ch = *tp++);)
+ *tp2++ = isupper(ch) ? tolower(ch) : ch;
+ *tp2 = '\0';
+ tp = tmpbuf;
+ }
+ if (ntflag) {
+ tp = dotrans(tp);
+ }
+ if (mapflag) {
+ tp = domap(tp);
+ }
+ recvrequest("RETR", tp, cp,
+ curtype == TYPE_I ? "wb" : "w",
+ tp != cp || !interactive, 0);
+ if (!mflag && fromatty) {
+ ointer = interactive;
+ interactive = 1;
+ if (confirm("Continue with","mget")) {
+ mflag++;
+ }
+ interactive = ointer;
+ }
+ }
+ }
+ signal(SIGINT,oldintr);
+ mflag = 0;
+}
+
+char *
+remglob(char **argv, int doswitch)
+{
+ char temp[16];
+ static char buf[MaxPathLen];
+ static FILE *ftemp = NULL;
+ static char **args;
+ int oldverbose, oldhash;
+ char *cp, *mode;
+
+ if (!mflag) {
+ if (!doglob) {
+ args = NULL;
+ }
+ else {
+ if (ftemp) {
+ fclose(ftemp);
+ ftemp = NULL;
+ }
+ }
+ return (NULL);
+ }
+ if (!doglob) {
+ if (args == NULL)
+ args = argv;
+ if ((cp = *++args) == NULL)
+ args = NULL;
+ return (cp);
+ }
+ if (ftemp == NULL) {
+ int fd;
+ strlcpy(temp, _PATH_TMP_XXX, sizeof(temp));
+ fd = mkstemp(temp);
+ if(fd < 0){
+ warn("unable to create temporary file %s", temp);
+ return NULL;
+ }
+ close(fd);
+ oldverbose = verbose, verbose = 0;
+ oldhash = hash, hash = 0;
+ if (doswitch) {
+ pswitch(!proxy);
+ }
+ for (mode = "w"; *++argv != NULL; mode = "a")
+ recvrequest ("NLST", temp, *argv, mode, 0, 0);
+ if (doswitch) {
+ pswitch(!proxy);
+ }
+ verbose = oldverbose; hash = oldhash;
+ ftemp = fopen(temp, "r");
+ unlink(temp);
+ if (ftemp == NULL) {
+ printf("can't find list of remote files, oops\n");
+ return (NULL);
+ }
+ }
+ while(fgets(buf, sizeof (buf), ftemp)) {
+ if ((cp = strchr(buf, '\n')) != NULL)
+ *cp = '\0';
+ if(!interactive && suspicious_filename(buf)){
+ printf("Ignoring remote globbed file `%s'\n", buf);
+ continue;
+ }
+ return buf;
+ }
+ fclose(ftemp);
+ ftemp = NULL;
+ return (NULL);
+}
+
+char *
+onoff(int bool)
+{
+
+ return (bool ? "on" : "off");
+}
+
+/*
+ * Show status.
+ */
+/*ARGSUSED*/
+void
+status(int argc, char **argv)
+{
+ int i;
+
+ if (connected)
+ printf("Connected to %s.\n", hostname);
+ else
+ printf("Not connected.\n");
+ if (!proxy) {
+ pswitch(1);
+ if (connected) {
+ printf("Connected for proxy commands to %s.\n", hostname);
+ }
+ else {
+ printf("No proxy connection.\n");
+ }
+ pswitch(0);
+ }
+ sec_status();
+ printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
+ modename, typename, formname, structname);
+ printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n",
+ onoff(verbose), onoff(bell), onoff(interactive),
+ onoff(doglob));
+ printf("Store unique: %s; Receive unique: %s\n", onoff(sunique),
+ onoff(runique));
+ printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag));
+ if (ntflag) {
+ printf("Ntrans: (in) %s (out) %s\n", ntin,ntout);
+ }
+ else {
+ printf("Ntrans: off\n");
+ }
+ if (mapflag) {
+ printf("Nmap: (in) %s (out) %s\n", mapin, mapout);
+ }
+ else {
+ printf("Nmap: off\n");
+ }
+ printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
+ onoff(hash), onoff(sendport));
+ if (macnum > 0) {
+ printf("Macros:\n");
+ for (i=0; i<macnum; i++) {
+ printf("\t%s\n",macros[i].mac_name);
+ }
+ }
+ code = 0;
+}
+
+/*
+ * Set beep on cmd completed mode.
+ */
+/*VARARGS*/
+void
+setbell(int argc, char **argv)
+{
+
+ bell = !bell;
+ printf("Bell mode %s.\n", onoff(bell));
+ code = bell;
+}
+
+/*
+ * Turn on packet tracing.
+ */
+/*VARARGS*/
+void
+settrace(int argc, char **argv)
+{
+
+ trace = !trace;
+ printf("Packet tracing %s.\n", onoff(trace));
+ code = trace;
+}
+
+/*
+ * Toggle hash mark printing during transfers.
+ */
+/*VARARGS*/
+void
+sethash(int argc, char **argv)
+{
+
+ hash = !hash;
+ printf("Hash mark printing %s", onoff(hash));
+ code = hash;
+ if (hash)
+ printf(" (%d bytes/hash mark)", 1024);
+ printf(".\n");
+}
+
+/*
+ * Turn on printing of server echo's.
+ */
+/*VARARGS*/
+void
+setverbose(int argc, char **argv)
+{
+
+ verbose = !verbose;
+ printf("Verbose mode %s.\n", onoff(verbose));
+ code = verbose;
+}
+
+/*
+ * Toggle PORT cmd use before each data connection.
+ */
+/*VARARGS*/
+void
+setport(int argc, char **argv)
+{
+
+ sendport = !sendport;
+ printf("Use of PORT cmds %s.\n", onoff(sendport));
+ code = sendport;
+}
+
+/*
+ * Turn on interactive prompting
+ * during mget, mput, and mdelete.
+ */
+/*VARARGS*/
+void
+setprompt(int argc, char **argv)
+{
+
+ interactive = !interactive;
+ printf("Interactive mode %s.\n", onoff(interactive));
+ code = interactive;
+}
+
+/*
+ * Toggle metacharacter interpretation
+ * on local file names.
+ */
+/*VARARGS*/
+void
+setglob(int argc, char **argv)
+{
+
+ doglob = !doglob;
+ printf("Globbing %s.\n", onoff(doglob));
+ code = doglob;
+}
+
+/*
+ * Set debugging mode on/off and/or
+ * set level of debugging.
+ */
+/*VARARGS*/
+void
+setdebug(int argc, char **argv)
+{
+ int val;
+
+ if (argc > 1) {
+ val = atoi(argv[1]);
+ if (val < 0) {
+ printf("%s: bad debugging value.\n", argv[1]);
+ code = -1;
+ return;
+ }
+ } else
+ val = !debug;
+ debug = val;
+ if (debug)
+ options |= SO_DEBUG;
+ else
+ options &= ~SO_DEBUG;
+ printf("Debugging %s (debug=%d).\n", onoff(debug), debug);
+ code = debug > 0;
+}
+
+/*
+ * Set current working directory
+ * on remote machine.
+ */
+void
+cd(int argc, char **argv)
+{
+
+ if (argc < 2 && !another(&argc, &argv, "remote-directory")) {
+ printf("usage: %s remote-directory\n", argv[0]);
+ code = -1;
+ return;
+ }
+ if (command("CWD %s", argv[1]) == ERROR && code == 500) {
+ if (verbose)
+ printf("CWD command not recognized, trying XCWD\n");
+ command("XCWD %s", argv[1]);
+ }
+}
+
+/*
+ * Set current working directory
+ * on local machine.
+ */
+void
+lcd(int argc, char **argv)
+{
+ char buf[MaxPathLen];
+
+ if (argc < 2)
+ argc++, argv[1] = home;
+ if (argc != 2) {
+ printf("usage: %s local-directory\n", argv[0]);
+ code = -1;
+ return;
+ }
+ if (!globulize(&argv[1])) {
+ code = -1;
+ return;
+ }
+ if (chdir(argv[1]) < 0) {
+ warn("local: %s", argv[1]);
+ code = -1;
+ return;
+ }
+ if (getcwd(buf, sizeof(buf)) != NULL)
+ printf("Local directory now %s\n", buf);
+ else
+ warnx("getwd: %s", buf);
+ code = 0;
+}
+
+/*
+ * Delete a single file.
+ */
+void
+delete(int argc, char **argv)
+{
+
+ if (argc < 2 && !another(&argc, &argv, "remote-file")) {
+ printf("usage: %s remote-file\n", argv[0]);
+ code = -1;
+ return;
+ }
+ command("DELE %s", argv[1]);
+}
+
+/*
+ * Delete multiple files.
+ */
+void
+mdelete(int argc, char **argv)
+{
+ sighand oldintr;
+ int ointer;
+ char *cp;
+
+ if (argc < 2 && !another(&argc, &argv, "remote-files")) {
+ printf("usage: %s remote-files\n", argv[0]);
+ code = -1;
+ return;
+ }
+ mname = argv[0];
+ mflag = 1;
+ oldintr = signal(SIGINT, mabort);
+ setjmp(jabort);
+ while ((cp = remglob(argv,0)) != NULL) {
+ if (*cp == '\0') {
+ mflag = 0;
+ continue;
+ }
+ if (mflag && confirm(argv[0], cp)) {
+ command("DELE %s", cp);
+ if (!mflag && fromatty) {
+ ointer = interactive;
+ interactive = 1;
+ if (confirm("Continue with", "mdelete")) {
+ mflag++;
+ }
+ interactive = ointer;
+ }
+ }
+ }
+ signal(SIGINT, oldintr);
+ mflag = 0;
+}
+
+/*
+ * Rename a remote file.
+ */
+void
+renamefile(int argc, char **argv)
+{
+
+ if (argc < 2 && !another(&argc, &argv, "from-name"))
+ goto usage;
+ if (argc < 3 && !another(&argc, &argv, "to-name")) {
+usage:
+ printf("%s from-name to-name\n", argv[0]);
+ code = -1;
+ return;
+ }
+ if (command("RNFR %s", argv[1]) == CONTINUE)
+ command("RNTO %s", argv[2]);
+}
+
+/*
+ * Get a directory listing
+ * of remote files.
+ */
+void
+ls(int argc, char **argv)
+{
+ char *cmd;
+
+ if (argc < 2)
+ argc++, argv[1] = NULL;
+ if (argc < 3)
+ argc++, argv[2] = "-";
+ if (argc > 3) {
+ printf("usage: %s remote-directory local-file\n", argv[0]);
+ code = -1;
+ return;
+ }
+ cmd = argv[0][0] == 'n' ? "NLST" : "LIST";
+ if (strcmp(argv[2], "-") && !globulize(&argv[2])) {
+ code = -1;
+ return;
+ }
+ if (strcmp(argv[2], "-") && *argv[2] != '|')
+ if (!globulize(&argv[2]) || !confirm("output to local-file:",
+ argv[2])) {
+ code = -1;
+ return;
+ }
+ recvrequest(cmd, argv[2], argv[1], "w", 0, 1);
+}
+
+/*
+ * Get a directory listing
+ * of multiple remote files.
+ */
+void
+mls(int argc, char **argv)
+{
+ sighand oldintr;
+ int ointer, i;
+ char *cmd, mode[1], *dest;
+
+ if (argc < 2 && !another(&argc, &argv, "remote-files"))
+ goto usage;
+ if (argc < 3 && !another(&argc, &argv, "local-file")) {
+usage:
+ printf("usage: %s remote-files local-file\n", argv[0]);
+ code = -1;
+ return;
+ }
+ dest = argv[argc - 1];
+ argv[argc - 1] = NULL;
+ if (strcmp(dest, "-") && *dest != '|')
+ if (!globulize(&dest) ||
+ !confirm("output to local-file:", dest)) {
+ code = -1;
+ return;
+ }
+ cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
+ mname = argv[0];
+ mflag = 1;
+ oldintr = signal(SIGINT, mabort);
+ setjmp(jabort);
+ for (i = 1; mflag && i < argc-1; ++i) {
+ *mode = (i == 1) ? 'w' : 'a';
+ recvrequest(cmd, dest, argv[i], mode, 0, 1);
+ if (!mflag && fromatty) {
+ ointer = interactive;
+ interactive = 1;
+ if (confirm("Continue with", argv[0])) {
+ mflag ++;
+ }
+ interactive = ointer;
+ }
+ }
+ signal(SIGINT, oldintr);
+ mflag = 0;
+}
+
+/*
+ * Do a shell escape
+ */
+/*ARGSUSED*/
+void
+shell(int argc, char **argv)
+{
+ pid_t pid;
+ RETSIGTYPE (*old1)(), (*old2)();
+ char shellnam[40], *shell, *namep;
+ int status;
+
+ old1 = signal (SIGINT, SIG_IGN);
+ old2 = signal (SIGQUIT, SIG_IGN);
+ if ((pid = fork()) == 0) {
+ for (pid = 3; pid < 20; pid++)
+ close(pid);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+ shell = getenv("SHELL");
+ if (shell == NULL)
+ shell = _PATH_BSHELL;
+ namep = strrchr(shell,'/');
+ if (namep == NULL)
+ namep = shell;
+ snprintf (shellnam, sizeof(shellnam),
+ "-%s", ++namep);
+ if (strcmp(namep, "sh") != 0)
+ shellnam[0] = '+';
+ if (debug) {
+ printf ("%s\n", shell);
+ fflush (stdout);
+ }
+ if (argc > 1) {
+ execl(shell,shellnam,"-c",altarg,(char *)0);
+ }
+ else {
+ execl(shell,shellnam,(char *)0);
+ }
+ warn("%s", shell);
+ code = -1;
+ exit(1);
+ }
+ if (pid > 0)
+ while (waitpid(-1, &status, 0) != pid)
+ ;
+ signal(SIGINT, old1);
+ signal(SIGQUIT, old2);
+ if (pid == -1) {
+ warn("%s", "Try again later");
+ code = -1;
+ }
+ else {
+ code = 0;
+ }
+}
+
+/*
+ * Send new user information (re-login)
+ */
+void
+user(int argc, char **argv)
+{
+ char acct[80];
+ int n, aflag = 0;
+ char tmp[256];
+
+ if (argc < 2)
+ another(&argc, &argv, "username");
+ if (argc < 2 || argc > 4) {
+ printf("usage: %s username [password] [account]\n", argv[0]);
+ code = -1;
+ return;
+ }
+ n = command("USER %s", argv[1]);
+ if (n == CONTINUE) {
+ if (argc < 3 ) {
+ des_read_pw_string (tmp,
+ sizeof(tmp),
+ "Password: ", 0);
+ argv[2] = tmp;
+ argc++;
+ }
+ n = command("PASS %s", argv[2]);
+ }
+ if (n == CONTINUE) {
+ if (argc < 4) {
+ printf("Account: "); fflush(stdout);
+ fgets(acct, sizeof(acct) - 1, stdin);
+ acct[strlen(acct) - 1] = '\0';
+ argv[3] = acct; argc++;
+ }
+ n = command("ACCT %s", argv[3]);
+ aflag++;
+ }
+ if (n != COMPLETE) {
+ fprintf(stdout, "Login failed.\n");
+ return;
+ }
+ if (!aflag && argc == 4) {
+ command("ACCT %s", argv[3]);
+ }
+}
+
+/*
+ * Print working directory.
+ */
+/*VARARGS*/
+void
+pwd(int argc, char **argv)
+{
+ int oldverbose = verbose;
+
+ /*
+ * If we aren't verbose, this doesn't do anything!
+ */
+ verbose = 1;
+ if (command("PWD") == ERROR && code == 500) {
+ printf("PWD command not recognized, trying XPWD\n");
+ command("XPWD");
+ }
+ verbose = oldverbose;
+}
+
+/*
+ * Make a directory.
+ */
+void
+makedir(int argc, char **argv)
+{
+
+ if (argc < 2 && !another(&argc, &argv, "directory-name")) {
+ printf("usage: %s directory-name\n", argv[0]);
+ code = -1;
+ return;
+ }
+ if (command("MKD %s", argv[1]) == ERROR && code == 500) {
+ if (verbose)
+ printf("MKD command not recognized, trying XMKD\n");
+ command("XMKD %s", argv[1]);
+ }
+}
+
+/*
+ * Remove a directory.
+ */
+void
+removedir(int argc, char **argv)
+{
+
+ if (argc < 2 && !another(&argc, &argv, "directory-name")) {
+ printf("usage: %s directory-name\n", argv[0]);
+ code = -1;
+ return;
+ }
+ if (command("RMD %s", argv[1]) == ERROR && code == 500) {
+ if (verbose)
+ printf("RMD command not recognized, trying XRMD\n");
+ command("XRMD %s", argv[1]);
+ }
+}
+
+/*
+ * Send a line, verbatim, to the remote machine.
+ */
+void
+quote(int argc, char **argv)
+{
+
+ if (argc < 2 && !another(&argc, &argv, "command line to send")) {
+ printf("usage: %s line-to-send\n", argv[0]);
+ code = -1;
+ return;
+ }
+ quote1("", argc, argv);
+}
+
+/*
+ * Send a SITE command to the remote machine. The line
+ * is sent verbatim to the remote machine, except that the
+ * word "SITE" is added at the front.
+ */
+void
+site(int argc, char **argv)
+{
+
+ if (argc < 2 && !another(&argc, &argv, "arguments to SITE command")) {
+ printf("usage: %s line-to-send\n", argv[0]);
+ code = -1;
+ return;
+ }
+ quote1("SITE ", argc, argv);
+}
+
+/*
+ * Turn argv[1..argc) into a space-separated string, then prepend initial text.
+ * Send the result as a one-line command and get response.
+ */
+void
+quote1(char *initial, int argc, char **argv)
+{
+ int i;
+ char buf[BUFSIZ]; /* must be >= sizeof(line) */
+
+ strlcpy(buf, initial, sizeof(buf));
+ for(i = 1; i < argc; i++) {
+ if(i > 1)
+ strlcat(buf, " ", sizeof(buf));
+ strlcat(buf, argv[i], sizeof(buf));
+ }
+ if (command("%s", buf) == PRELIM) {
+ while (getreply(0) == PRELIM)
+ continue;
+ }
+}
+
+void
+do_chmod(int argc, char **argv)
+{
+
+ if (argc < 2 && !another(&argc, &argv, "mode"))
+ goto usage;
+ if (argc < 3 && !another(&argc, &argv, "file-name")) {
+usage:
+ printf("usage: %s mode file-name\n", argv[0]);
+ code = -1;
+ return;
+ }
+ command("SITE CHMOD %s %s", argv[1], argv[2]);
+}
+
+void
+do_umask(int argc, char **argv)
+{
+ int oldverbose = verbose;
+
+ verbose = 1;
+ command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]);
+ verbose = oldverbose;
+}
+
+void
+ftp_idle(int argc, char **argv)
+{
+ int oldverbose = verbose;
+
+ verbose = 1;
+ command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]);
+ verbose = oldverbose;
+}
+
+/*
+ * Ask the other side for help.
+ */
+void
+rmthelp(int argc, char **argv)
+{
+ int oldverbose = verbose;
+
+ verbose = 1;
+ command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
+ verbose = oldverbose;
+}
+
+/*
+ * Terminate session and exit.
+ */
+/*VARARGS*/
+void
+quit(int argc, char **argv)
+{
+
+ if (connected)
+ disconnect(0, 0);
+ pswitch(1);
+ if (connected) {
+ disconnect(0, 0);
+ }
+ exit(0);
+}
+
+/*
+ * Terminate session, but don't exit.
+ */
+void
+disconnect(int argc, char **argv)
+{
+
+ if (!connected)
+ return;
+ command("QUIT");
+ if (cout) {
+ fclose(cout);
+ }
+ cout = NULL;
+ connected = 0;
+ sec_end();
+ data = -1;
+ if (!proxy) {
+ macnum = 0;
+ }
+}
+
+int
+confirm(char *cmd, char *file)
+{
+ char line[BUFSIZ];
+
+ if (!interactive)
+ return (1);
+ printf("%s %s? ", cmd, file);
+ fflush(stdout);
+ if (fgets(line, sizeof line, stdin) == NULL)
+ return (0);
+ return (*line == 'y' || *line == 'Y');
+}
+
+void
+fatal(char *msg)
+{
+
+ errx(1, "%s", msg);
+}
+
+/*
+ * Glob a local file name specification with
+ * the expectation of a single return value.
+ * Can't control multiple values being expanded
+ * from the expression, we return only the first.
+ */
+int
+globulize(char **cpp)
+{
+ glob_t gl;
+ int flags;
+
+ if (!doglob)
+ return (1);
+
+ flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+ memset(&gl, 0, sizeof(gl));
+ if (glob(*cpp, flags, NULL, &gl) ||
+ gl.gl_pathc == 0) {
+ warnx("%s: not found", *cpp);
+ globfree(&gl);
+ return (0);
+ }
+ *cpp = strdup(gl.gl_pathv[0]); /* XXX - wasted memory */
+ globfree(&gl);
+ return (1);
+}
+
+void
+account(int argc, char **argv)
+{
+ char acct[50];
+
+ if (argc > 1) {
+ ++argv;
+ --argc;
+ strlcpy (acct, *argv, sizeof(acct));
+ while (argc > 1) {
+ --argc;
+ ++argv;
+ strlcat(acct, *argv, sizeof(acct));
+ }
+ }
+ else {
+ des_read_pw_string(acct, sizeof(acct), "Account:", 0);
+ }
+ command("ACCT %s", acct);
+}
+
+jmp_buf abortprox;
+
+static RETSIGTYPE
+proxabort(int sig)
+{
+
+ if (!proxy) {
+ pswitch(1);
+ }
+ if (connected) {
+ proxflag = 1;
+ }
+ else {
+ proxflag = 0;
+ }
+ pswitch(0);
+ longjmp(abortprox,1);
+}
+
+void
+doproxy(int argc, char **argv)
+{
+ struct cmd *c;
+ RETSIGTYPE (*oldintr)();
+
+ if (argc < 2 && !another(&argc, &argv, "command")) {
+ printf("usage: %s command\n", argv[0]);
+ code = -1;
+ return;
+ }
+ c = getcmd(argv[1]);
+ if (c == (struct cmd *) -1) {
+ printf("?Ambiguous command\n");
+ fflush(stdout);
+ code = -1;
+ return;
+ }
+ if (c == 0) {
+ printf("?Invalid command\n");
+ fflush(stdout);
+ code = -1;
+ return;
+ }
+ if (!c->c_proxy) {
+ printf("?Invalid proxy command\n");
+ fflush(stdout);
+ code = -1;
+ return;
+ }
+ if (setjmp(abortprox)) {
+ code = -1;
+ return;
+ }
+ oldintr = signal(SIGINT, proxabort);
+ pswitch(1);
+ if (c->c_conn && !connected) {
+ printf("Not connected\n");
+ fflush(stdout);
+ pswitch(0);
+ signal(SIGINT, oldintr);
+ code = -1;
+ return;
+ }
+ (*c->c_handler)(argc-1, argv+1);
+ if (connected) {
+ proxflag = 1;
+ }
+ else {
+ proxflag = 0;
+ }
+ pswitch(0);
+ signal(SIGINT, oldintr);
+}
+
+void
+setcase(int argc, char **argv)
+{
+
+ mcase = !mcase;
+ printf("Case mapping %s.\n", onoff(mcase));
+ code = mcase;
+}
+
+void
+setcr(int argc, char **argv)
+{
+
+ crflag = !crflag;
+ printf("Carriage Return stripping %s.\n", onoff(crflag));
+ code = crflag;
+}
+
+void
+setntrans(int argc, char **argv)
+{
+ if (argc == 1) {
+ ntflag = 0;
+ printf("Ntrans off.\n");
+ code = ntflag;
+ return;
+ }
+ ntflag++;
+ code = ntflag;
+ strlcpy (ntin, argv[1], 17);
+ if (argc == 2) {
+ ntout[0] = '\0';
+ return;
+ }
+ strlcpy (ntout, argv[2], 17);
+}
+
+char *
+dotrans(char *name)
+{
+ static char new[MaxPathLen];
+ char *cp1, *cp2 = new;
+ int i, ostop, found;
+
+ for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++)
+ continue;
+ for (cp1 = name; *cp1; cp1++) {
+ found = 0;
+ for (i = 0; *(ntin + i) && i < 16; i++) {
+ if (*cp1 == *(ntin + i)) {
+ found++;
+ if (i < ostop) {
+ *cp2++ = *(ntout + i);
+ }
+ break;
+ }
+ }
+ if (!found) {
+ *cp2++ = *cp1;
+ }
+ }
+ *cp2 = '\0';
+ return (new);
+}
+
+void
+setnmap(int argc, char **argv)
+{
+ char *cp;
+
+ if (argc == 1) {
+ mapflag = 0;
+ printf("Nmap off.\n");
+ code = mapflag;
+ return;
+ }
+ if (argc < 3 && !another(&argc, &argv, "mapout")) {
+ printf("Usage: %s [mapin mapout]\n",argv[0]);
+ code = -1;
+ return;
+ }
+ mapflag = 1;
+ code = 1;
+ cp = strchr(altarg, ' ');
+ if (proxy) {
+ while(*++cp == ' ')
+ continue;
+ altarg = cp;
+ cp = strchr(altarg, ' ');
+ }
+ *cp = '\0';
+ strlcpy(mapin, altarg, MaxPathLen);
+ while (*++cp == ' ')
+ continue;
+ strlcpy(mapout, cp, MaxPathLen);
+}
+
+char *
+domap(char *name)
+{
+ static char new[MaxPathLen];
+ char *cp1 = name, *cp2 = mapin;
+ char *tp[9], *te[9];
+ int i, toks[9], toknum = 0, match = 1;
+
+ for (i=0; i < 9; ++i) {
+ toks[i] = 0;
+ }
+ while (match && *cp1 && *cp2) {
+ switch (*cp2) {
+ case '\\':
+ if (*++cp2 != *cp1) {
+ match = 0;
+ }
+ break;
+ case '$':
+ if (*(cp2+1) >= '1' && (*cp2+1) <= '9') {
+ if (*cp1 != *(++cp2+1)) {
+ toks[toknum = *cp2 - '1']++;
+ tp[toknum] = cp1;
+ while (*++cp1 && *(cp2+1)
+ != *cp1);
+ te[toknum] = cp1;
+ }
+ cp2++;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ if (*cp2 != *cp1) {
+ match = 0;
+ }
+ break;
+ }
+ if (match && *cp1) {
+ cp1++;
+ }
+ if (match && *cp2) {
+ cp2++;
+ }
+ }
+ if (!match && *cp1) /* last token mismatch */
+ {
+ toks[toknum] = 0;
+ }
+ cp1 = new;
+ *cp1 = '\0';
+ cp2 = mapout;
+ while (*cp2) {
+ match = 0;
+ switch (*cp2) {
+ case '\\':
+ if (*(cp2 + 1)) {
+ *cp1++ = *++cp2;
+ }
+ break;
+ case '[':
+LOOP:
+ if (*++cp2 == '$' && isdigit(*(cp2+1))) {
+ if (*++cp2 == '0') {
+ char *cp3 = name;
+
+ while (*cp3) {
+ *cp1++ = *cp3++;
+ }
+ match = 1;
+ }
+ else if (toks[toknum = *cp2 - '1']) {
+ char *cp3 = tp[toknum];
+
+ while (cp3 != te[toknum]) {
+ *cp1++ = *cp3++;
+ }
+ match = 1;
+ }
+ }
+ else {
+ while (*cp2 && *cp2 != ',' &&
+ *cp2 != ']') {
+ if (*cp2 == '\\') {
+ cp2++;
+ }
+ else if (*cp2 == '$' &&
+ isdigit(*(cp2+1))) {
+ if (*++cp2 == '0') {
+ char *cp3 = name;
+
+ while (*cp3) {
+ *cp1++ = *cp3++;
+ }
+ }
+ else if (toks[toknum =
+ *cp2 - '1']) {
+ char *cp3=tp[toknum];
+
+ while (cp3 !=
+ te[toknum]) {
+ *cp1++ = *cp3++;
+ }
+ }
+ }
+ else if (*cp2) {
+ *cp1++ = *cp2++;
+ }
+ }
+ if (!*cp2) {
+ printf("nmap: unbalanced brackets\n");
+ return (name);
+ }
+ match = 1;
+ cp2--;
+ }
+ if (match) {
+ while (*++cp2 && *cp2 != ']') {
+ if (*cp2 == '\\' && *(cp2 + 1)) {
+ cp2++;
+ }
+ }
+ if (!*cp2) {
+ printf("nmap: unbalanced brackets\n");
+ return (name);
+ }
+ break;
+ }
+ switch (*++cp2) {
+ case ',':
+ goto LOOP;
+ case ']':
+ break;
+ default:
+ cp2--;
+ goto LOOP;
+ }
+ break;
+ case '$':
+ if (isdigit(*(cp2 + 1))) {
+ if (*++cp2 == '0') {
+ char *cp3 = name;
+
+ while (*cp3) {
+ *cp1++ = *cp3++;
+ }
+ }
+ else if (toks[toknum = *cp2 - '1']) {
+ char *cp3 = tp[toknum];
+
+ while (cp3 != te[toknum]) {
+ *cp1++ = *cp3++;
+ }
+ }
+ break;
+ }
+ /* intentional drop through */
+ default:
+ *cp1++ = *cp2;
+ break;
+ }
+ cp2++;
+ }
+ *cp1 = '\0';
+ if (!*new) {
+ return (name);
+ }
+ return (new);
+}
+
+void
+setpassive(int argc, char **argv)
+{
+
+ passivemode = !passivemode;
+ printf("Passive mode %s.\n", onoff(passivemode));
+ code = passivemode;
+}
+
+void
+setsunique(int argc, char **argv)
+{
+
+ sunique = !sunique;
+ printf("Store unique %s.\n", onoff(sunique));
+ code = sunique;
+}
+
+void
+setrunique(int argc, char **argv)
+{
+
+ runique = !runique;
+ printf("Receive unique %s.\n", onoff(runique));
+ code = runique;
+}
+
+/* change directory to perent directory */
+void
+cdup(int argc, char **argv)
+{
+
+ if (command("CDUP") == ERROR && code == 500) {
+ if (verbose)
+ printf("CDUP command not recognized, trying XCUP\n");
+ command("XCUP");
+ }
+}
+
+/* restart transfer at specific point */
+void
+restart(int argc, char **argv)
+{
+
+ if (argc != 2)
+ printf("restart: offset not specified\n");
+ else {
+ restart_point = atol(argv[1]);
+ printf("restarting at %ld. %s\n", (long)restart_point,
+ "execute get, put or append to initiate transfer");
+ }
+}
+
+/* show remote system type */
+void
+syst(int argc, char **argv)
+{
+
+ command("SYST");
+}
+
+void
+macdef(int argc, char **argv)
+{
+ char *tmp;
+ int c;
+
+ if (macnum == 16) {
+ printf("Limit of 16 macros have already been defined\n");
+ code = -1;
+ return;
+ }
+ if (argc < 2 && !another(&argc, &argv, "macro name")) {
+ printf("Usage: %s macro_name\n",argv[0]);
+ code = -1;
+ return;
+ }
+ if (interactive) {
+ printf("Enter macro line by line, terminating it with a null line\n");
+ }
+ strlcpy(macros[macnum].mac_name,
+ argv[1],
+ sizeof(macros[macnum].mac_name));
+ if (macnum == 0) {
+ macros[macnum].mac_start = macbuf;
+ }
+ else {
+ macros[macnum].mac_start = macros[macnum - 1].mac_end + 1;
+ }
+ tmp = macros[macnum].mac_start;
+ while (tmp != macbuf+4096) {
+ if ((c = getchar()) == EOF) {
+ printf("macdef:end of file encountered\n");
+ code = -1;
+ return;
+ }
+ if ((*tmp = c) == '\n') {
+ if (tmp == macros[macnum].mac_start) {
+ macros[macnum++].mac_end = tmp;
+ code = 0;
+ return;
+ }
+ if (*(tmp-1) == '\0') {
+ macros[macnum++].mac_end = tmp - 1;
+ code = 0;
+ return;
+ }
+ *tmp = '\0';
+ }
+ tmp++;
+ }
+ while (1) {
+ while ((c = getchar()) != '\n' && c != EOF)
+ /* LOOP */;
+ if (c == EOF || getchar() == '\n') {
+ printf("Macro not defined - 4k buffer exceeded\n");
+ code = -1;
+ return;
+ }
+ }
+}
+
+/*
+ * get size of file on remote machine
+ */
+void
+sizecmd(int argc, char **argv)
+{
+
+ if (argc < 2 && !another(&argc, &argv, "filename")) {
+ printf("usage: %s filename\n", argv[0]);
+ code = -1;
+ return;
+ }
+ command("SIZE %s", argv[1]);
+}
+
+/*
+ * get last modification time of file on remote machine
+ */
+void
+modtime(int argc, char **argv)
+{
+ int overbose;
+
+ if (argc < 2 && !another(&argc, &argv, "filename")) {
+ printf("usage: %s filename\n", argv[0]);
+ code = -1;
+ return;
+ }
+ overbose = verbose;
+ if (debug == 0)
+ verbose = -1;
+ if (command("MDTM %s", argv[1]) == COMPLETE) {
+ int yy, mo, day, hour, min, sec;
+ sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo,
+ &day, &hour, &min, &sec);
+ /* might want to print this in local time */
+ printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1],
+ mo, day, yy, hour, min, sec);
+ } else
+ printf("%s\n", reply_string);
+ verbose = overbose;
+}
+
+/*
+ * show status on reomte machine
+ */
+void
+rmtstatus(int argc, char **argv)
+{
+
+ command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
+}
+
+/*
+ * get file if modtime is more recent than current file
+ */
+void
+newer(int argc, char **argv)
+{
+
+ if (getit(argc, argv, -1, curtype == TYPE_I ? "wb" : "w"))
+ printf("Local file \"%s\" is newer than remote file \"%s\"\n",
+ argv[2], argv[1]);
+}
diff --git a/crypto/heimdal/appl/ftp/ftp/cmdtab.c b/crypto/heimdal/appl/ftp/ftp/cmdtab.c
new file mode 100644
index 000000000000..5dc96efa3672
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/cmdtab.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#include "ftp_locl.h"
+
+/*
+ * User FTP -- Command Tables.
+ */
+
+char accounthelp[] = "send account command to remote server";
+char appendhelp[] = "append to a file";
+char asciihelp[] = "set ascii transfer type";
+char beephelp[] = "beep when command completed";
+char binaryhelp[] = "set binary transfer type";
+char casehelp[] = "toggle mget upper/lower case id mapping";
+char cdhelp[] = "change remote working directory";
+char cduphelp[] = "change remote working directory to parent directory";
+char chmodhelp[] = "change file permissions of remote file";
+char connecthelp[] = "connect to remote tftp";
+char crhelp[] = "toggle carriage return stripping on ascii gets";
+char deletehelp[] = "delete remote file";
+char debughelp[] = "toggle/set debugging mode";
+char dirhelp[] = "list contents of remote directory";
+char disconhelp[] = "terminate ftp session";
+char domachelp[] = "execute macro";
+char formhelp[] = "set file transfer format";
+char globhelp[] = "toggle metacharacter expansion of local file names";
+char hashhelp[] = "toggle printing `#' for each buffer transferred";
+char helphelp[] = "print local help information";
+char idlehelp[] = "get (set) idle timer on remote side";
+char lcdhelp[] = "change local working directory";
+char lshelp[] = "list contents of remote directory";
+char macdefhelp[] = "define a macro";
+char mdeletehelp[] = "delete multiple files";
+char mdirhelp[] = "list contents of multiple remote directories";
+char mgethelp[] = "get multiple files";
+char mkdirhelp[] = "make directory on the remote machine";
+char mlshelp[] = "list contents of multiple remote directories";
+char modtimehelp[] = "show last modification time of remote file";
+char modehelp[] = "set file transfer mode";
+char mputhelp[] = "send multiple files";
+char newerhelp[] = "get file if remote file is newer than local file ";
+char nlisthelp[] = "nlist contents of remote directory";
+char nmaphelp[] = "set templates for default file name mapping";
+char ntranshelp[] = "set translation table for default file name mapping";
+char porthelp[] = "toggle use of PORT cmd for each data connection";
+char prompthelp[] = "force interactive prompting on multiple commands";
+char proxyhelp[] = "issue command on alternate connection";
+char pwdhelp[] = "print working directory on remote machine";
+char quithelp[] = "terminate ftp session and exit";
+char quotehelp[] = "send arbitrary ftp command";
+char receivehelp[] = "receive file";
+char regethelp[] = "get file restarting at end of local file";
+char remotehelp[] = "get help from remote server";
+char renamehelp[] = "rename file";
+char restarthelp[]= "restart file transfer at bytecount";
+char rmdirhelp[] = "remove directory on the remote machine";
+char rmtstatushelp[]="show status of remote machine";
+char runiquehelp[] = "toggle store unique for local files";
+char resethelp[] = "clear queued command replies";
+char sendhelp[] = "send one file";
+char passivehelp[] = "enter passive transfer mode";
+char sitehelp[] = "send site specific command to remote server\n\t\tTry \"rhelp site\" or \"site help\" for more information";
+char shellhelp[] = "escape to the shell";
+char sizecmdhelp[] = "show size of remote file";
+char statushelp[] = "show current status";
+char structhelp[] = "set file transfer structure";
+char suniquehelp[] = "toggle store unique on remote machine";
+char systemhelp[] = "show remote system type";
+char tenexhelp[] = "set tenex file transfer type";
+char tracehelp[] = "toggle packet tracing";
+char typehelp[] = "set file transfer type";
+char umaskhelp[] = "get (set) umask on remote side";
+char userhelp[] = "send new user information";
+char verbosehelp[] = "toggle verbose mode";
+
+char prothelp[] = "set protection level";
+#ifdef KRB4
+char kauthhelp[] = "get remote tokens";
+char klisthelp[] = "show remote tickets";
+char kdestroyhelp[] = "destroy remote tickets";
+char krbtkfilehelp[] = "set filename of remote tickets";
+char afsloghelp[] = "obtain remote AFS tokens";
+#endif
+
+struct cmd cmdtab[] = {
+ { "!", shellhelp, 0, 0, 0, shell },
+ { "$", domachelp, 1, 0, 0, domacro },
+ { "account", accounthelp, 0, 1, 1, account},
+ { "append", appendhelp, 1, 1, 1, put },
+ { "ascii", asciihelp, 0, 1, 1, setascii },
+ { "bell", beephelp, 0, 0, 0, setbell },
+ { "binary", binaryhelp, 0, 1, 1, setbinary },
+ { "bye", quithelp, 0, 0, 0, quit },
+ { "case", casehelp, 0, 0, 1, setcase },
+ { "cd", cdhelp, 0, 1, 1, cd },
+ { "cdup", cduphelp, 0, 1, 1, cdup },
+ { "chmod", chmodhelp, 0, 1, 1, do_chmod },
+ { "close", disconhelp, 0, 1, 1, disconnect },
+ { "cr", crhelp, 0, 0, 0, setcr },
+ { "delete", deletehelp, 0, 1, 1, delete },
+ { "debug", debughelp, 0, 0, 0, setdebug },
+ { "dir", dirhelp, 1, 1, 1, ls },
+ { "disconnect", disconhelp, 0, 1, 1, disconnect },
+ { "form", formhelp, 0, 1, 1, setform },
+ { "get", receivehelp, 1, 1, 1, get },
+ { "glob", globhelp, 0, 0, 0, setglob },
+ { "hash", hashhelp, 0, 0, 0, sethash },
+ { "help", helphelp, 0, 0, 1, help },
+ { "idle", idlehelp, 0, 1, 1, ftp_idle },
+ { "image", binaryhelp, 0, 1, 1, setbinary },
+ { "lcd", lcdhelp, 0, 0, 0, lcd },
+ { "ls", lshelp, 1, 1, 1, ls },
+ { "macdef", macdefhelp, 0, 0, 0, macdef },
+ { "mdelete", mdeletehelp, 1, 1, 1, mdelete },
+ { "mdir", mdirhelp, 1, 1, 1, mls },
+ { "mget", mgethelp, 1, 1, 1, mget },
+ { "mkdir", mkdirhelp, 0, 1, 1, makedir },
+ { "mls", mlshelp, 1, 1, 1, mls },
+ { "mode", modehelp, 0, 1, 1, setftmode },
+ { "modtime", modtimehelp, 0, 1, 1, modtime },
+ { "mput", mputhelp, 1, 1, 1, mput },
+ { "newer", newerhelp, 1, 1, 1, newer },
+ { "nmap", nmaphelp, 0, 0, 1, setnmap },
+ { "nlist", nlisthelp, 1, 1, 1, ls },
+ { "ntrans", ntranshelp, 0, 0, 1, setntrans },
+ { "open", connecthelp, 0, 0, 1, setpeer },
+ { "passive", passivehelp, 0, 0, 0, setpassive },
+ { "prompt", prompthelp, 0, 0, 0, setprompt },
+ { "proxy", proxyhelp, 0, 0, 1, doproxy },
+ { "sendport", porthelp, 0, 0, 0, setport },
+ { "put", sendhelp, 1, 1, 1, put },
+ { "pwd", pwdhelp, 0, 1, 1, pwd },
+ { "quit", quithelp, 0, 0, 0, quit },
+ { "quote", quotehelp, 1, 1, 1, quote },
+ { "recv", receivehelp, 1, 1, 1, get },
+ { "reget", regethelp, 1, 1, 1, reget },
+ { "rstatus", rmtstatushelp, 0, 1, 1, rmtstatus },
+ { "rhelp", remotehelp, 0, 1, 1, rmthelp },
+ { "rename", renamehelp, 0, 1, 1, renamefile },
+ { "reset", resethelp, 0, 1, 1, reset },
+ { "restart", restarthelp, 1, 1, 1, restart },
+ { "rmdir", rmdirhelp, 0, 1, 1, removedir },
+ { "runique", runiquehelp, 0, 0, 1, setrunique },
+ { "send", sendhelp, 1, 1, 1, put },
+ { "site", sitehelp, 0, 1, 1, site },
+ { "size", sizecmdhelp, 1, 1, 1, sizecmd },
+ { "status", statushelp, 0, 0, 1, status },
+ { "struct", structhelp, 0, 1, 1, setstruct },
+ { "system", systemhelp, 0, 1, 1, syst },
+ { "sunique", suniquehelp, 0, 0, 1, setsunique },
+ { "tenex", tenexhelp, 0, 1, 1, settenex },
+ { "trace", tracehelp, 0, 0, 0, settrace },
+ { "type", typehelp, 0, 1, 1, settype },
+ { "user", userhelp, 0, 1, 1, user },
+ { "umask", umaskhelp, 0, 1, 1, do_umask },
+ { "verbose", verbosehelp, 0, 0, 0, setverbose },
+ { "?", helphelp, 0, 0, 1, help },
+
+ { "prot", prothelp, 0, 1, 0, sec_prot },
+#ifdef KRB4
+ { "kauth", kauthhelp, 0, 1, 0, kauth },
+ { "klist", klisthelp, 0, 1, 0, klist },
+ { "kdestroy", kdestroyhelp, 0, 1, 0, kdestroy },
+ { "krbtkfile", krbtkfilehelp, 0, 1, 0, krbtkfile },
+ { "afslog", afsloghelp, 0, 1, 0, afslog },
+#endif
+
+ { 0 },
+};
+
+int NCMDS = (sizeof (cmdtab) / sizeof (cmdtab[0])) - 1;
diff --git a/crypto/heimdal/appl/ftp/ftp/domacro.c b/crypto/heimdal/appl/ftp/ftp/domacro.c
new file mode 100644
index 000000000000..d91660d0144d
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/domacro.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1985, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#include "ftp_locl.h"
+RCSID("$Id: domacro.c,v 1.7 1999/09/16 20:37:29 assar Exp $");
+
+void
+domacro(int argc, char **argv)
+{
+ int i, j, count = 2, loopflg = 0;
+ char *cp1, *cp2, line2[200];
+ struct cmd *c;
+
+ if (argc < 2 && !another(&argc, &argv, "macro name")) {
+ printf("Usage: %s macro_name.\n", argv[0]);
+ code = -1;
+ return;
+ }
+ for (i = 0; i < macnum; ++i) {
+ if (!strncmp(argv[1], macros[i].mac_name, 9)) {
+ break;
+ }
+ }
+ if (i == macnum) {
+ printf("'%s' macro not found.\n", argv[1]);
+ code = -1;
+ return;
+ }
+ strlcpy(line2, line, sizeof(line2));
+TOP:
+ cp1 = macros[i].mac_start;
+ while (cp1 != macros[i].mac_end) {
+ while (isspace(*cp1)) {
+ cp1++;
+ }
+ cp2 = line;
+ while (*cp1 != '\0') {
+ switch(*cp1) {
+ case '\\':
+ *cp2++ = *++cp1;
+ break;
+ case '$':
+ if (isdigit(*(cp1+1))) {
+ j = 0;
+ while (isdigit(*++cp1)) {
+ j = 10*j + *cp1 - '0';
+ }
+ cp1--;
+ if (argc - 2 >= j) {
+ strcpy(cp2, argv[j+1]);
+ cp2 += strlen(argv[j+1]);
+ }
+ break;
+ }
+ if (*(cp1+1) == 'i') {
+ loopflg = 1;
+ cp1++;
+ if (count < argc) {
+ strcpy(cp2, argv[count]);
+ cp2 += strlen(argv[count]);
+ }
+ break;
+ }
+ /* intentional drop through */
+ default:
+ *cp2++ = *cp1;
+ break;
+ }
+ if (*cp1 != '\0') {
+ cp1++;
+ }
+ }
+ *cp2 = '\0';
+ makeargv();
+ c = getcmd(margv[0]);
+ if (c == (struct cmd *)-1) {
+ printf("?Ambiguous command\n");
+ code = -1;
+ }
+ else if (c == 0) {
+ printf("?Invalid command\n");
+ code = -1;
+ }
+ else if (c->c_conn && !connected) {
+ printf("Not connected.\n");
+ code = -1;
+ }
+ else {
+ if (verbose) {
+ printf("%s\n",line);
+ }
+ (*c->c_handler)(margc, margv);
+ if (bell && c->c_bell) {
+ putchar('\007');
+ }
+ strcpy(line, line2);
+ makeargv();
+ argc = margc;
+ argv = margv;
+ }
+ if (cp1 != macros[i].mac_end) {
+ cp1++;
+ }
+ }
+ if (loopflg && ++count < argc) {
+ goto TOP;
+ }
+}
diff --git a/crypto/heimdal/appl/ftp/ftp/extern.h b/crypto/heimdal/appl/ftp/ftp/extern.h
new file mode 100644
index 000000000000..d488ecd96f98
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/extern.h
@@ -0,0 +1,173 @@
+/*-
+ * Copyright (c) 1994 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)extern.h 8.3 (Berkeley) 10/9/94
+ */
+
+/* $Id: extern.h,v 1.18 1999/10/28 20:49:10 assar Exp $ */
+
+#include <setjmp.h>
+#include <stdlib.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+void abort_remote (FILE *);
+void abortpt (int);
+void abortrecv (int);
+void account (int, char **);
+int another (int *, char ***, char *);
+void blkfree (char **);
+void cd (int, char **);
+void cdup (int, char **);
+void changetype (int, int);
+void cmdabort (int);
+void cmdscanner (int);
+int command (char *fmt, ...);
+int confirm (char *, char *);
+FILE *dataconn (const char *);
+void delete (int, char **);
+void disconnect (int, char **);
+void do_chmod (int, char **);
+void do_umask (int, char **);
+void domacro (int, char **);
+char *domap (char *);
+void doproxy (int, char **);
+char *dotrans (char *);
+int empty (fd_set *, int);
+void fatal (char *);
+void get (int, char **);
+struct cmd *getcmd (char *);
+int getit (int, char **, int, char *);
+int getreply (int);
+int globulize (char **);
+char *gunique (char *);
+void help (int, char **);
+char *hookup (const char *, int);
+void ftp_idle (int, char **);
+int initconn (void);
+void intr (int);
+void lcd (int, char **);
+int login (char *);
+RETSIGTYPE lostpeer (int);
+void ls (int, char **);
+void macdef (int, char **);
+void makeargv (void);
+void makedir (int, char **);
+void mdelete (int, char **);
+void mget (int, char **);
+void mls (int, char **);
+void modtime (int, char **);
+void mput (int, char **);
+char *onoff (int);
+void newer (int, char **);
+void proxtrans (char *, char *, char *);
+void psabort (int);
+void pswitch (int);
+void ptransfer (char *, long, struct timeval *, struct timeval *);
+void put (int, char **);
+void pwd (int, char **);
+void quit (int, char **);
+void quote (int, char **);
+void quote1 (char *, int, char **);
+void recvrequest (char *, char *, char *, char *, int, int);
+void reget (int, char **);
+char *remglob (char **, int);
+void removedir (int, char **);
+void renamefile (int, char **);
+void reset (int, char **);
+void restart (int, char **);
+void rmthelp (int, char **);
+void rmtstatus (int, char **);
+int ruserpass (char *, char **, char **, char **);
+void sendrequest (char *, char *, char *, char *, int);
+void setascii (int, char **);
+void setbell (int, char **);
+void setbinary (int, char **);
+void setcase (int, char **);
+void setcr (int, char **);
+void setdebug (int, char **);
+void setform (int, char **);
+void setftmode (int, char **);
+void setglob (int, char **);
+void sethash (int, char **);
+void setnmap (int, char **);
+void setntrans (int, char **);
+void setpassive (int, char **);
+void setpeer (int, char **);
+void setport (int, char **);
+void setprompt (int, char **);
+void setrunique (int, char **);
+void setstruct (int, char **);
+void setsunique (int, char **);
+void settenex (int, char **);
+void settrace (int, char **);
+void settype (int, char **);
+void setverbose (int, char **);
+void shell (int, char **);
+void site (int, char **);
+void sizecmd (int, char **);
+char *slurpstring (void);
+void status (int, char **);
+void syst (int, char **);
+void tvsub (struct timeval *, struct timeval *, struct timeval *);
+void user (int, char **);
+
+extern jmp_buf abortprox;
+extern int abrtflag;
+extern struct cmd cmdtab[];
+extern FILE *cout;
+extern int data;
+extern char *home;
+extern jmp_buf jabort;
+extern int proxy;
+extern char reply_string[];
+extern off_t restart_point;
+extern int NCMDS;
+
+extern char username[32];
+extern char myhostname[];
+extern char *mydomain;
+
+void afslog (int, char **);
+void kauth (int, char **);
+void kdestroy (int, char **);
+void klist (int, char **);
+void krbtkfile (int, char **);
diff --git a/crypto/heimdal/appl/ftp/ftp/ftp.1 b/crypto/heimdal/appl/ftp/ftp/ftp.1
new file mode 100644
index 000000000000..e5c21f096145
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/ftp.1
@@ -0,0 +1,1193 @@
+.\" $NetBSD: ftp.1,v 1.11 1995/09/08 01:06:24 tls Exp $
+.\"
+.\" Copyright (c) 1985, 1989, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. 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.
+.\"
+.\" @(#)ftp.1 8.3 (Berkeley) 10/9/94
+.\"
+.Dd April 27, 1996
+.Dt FTP 1
+.Os BSD 4.2
+.Sh NAME
+.Nm ftp
+.Nd
+.Tn ARPANET
+file transfer program
+.Sh SYNOPSIS
+.Nm ftp
+.Op Fl t
+.Op Fl v
+.Op Fl d
+.Op Fl i
+.Op Fl n
+.Op Fl g
+.Op Fl p
+.Op Ar host
+.Sh DESCRIPTION
+.Nm Ftp
+is the user interface to the
+.Tn ARPANET
+standard File Transfer Protocol.
+The program allows a user to transfer files to and from a
+remote network site.
+.Pp
+Modifications has been made so that it almost follows the ftpsec
+Internet draft.
+.Pp
+Options may be specified at the command line, or to the
+command interpreter.
+.Bl -tag -width flag
+.It Fl t
+Enables packet tracing.
+.It Fl v
+Verbose option forces
+.Nm ftp
+to show all responses from the remote server, as well
+as report on data transfer statistics.
+.It Fl n
+Restrains
+.Nm ftp
+from attempting \*(Lqauto-login\*(Rq upon initial connection.
+If auto-login is enabled,
+.Nm ftp
+will check the
+.Pa .netrc
+(see below) file in the user's home directory for an entry describing
+an account on the remote machine.
+If no entry exists,
+.Nm ftp
+will prompt for the remote machine login name (default is the user
+identity on the local machine), and, if necessary, prompt for a password
+and an account with which to login.
+.It Fl i
+Turns off interactive prompting during
+multiple file transfers.
+.It Fl p
+Turn on passive mode.
+.It Fl d
+Enables debugging.
+.It Fl g
+Disables file name globbing.
+.El
+.Pp
+The client host with which
+.Nm ftp
+is to communicate may be specified on the command line.
+If this is done,
+.Nm ftp
+will immediately attempt to establish a connection to an
+.Tn FTP
+server on that host; otherwise,
+.Nm ftp
+will enter its command interpreter and await instructions
+from the user.
+When
+.Nm ftp
+is awaiting commands from the user the prompt
+.Ql ftp>
+is provided to the user.
+The following commands are recognized
+by
+.Nm ftp :
+.Bl -tag -width Fl
+.It Ic \&! Op Ar command Op Ar args
+Invoke an interactive shell on the local machine.
+If there are arguments, the first is taken to be a command to execute
+directly, with the rest of the arguments as its arguments.
+.It Ic \&$ Ar macro-name Op Ar args
+Execute the macro
+.Ar macro-name
+that was defined with the
+.Ic macdef
+command.
+Arguments are passed to the macro unglobbed.
+.It Ic account Op Ar passwd
+Supply a supplemental password required by a remote system for access
+to resources once a login has been successfully completed.
+If no argument is included, the user will be prompted for an account
+password in a non-echoing input mode.
+.It Ic append Ar local-file Op Ar remote-file
+Append a local file to a file on the remote machine.
+If
+.Ar remote-file
+is left unspecified, the local file name is used in naming the
+remote file after being altered by any
+.Ic ntrans
+or
+.Ic nmap
+setting.
+File transfer uses the current settings for
+.Ic type ,
+.Ic format ,
+.Ic mode ,
+and
+.Ic structure .
+.It Ic ascii
+Set the file transfer
+.Ic type
+to network
+.Tn ASCII .
+This is the default type.
+.It Ic bell
+Arrange that a bell be sounded after each file transfer
+command is completed.
+.It Ic binary
+Set the file transfer
+.Ic type
+to support binary image transfer.
+.It Ic bye
+Terminate the
+.Tn FTP
+session with the remote server
+and exit
+.Nm ftp .
+An end of file will also terminate the session and exit.
+.It Ic case
+Toggle remote computer file name case mapping during
+.Ic mget
+commands.
+When
+.Ic case
+is on (default is off), remote computer file names with all letters in
+upper case are written in the local directory with the letters mapped
+to lower case.
+.It Ic \&cd Ar remote-directory
+Change the working directory on the remote machine
+to
+.Ar remote-directory .
+.It Ic cdup
+Change the remote machine working directory to the parent of the
+current remote machine working directory.
+.It Ic chmod Ar mode file-name
+Change the permission modes of the file
+.Ar file-name
+on the remote
+sytem to
+.Ar mode .
+.It Ic close
+Terminate the
+.Tn FTP
+session with the remote server, and
+return to the command interpreter.
+Any defined macros are erased.
+.It Ic \&cr
+Toggle carriage return stripping during
+ascii type file retrieval.
+Records are denoted by a carriage return/linefeed sequence
+during ascii type file transfer.
+When
+.Ic \&cr
+is on (the default), carriage returns are stripped from this
+sequence to conform with the
+.Ux
+single linefeed record
+delimiter.
+Records on
+.Pf non\- Ns Ux
+remote systems may contain single linefeeds;
+when an ascii type transfer is made, these linefeeds may be
+distinguished from a record delimiter only when
+.Ic \&cr
+is off.
+.It Ic delete Ar remote-file
+Delete the file
+.Ar remote-file
+on the remote machine.
+.It Ic debug Op Ar debug-value
+Toggle debugging mode.
+If an optional
+.Ar debug-value
+is specified it is used to set the debugging level.
+When debugging is on,
+.Nm ftp
+prints each command sent to the remote machine, preceded
+by the string
+.Ql \-\->
+.It Xo
+.Ic dir
+.Op Ar remote-directory
+.Op Ar local-file
+.Xc
+Print a listing of the directory contents in the
+directory,
+.Ar remote-directory ,
+and, optionally, placing the output in
+.Ar local-file .
+If interactive prompting is on,
+.Nm ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.Ic dir
+output.
+If no directory is specified, the current working
+directory on the remote machine is used.
+If no local
+file is specified, or
+.Ar local-file
+is
+.Fl ,
+output comes to the terminal.
+.It Ic disconnect
+A synonym for
+.Ar close .
+.It Ic form Ar format
+Set the file transfer
+.Ic form
+to
+.Ar format .
+The default format is \*(Lqfile\*(Rq.
+.It Ic get Ar remote-file Op Ar local-file
+Retrieve the
+.Ar remote-file
+and store it on the local machine.
+If the local
+file name is not specified, it is given the same
+name it has on the remote machine, subject to
+alteration by the current
+.Ic case ,
+.Ic ntrans ,
+and
+.Ic nmap
+settings.
+The current settings for
+.Ic type ,
+.Ic form ,
+.Ic mode ,
+and
+.Ic structure
+are used while transferring the file.
+.It Ic glob
+Toggle filename expansion for
+.Ic mdelete ,
+.Ic mget
+and
+.Ic mput .
+If globbing is turned off with
+.Ic glob ,
+the file name arguments
+are taken literally and not expanded.
+Globbing for
+.Ic mput
+is done as in
+.Xr csh 1 .
+For
+.Ic mdelete
+and
+.Ic mget ,
+each remote file name is expanded
+separately on the remote machine and the lists are not merged.
+Expansion of a directory name is likely to be
+different from expansion of the name of an ordinary file:
+the exact result depends on the foreign operating system and ftp server,
+and can be previewed by doing
+.Ql mls remote-files \- .
+As a security measure, remotely globbed files that starts with
+.Sq /
+or contains
+.Sq ../ ,
+will not be automatically received. If you have interactive prompting
+turned off, these filenames will be ignored. Note:
+.Ic mget
+and
+.Ic mput
+are not meant to transfer
+entire directory subtrees of files.
+That can be done by
+transferring a
+.Xr tar 1
+archive of the subtree (in binary mode).
+.It Ic hash
+Toggle hash-sign (``#'') printing for each data block
+transferred.
+The size of a data block is 1024 bytes.
+.It Ic help Op Ar command
+Print an informative message about the meaning of
+.Ar command .
+If no argument is given,
+.Nm ftp
+prints a list of the known commands.
+.It Ic idle Op Ar seconds
+Set the inactivity timer on the remote server to
+.Ar seconds
+seconds.
+If
+.Ar seconds
+is omitted, the current inactivity timer is printed.
+.It Ic lcd Op Ar directory
+Change the working directory on the local machine.
+If
+no
+.Ar directory
+is specified, the user's home directory is used.
+.It Xo
+.Ic \&ls
+.Op Ar remote-directory
+.Op Ar local-file
+.Xc
+Print a listing of the contents of a
+directory on the remote machine.
+The listing includes any system-dependent information that the server
+chooses to include; for example, most
+.Ux
+systems will produce
+output from the command
+.Ql ls \-l .
+(See also
+.Ic nlist . )
+If
+.Ar remote-directory
+is left unspecified, the current working directory is used.
+If interactive prompting is on,
+.Nm ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.Ic \&ls
+output.
+If no local file is specified, or if
+.Ar local-file
+is
+.Sq Fl ,
+the output is sent to the terminal.
+.It Ic macdef Ar macro-name
+Define a macro.
+Subsequent lines are stored as the macro
+.Ar macro-name ;
+a null line (consecutive newline characters
+in a file or
+carriage returns from the terminal) terminates macro input mode.
+There is a limit of 16 macros and 4096 total characters in all
+defined macros.
+Macros remain defined until a
+.Ic close
+command is executed.
+The macro processor interprets `$' and `\e' as special characters.
+A `$' followed by a number (or numbers) is replaced by the
+corresponding argument on the macro invocation command line.
+A `$' followed by an `i' signals that macro processor that the
+executing macro is to be looped.
+On the first pass `$i' is
+replaced by the first argument on the macro invocation command line,
+on the second pass it is replaced by the second argument, and so on.
+A `\e' followed by any character is replaced by that character.
+Use the `\e' to prevent special treatment of the `$'.
+.It Ic mdelete Op Ar remote-files
+Delete the
+.Ar remote-files
+on the remote machine.
+.It Ic mdir Ar remote-files local-file
+Like
+.Ic dir ,
+except multiple remote files may be specified.
+If interactive prompting is on,
+.Nm ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.Ic mdir
+output.
+.It Ic mget Ar remote-files
+Expand the
+.Ar remote-files
+on the remote machine
+and do a
+.Ic get
+for each file name thus produced.
+See
+.Ic glob
+for details on the filename expansion.
+Resulting file names will then be processed according to
+.Ic case ,
+.Ic ntrans ,
+and
+.Ic nmap
+settings.
+Files are transferred into the local working directory,
+which can be changed with
+.Ql lcd directory ;
+new local directories can be created with
+.Ql "\&! mkdir directory" .
+.It Ic mkdir Ar directory-name
+Make a directory on the remote machine.
+.It Ic mls Ar remote-files local-file
+Like
+.Ic nlist ,
+except multiple remote files may be specified,
+and the
+.Ar local-file
+must be specified.
+If interactive prompting is on,
+.Nm ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.Ic mls
+output.
+.It Ic mode Op Ar mode-name
+Set the file transfer
+.Ic mode
+to
+.Ar mode-name .
+The default mode is \*(Lqstream\*(Rq mode.
+.It Ic modtime Ar file-name
+Show the last modification time of the file on the remote machine.
+.It Ic mput Ar local-files
+Expand wild cards in the list of local files given as arguments
+and do a
+.Ic put
+for each file in the resulting list.
+See
+.Ic glob
+for details of filename expansion.
+Resulting file names will then be processed according to
+.Ic ntrans
+and
+.Ic nmap
+settings.
+.It Ic newer Ar file-name
+Get the file only if the modification time of the remote file is more
+recent that the file on the current system.
+If the file does not
+exist on the current system, the remote file is considered
+.Ic newer .
+Otherwise, this command is identical to
+.Ar get .
+.It Xo
+.Ic nlist
+.Op Ar remote-directory
+.Op Ar local-file
+.Xc
+Print a list of the files in a
+directory on the remote machine.
+If
+.Ar remote-directory
+is left unspecified, the current working directory is used.
+If interactive prompting is on,
+.Nm ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.Ic nlist
+output.
+If no local file is specified, or if
+.Ar local-file
+is
+.Fl ,
+the output is sent to the terminal.
+.It Ic nmap Op Ar inpattern outpattern
+Set or unset the filename mapping mechanism.
+If no arguments are specified, the filename mapping mechanism is unset.
+If arguments are specified, remote filenames are mapped during
+.Ic mput
+commands and
+.Ic put
+commands issued without a specified remote target filename.
+If arguments are specified, local filenames are mapped during
+.Ic mget
+commands and
+.Ic get
+commands issued without a specified local target filename.
+This command is useful when connecting to a
+.No non\- Ns Ux
+remote computer
+with different file naming conventions or practices.
+The mapping follows the pattern set by
+.Ar inpattern
+and
+.Ar outpattern .
+.Op Ar Inpattern
+is a template for incoming filenames (which may have already been
+processed according to the
+.Ic ntrans
+and
+.Ic case
+settings).
+Variable templating is accomplished by including the
+sequences `$1', `$2', ..., `$9' in
+.Ar inpattern .
+Use `\\' to prevent this special treatment of the `$' character.
+All other characters are treated literally, and are used to determine the
+.Ic nmap
+.Op Ar inpattern
+variable values.
+For example, given
+.Ar inpattern
+$1.$2 and the remote file name "mydata.data", $1 would have the value
+"mydata", and $2 would have the value "data".
+The
+.Ar outpattern
+determines the resulting mapped filename.
+The sequences `$1', `$2', ...., `$9' are replaced by any value resulting
+from the
+.Ar inpattern
+template.
+The sequence `$0' is replace by the original filename.
+Additionally, the sequence
+.Ql Op Ar seq1 , Ar seq2
+is replaced by
+.Op Ar seq1
+if
+.Ar seq1
+is not a null string; otherwise it is replaced by
+.Ar seq2 .
+For example, the command
+.Pp
+.Bd -literal -offset indent -compact
+nmap $1.$2.$3 [$1,$2].[$2,file]
+.Ed
+.Pp
+would yield
+the output filename "myfile.data" for input filenames "myfile.data" and
+"myfile.data.old", "myfile.file" for the input filename "myfile", and
+"myfile.myfile" for the input filename ".myfile".
+Spaces may be included in
+.Ar outpattern ,
+as in the example: `nmap $1 sed "s/ *$//" > $1' .
+Use the `\e' character to prevent special treatment
+of the `$','[','[', and `,' characters.
+.It Ic ntrans Op Ar inchars Op Ar outchars
+Set or unset the filename character translation mechanism.
+If no arguments are specified, the filename character
+translation mechanism is unset.
+If arguments are specified, characters in
+remote filenames are translated during
+.Ic mput
+commands and
+.Ic put
+commands issued without a specified remote target filename.
+If arguments are specified, characters in
+local filenames are translated during
+.Ic mget
+commands and
+.Ic get
+commands issued without a specified local target filename.
+This command is useful when connecting to a
+.No non\- Ns Ux
+remote computer
+with different file naming conventions or practices.
+Characters in a filename matching a character in
+.Ar inchars
+are replaced with the corresponding character in
+.Ar outchars .
+If the character's position in
+.Ar inchars
+is longer than the length of
+.Ar outchars ,
+the character is deleted from the file name.
+.It Ic open Ar host Op Ar port
+Establish a connection to the specified
+.Ar host
+.Tn FTP
+server.
+An optional port number may be supplied,
+in which case,
+.Nm ftp
+will attempt to contact an
+.Tn FTP
+server at that port.
+If the
+.Ic auto-login
+option is on (default),
+.Nm ftp
+will also attempt to automatically log the user in to
+the
+.Tn FTP
+server (see below).
+.It Ic passive
+Toggle passive mode. If passive mode is turned on
+(default is off), the ftp client will
+send a
+.Dv PASV
+command for all data connections instead of the usual
+.Dv PORT
+command. The
+.Dv PASV
+command requests that the remote server open a port for the data connection
+and return the address of that port. The remote server listens on that
+port and the client connects to it. When using the more traditional
+.Dv PORT
+command, the client listens on a port and sends that address to the remote
+server, who connects back to it. Passive mode is useful when using
+.Nm ftp
+through a gateway router or host that controls the directionality of
+traffic.
+(Note that though ftp servers are required to support the
+.Dv PASV
+command by RFC 1123, some do not.)
+.It Ic prompt
+Toggle interactive prompting.
+Interactive prompting
+occurs during multiple file transfers to allow the
+user to selectively retrieve or store files.
+If prompting is turned off (default is on), any
+.Ic mget
+or
+.Ic mput
+will transfer all files, and any
+.Ic mdelete
+will delete all files.
+.It Ic proxy Ar ftp-command
+Execute an ftp command on a secondary control connection.
+This command allows simultaneous connection to two remote ftp
+servers for transferring files between the two servers.
+The first
+.Ic proxy
+command should be an
+.Ic open ,
+to establish the secondary control connection.
+Enter the command "proxy ?" to see other ftp commands executable on the
+secondary connection.
+The following commands behave differently when prefaced by
+.Ic proxy :
+.Ic open
+will not define new macros during the auto-login process,
+.Ic close
+will not erase existing macro definitions,
+.Ic get
+and
+.Ic mget
+transfer files from the host on the primary control connection
+to the host on the secondary control connection, and
+.Ic put ,
+.Ic mput ,
+and
+.Ic append
+transfer files from the host on the secondary control connection
+to the host on the primary control connection.
+Third party file transfers depend upon support of the ftp protocol
+.Dv PASV
+command by the server on the secondary control connection.
+.It Ic put Ar local-file Op Ar remote-file
+Store a local file on the remote machine.
+If
+.Ar remote-file
+is left unspecified, the local file name is used
+after processing according to any
+.Ic ntrans
+or
+.Ic nmap
+settings
+in naming the remote file.
+File transfer uses the
+current settings for
+.Ic type ,
+.Ic format ,
+.Ic mode ,
+and
+.Ic structure .
+.It Ic pwd
+Print the name of the current working directory on the remote
+machine.
+.It Ic quit
+A synonym for
+.Ic bye .
+.It Ic quote Ar arg1 arg2 ...
+The arguments specified are sent, verbatim, to the remote
+.Tn FTP
+server.
+.It Ic recv Ar remote-file Op Ar local-file
+A synonym for get.
+.It Ic reget Ar remote-file Op Ar local-file
+Reget acts like get, except that if
+.Ar local-file
+exists and is
+smaller than
+.Ar remote-file ,
+.Ar local-file
+is presumed to be
+a partially transferred copy of
+.Ar remote-file
+and the transfer
+is continued from the apparent point of failure.
+This command
+is useful when transferring very large files over networks that
+are prone to dropping connections.
+.It Ic remotehelp Op Ar command-name
+Request help from the remote
+.Tn FTP
+server.
+If a
+.Ar command-name
+is specified it is supplied to the server as well.
+.It Ic remotestatus Op Ar file-name
+With no arguments, show status of remote machine.
+If
+.Ar file-name
+is specified, show status of
+.Ar file-name
+on remote machine.
+.It Xo
+.Ic rename
+.Op Ar from
+.Op Ar to
+.Xc
+Rename the file
+.Ar from
+on the remote machine, to the file
+.Ar to .
+.It Ic reset
+Clear reply queue.
+This command re-synchronizes command/reply sequencing with the remote
+ftp server.
+Resynchronization may be necessary following a violation of the ftp protocol
+by the remote server.
+.It Ic restart Ar marker
+Restart the immediately following
+.Ic get
+or
+.Ic put
+at the
+indicated
+.Ar marker .
+On
+.Ux
+systems, marker is usually a byte
+offset into the file.
+.It Ic rmdir Ar directory-name
+Delete a directory on the remote machine.
+.It Ic runique
+Toggle storing of files on the local system with unique filenames.
+If a file already exists with a name equal to the target
+local filename for a
+.Ic get
+or
+.Ic mget
+command, a ".1" is appended to the name.
+If the resulting name matches another existing file,
+a ".2" is appended to the original name.
+If this process continues up to ".99", an error
+message is printed, and the transfer does not take place.
+The generated unique filename will be reported.
+Note that
+.Ic runique
+will not affect local files generated from a shell command
+(see below).
+The default value is off.
+.It Ic send Ar local-file Op Ar remote-file
+A synonym for put.
+.It Ic sendport
+Toggle the use of
+.Dv PORT
+commands.
+By default,
+.Nm ftp
+will attempt to use a
+.Dv PORT
+command when establishing
+a connection for each data transfer.
+The use of
+.Dv PORT
+commands can prevent delays
+when performing multiple file transfers.
+If the
+.Dv PORT
+command fails,
+.Nm ftp
+will use the default data port.
+When the use of
+.Dv PORT
+commands is disabled, no attempt will be made to use
+.Dv PORT
+commands for each data transfer.
+This is useful
+for certain
+.Tn FTP
+implementations which do ignore
+.Dv PORT
+commands but, incorrectly, indicate they've been accepted.
+.It Ic site Ar arg1 arg2 ...
+The arguments specified are sent, verbatim, to the remote
+.Tn FTP
+server as a
+.Dv SITE
+command.
+.It Ic size Ar file-name
+Return size of
+.Ar file-name
+on remote machine.
+.It Ic status
+Show the current status of
+.Nm ftp .
+.It Ic struct Op Ar struct-name
+Set the file transfer
+.Ar structure
+to
+.Ar struct-name .
+By default \*(Lqstream\*(Rq structure is used.
+.It Ic sunique
+Toggle storing of files on remote machine under unique file names.
+Remote ftp server must support ftp protocol
+.Dv STOU
+command for
+successful completion.
+The remote server will report unique name.
+Default value is off.
+.It Ic system
+Show the type of operating system running on the remote machine.
+.It Ic tenex
+Set the file transfer type to that needed to
+talk to
+.Tn TENEX
+machines.
+.It Ic trace
+Toggle packet tracing.
+.It Ic type Op Ar type-name
+Set the file transfer
+.Ic type
+to
+.Ar type-name .
+If no type is specified, the current type
+is printed.
+The default type is network
+.Tn ASCII .
+.It Ic umask Op Ar newmask
+Set the default umask on the remote server to
+.Ar newmask .
+If
+.Ar newmask
+is omitted, the current umask is printed.
+.It Xo
+.Ic user Ar user-name
+.Op Ar password
+.Op Ar account
+.Xc
+Identify yourself to the remote
+.Tn FTP
+server.
+If the
+.Ar password
+is not specified and the server requires it,
+.Nm ftp
+will prompt the user for it (after disabling local echo).
+If an
+.Ar account
+field is not specified, and the
+.Tn FTP
+server
+requires it, the user will be prompted for it.
+If an
+.Ar account
+field is specified, an account command will
+be relayed to the remote server after the login sequence
+is completed if the remote server did not require it
+for logging in.
+Unless
+.Nm ftp
+is invoked with \*(Lqauto-login\*(Rq disabled, this
+process is done automatically on initial connection to
+the
+.Tn FTP
+server.
+.It Ic verbose
+Toggle verbose mode.
+In verbose mode, all responses from
+the
+.Tn FTP
+server are displayed to the user.
+In addition,
+if verbose is on, when a file transfer completes, statistics
+regarding the efficiency of the transfer are reported.
+By default,
+verbose is on.
+.It Ic ? Op Ar command
+A synonym for help.
+.El
+.Pp
+The following command can be used with ftpsec-aware servers.
+.Bl -tag -width Fl
+.It Xo
+.Ic prot
+.Ar clear |
+.Ar safe |
+.Ar confidential |
+.Ar private
+.Xc
+Set the data protection level to the requested level.
+.El
+.Pp
+The following command can be used with ftp servers that has
+implemented the KAUTH site command.
+.Bl -tag -width Fl
+.It Ic kauth Op Ar principal
+Obtain remote tickets.
+.El
+.Pp
+Command arguments which have embedded spaces may be quoted with
+quote `"' marks.
+.Sh ABORTING A FILE TRANSFER
+To abort a file transfer, use the terminal interrupt key
+(usually Ctrl-C).
+Sending transfers will be immediately halted.
+Receiving transfers will be halted by sending a ftp protocol
+.Dv ABOR
+command to the remote server, and discarding any further data received.
+The speed at which this is accomplished depends upon the remote
+server's support for
+.Dv ABOR
+processing.
+If the remote server does not support the
+.Dv ABOR
+command, an
+.Ql ftp>
+prompt will not appear until the remote server has completed
+sending the requested file.
+.Pp
+The terminal interrupt key sequence will be ignored when
+.Nm ftp
+has completed any local processing and is awaiting a reply
+from the remote server.
+A long delay in this mode may result from the ABOR processing described
+above, or from unexpected behavior by the remote server, including
+violations of the ftp protocol.
+If the delay results from unexpected remote server behavior, the local
+.Nm ftp
+program must be killed by hand.
+.Sh FILE NAMING CONVENTIONS
+Files specified as arguments to
+.Nm ftp
+commands are processed according to the following rules.
+.Bl -enum
+.It
+If the file name
+.Sq Fl
+is specified, the
+.Ar stdin
+(for reading) or
+.Ar stdout
+(for writing) is used.
+.It
+If the first character of the file name is
+.Sq \&| ,
+the
+remainder of the argument is interpreted as a shell command.
+.Nm Ftp
+then forks a shell, using
+.Xr popen 3
+with the argument supplied, and reads (writes) from the stdout
+(stdin).
+If the shell command includes spaces, the argument
+must be quoted; e.g.
+\*(Lq" ls -lt"\*(Rq.
+A particularly
+useful example of this mechanism is: \*(Lqdir more\*(Rq.
+.It
+Failing the above checks, if ``globbing'' is enabled,
+local file names are expanded
+according to the rules used in the
+.Xr csh 1 ;
+c.f. the
+.Ic glob
+command.
+If the
+.Nm ftp
+command expects a single local file (.e.g.
+.Ic put ) ,
+only the first filename generated by the "globbing" operation is used.
+.It
+For
+.Ic mget
+commands and
+.Ic get
+commands with unspecified local file names, the local filename is
+the remote filename, which may be altered by a
+.Ic case ,
+.Ic ntrans ,
+or
+.Ic nmap
+setting.
+The resulting filename may then be altered if
+.Ic runique
+is on.
+.It
+For
+.Ic mput
+commands and
+.Ic put
+commands with unspecified remote file names, the remote filename is
+the local filename, which may be altered by a
+.Ic ntrans
+or
+.Ic nmap
+setting.
+The resulting filename may then be altered by the remote server if
+.Ic sunique
+is on.
+.El
+.Sh FILE TRANSFER PARAMETERS
+The FTP specification specifies many parameters which may
+affect a file transfer.
+The
+.Ic type
+may be one of \*(Lqascii\*(Rq, \*(Lqimage\*(Rq (binary),
+\*(Lqebcdic\*(Rq, and \*(Lqlocal byte size\*(Rq (for
+.Tn PDP Ns -10's
+and
+.Tn PDP Ns -20's
+mostly).
+.Nm Ftp
+supports the ascii and image types of file transfer,
+plus local byte size 8 for
+.Ic tenex
+mode transfers.
+.Pp
+.Nm Ftp
+supports only the default values for the remaining
+file transfer parameters:
+.Ic mode ,
+.Ic form ,
+and
+.Ic struct .
+.Sh THE .netrc FILE
+The
+.Pa .netrc
+file contains login and initialization information
+used by the auto-login process.
+It resides in the user's home directory.
+The following tokens are recognized; they may be separated by spaces,
+tabs, or new-lines:
+.Bl -tag -width password
+.It Ic machine Ar name
+Identify a remote machine
+.Ar name .
+The auto-login process searches the
+.Pa .netrc
+file for a
+.Ic machine
+token that matches the remote machine specified on the
+.Nm ftp
+command line or as an
+.Ic open
+command argument.
+Once a match is made, the subsequent
+.Pa .netrc
+tokens are processed,
+stopping when the end of file is reached or another
+.Ic machine
+or a
+.Ic default
+token is encountered.
+.It Ic default
+This is the same as
+.Ic machine
+.Ar name
+except that
+.Ic default
+matches any name.
+There can be only one
+.Ic default
+token, and it must be after all
+.Ic machine
+tokens.
+This is normally used as:
+.Pp
+.Dl default login anonymous password user@site
+.Pp
+thereby giving the user
+.Ar automatic
+anonymous ftp login to
+machines not specified in
+.Pa .netrc .
+This can be overridden
+by using the
+.Fl n
+flag to disable auto-login.
+.It Ic login Ar name
+Identify a user on the remote machine.
+If this token is present, the auto-login process will initiate
+a login using the specified
+.Ar name .
+.It Ic password Ar string
+Supply a password.
+If this token is present, the auto-login process will supply the
+specified string if the remote server requires a password as part
+of the login process.
+Note that if this token is present in the
+.Pa .netrc
+file for any user other
+than
+.Ar anonymous ,
+.Nm ftp
+will abort the auto-login process if the
+.Pa .netrc
+is readable by
+anyone besides the user.
+.It Ic account Ar string
+Supply an additional account password.
+If this token is present, the auto-login process will supply the
+specified string if the remote server requires an additional
+account password, or the auto-login process will initiate an
+.Dv ACCT
+command if it does not.
+.It Ic macdef Ar name
+Define a macro.
+This token functions like the
+.Nm ftp
+.Ic macdef
+command functions.
+A macro is defined with the specified name; its contents begin with the
+next
+.Pa .netrc
+line and continue until a null line (consecutive new-line
+characters) is encountered.
+If a macro named
+.Ic init
+is defined, it is automatically executed as the last step in the
+auto-login process.
+.El
+.Sh ENVIRONMENT
+.Nm Ftp
+utilizes the following environment variables.
+.Bl -tag -width Fl
+.It Ev HOME
+For default location of a
+.Pa .netrc
+file, if one exists.
+.It Ev SHELL
+For default shell.
+.El
+.Sh SEE ALSO
+.Xr ftpd 8 ,
+.%T RFC2228
+.Sh HISTORY
+The
+.Nm ftp
+command appeared in
+.Bx 4.2 .
+.Sh BUGS
+Correct execution of many commands depends upon proper behavior
+by the remote server.
+.Pp
+An error in the treatment of carriage returns
+in the
+.Bx 4.2
+ascii-mode transfer code
+has been corrected.
+This correction may result in incorrect transfers of binary files
+to and from
+.Bx 4.2
+servers using the ascii type.
+Avoid this problem by using the binary image type.
diff --git a/crypto/heimdal/appl/ftp/ftp/ftp.c b/crypto/heimdal/appl/ftp/ftp/ftp.c
new file mode 100644
index 000000000000..2e7a9dd2b069
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/ftp.c
@@ -0,0 +1,1746 @@
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#include "ftp_locl.h"
+RCSID ("$Id: ftp.c,v 1.63 2000/01/08 07:43:47 assar Exp $");
+
+struct sockaddr_storage hisctladdr_ss;
+struct sockaddr *hisctladdr = (struct sockaddr *)&hisctladdr_ss;
+struct sockaddr_storage data_addr_ss;
+struct sockaddr *data_addr = (struct sockaddr *)&data_addr_ss;
+struct sockaddr_storage myctladdr_ss;
+struct sockaddr *myctladdr = (struct sockaddr *)&myctladdr_ss;
+int data = -1;
+int abrtflag = 0;
+jmp_buf ptabort;
+int ptabflg;
+int ptflag = 0;
+off_t restart_point = 0;
+
+
+FILE *cin, *cout;
+
+typedef void (*sighand) (int);
+
+char *
+hookup (const char *host, int port)
+{
+ static char hostnamebuf[MaxHostNameLen];
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char portstr[NI_MAXSERV];
+ int len;
+ int s;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_flags = AI_CANONNAME;
+
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(port));
+
+ error = getaddrinfo (host, portstr, &hints, &ai);
+ if (error) {
+ warnx ("%s: %s", host, gai_strerror(error));
+ code = -1;
+ return NULL;
+ }
+ strlcpy (hostnamebuf, host, sizeof(hostnamebuf));
+ hostname = hostnamebuf;
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0)
+ continue;
+
+ if (a->ai_canonname != NULL)
+ strlcpy (hostnamebuf, a->ai_canonname, sizeof(hostnamebuf));
+
+ memcpy (hisctladdr, a->ai_addr, a->ai_addrlen);
+
+ error = connect (s, a->ai_addr, a->ai_addrlen);
+ if (error < 0) {
+ char addrstr[256];
+
+ if (getnameinfo (a->ai_addr, a->ai_addrlen,
+ addrstr, sizeof(addrstr),
+ NULL, 0, NI_NUMERICHOST) != 0)
+ strlcpy (addrstr, "unknown address", sizeof(addrstr));
+
+ warn ("connect %s", addrstr);
+ close (s);
+ continue;
+ }
+ break;
+ }
+ freeaddrinfo (ai);
+ if (error < 0) {
+ warnx ("failed to contact %s", host);
+ code = -1;
+ return NULL;
+ }
+
+ len = sizeof(myctladdr_ss);
+ if (getsockname (s, myctladdr, &len) < 0) {
+ warn ("getsockname");
+ code = -1;
+ close (s);
+ return NULL;
+ }
+#ifdef IPTOS_LOWDELAY
+ socket_set_tos (s, IPTOS_LOWDELAY);
+#endif
+ cin = fdopen (s, "r");
+ cout = fdopen (s, "w");
+ if (cin == NULL || cout == NULL) {
+ warnx ("fdopen failed.");
+ if (cin)
+ fclose (cin);
+ if (cout)
+ fclose (cout);
+ code = -1;
+ goto bad;
+ }
+ if (verbose)
+ printf ("Connected to %s.\n", hostname);
+ if (getreply (0) > 2) { /* read startup message from server */
+ if (cin)
+ fclose (cin);
+ if (cout)
+ fclose (cout);
+ code = -1;
+ goto bad;
+ }
+#if defined(SO_OOBINLINE) && defined(HAVE_SETSOCKOPT)
+ {
+ int on = 1;
+
+ if (setsockopt (s, SOL_SOCKET, SO_OOBINLINE, (char *) &on, sizeof (on))
+ < 0 && debug) {
+ warn ("setsockopt");
+ }
+ }
+#endif /* SO_OOBINLINE */
+
+ return (hostname);
+bad:
+ close (s);
+ return NULL;
+}
+
+int
+login (char *host)
+{
+ char tmp[80];
+ char defaultpass[128];
+ char *user, *pass, *acct;
+ int n, aflag = 0;
+
+ char *myname = NULL;
+ struct passwd *pw = k_getpwuid(getuid());
+
+ if (pw != NULL)
+ myname = pw->pw_name;
+
+ user = pass = acct = 0;
+
+ if(sec_login(host))
+ printf("\n*** Using plaintext user and password ***\n\n");
+ else{
+ printf("Authentication successful.\n\n");
+ }
+
+ if (ruserpass (host, &user, &pass, &acct) < 0) {
+ code = -1;
+ return (0);
+ }
+ while (user == NULL) {
+ if (myname)
+ printf ("Name (%s:%s): ", host, myname);
+ else
+ printf ("Name (%s): ", host);
+ fgets (tmp, sizeof (tmp) - 1, stdin);
+ tmp[strlen (tmp) - 1] = '\0';
+ if (*tmp == '\0')
+ user = myname;
+ else
+ user = tmp;
+ }
+ strlcpy(username, user, sizeof(username));
+ n = command("USER %s", user);
+ if (n == CONTINUE) {
+ if(sec_complete)
+ pass = myname;
+ else if (pass == NULL) {
+ char prompt[128];
+ if(myname &&
+ (!strcmp(user, "ftp") || !strcmp(user, "anonymous"))){
+ snprintf(defaultpass, sizeof(defaultpass),
+ "%s@%s", myname, mydomain);
+ snprintf(prompt, sizeof(prompt),
+ "Password (%s): ", defaultpass);
+ }else{
+ *defaultpass = '\0';
+ snprintf(prompt, sizeof(prompt), "Password: ");
+ }
+ pass = defaultpass;
+ des_read_pw_string (tmp, sizeof (tmp), prompt, 0);
+ if (tmp[0])
+ pass = tmp;
+ }
+ n = command ("PASS %s", pass);
+ }
+ if (n == CONTINUE) {
+ aflag++;
+ acct = tmp;
+ des_read_pw_string (acct, 128, "Account:", 0);
+ n = command ("ACCT %s", acct);
+ }
+ if (n != COMPLETE) {
+ warnx ("Login failed.");
+ return (0);
+ }
+ if (!aflag && acct != NULL)
+ command ("ACCT %s", acct);
+ if (proxy)
+ return (1);
+ for (n = 0; n < macnum; ++n) {
+ if (!strcmp("init", macros[n].mac_name)) {
+ strlcpy (line, "$init", sizeof (line));
+ makeargv();
+ domacro(margc, margv);
+ break;
+ }
+ }
+ sec_set_protection_level ();
+ return (1);
+}
+
+void
+cmdabort (int sig)
+{
+
+ printf ("\n");
+ fflush (stdout);
+ abrtflag++;
+ if (ptflag)
+ longjmp (ptabort, 1);
+}
+
+int
+command (char *fmt,...)
+{
+ va_list ap;
+ int r;
+ sighand oldintr;
+
+ abrtflag = 0;
+ if (cout == NULL) {
+ warn ("No control connection for command");
+ code = -1;
+ return (0);
+ }
+ oldintr = signal(SIGINT, cmdabort);
+ va_start(ap, fmt);
+ if(debug){
+ printf("---> ");
+ if (strncmp("PASS ", fmt, 5) == 0)
+ printf("PASS XXXX");
+ else
+ vfprintf(stdout, fmt, ap);
+ va_start(ap, fmt);
+ }
+ sec_vfprintf(cout, fmt, ap);
+ va_end(ap);
+ if(debug){
+ printf("\n");
+ fflush(stdout);
+ }
+ fprintf (cout, "\r\n");
+ fflush (cout);
+ cpend = 1;
+ r = getreply (!strcmp (fmt, "QUIT"));
+ if (abrtflag && oldintr != SIG_IGN)
+ (*oldintr) (SIGINT);
+ signal (SIGINT, oldintr);
+ return (r);
+}
+
+char reply_string[BUFSIZ]; /* last line of previous reply */
+
+int
+getreply (int expecteof)
+{
+ char *p;
+ char *lead_string;
+ int c;
+ struct sigaction sa, osa;
+ char buf[1024];
+
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = cmdabort;
+ sigaction (SIGINT, &sa, &osa);
+
+ p = buf;
+
+ while (1) {
+ c = getc (cin);
+ switch (c) {
+ case EOF:
+ if (expecteof) {
+ sigaction (SIGINT, &osa, NULL);
+ code = 221;
+ return 0;
+ }
+ lostpeer (0);
+ if (verbose) {
+ printf ("421 Service not available, "
+ "remote server has closed connection\n");
+ fflush (stdout);
+ }
+ code = 421;
+ return (4);
+ case IAC:
+ c = getc (cin);
+ if (c == WILL || c == WONT)
+ fprintf (cout, "%c%c%c", IAC, DONT, getc (cin));
+ if (c == DO || c == DONT)
+ fprintf (cout, "%c%c%c", IAC, WONT, getc (cin));
+ continue;
+ case '\n':
+ *p++ = '\0';
+ if(isdigit(buf[0])){
+ sscanf(buf, "%d", &code);
+ if(code == 631){
+ sec_read_msg(buf, prot_safe);
+ sscanf(buf, "%d", &code);
+ lead_string = "S:";
+ } else if(code == 632){
+ sec_read_msg(buf, prot_private);
+ sscanf(buf, "%d", &code);
+ lead_string = "P:";
+ }else if(code == 633){
+ sec_read_msg(buf, prot_confidential);
+ sscanf(buf, "%d", &code);
+ lead_string = "C:";
+ }else if(sec_complete)
+ lead_string = "!!";
+ else
+ lead_string = "";
+ if (verbose > 0 || (verbose > -1 && code > 499))
+ fprintf (stdout, "%s%s\n", lead_string, buf);
+ if (buf[3] == ' ') {
+ strcpy (reply_string, buf);
+ if (code >= 200)
+ cpend = 0;
+ sigaction (SIGINT, &osa, NULL);
+ if (code == 421)
+ lostpeer (0);
+#if 1
+ if (abrtflag &&
+ osa.sa_handler != cmdabort &&
+ osa.sa_handler != SIG_IGN)
+ osa.sa_handler (SIGINT);
+#endif
+ if (code == 227 || code == 229) {
+ char *p, *q;
+
+ pasv[0] = 0;
+ p = strchr (reply_string, '(');
+ if (p) {
+ p++;
+ q = strchr(p, ')');
+ if(q){
+ memcpy (pasv, p, q - p);
+ pasv[q - p] = 0;
+ }
+ }
+ }
+ return code / 100;
+ }
+ }else{
+ if(verbose > 0 || (verbose > -1 && code > 499)){
+ if(sec_complete)
+ fprintf(stdout, "!!");
+ fprintf(stdout, "%s\n", buf);
+ }
+ }
+ p = buf;
+ continue;
+ default:
+ *p++ = c;
+ }
+ }
+
+}
+
+
+#if 0
+int
+getreply (int expecteof)
+{
+ int c, n;
+ int dig;
+ int originalcode = 0, continuation = 0;
+ sighand oldintr;
+ int pflag = 0;
+ char *cp, *pt = pasv;
+
+ oldintr = signal (SIGINT, cmdabort);
+ for (;;) {
+ dig = n = code = 0;
+ cp = reply_string;
+ while ((c = getc (cin)) != '\n') {
+ if (c == IAC) { /* handle telnet commands */
+ switch (c = getc (cin)) {
+ case WILL:
+ case WONT:
+ c = getc (cin);
+ fprintf (cout, "%c%c%c", IAC, DONT, c);
+ fflush (cout);
+ break;
+ case DO:
+ case DONT:
+ c = getc (cin);
+ fprintf (cout, "%c%c%c", IAC, WONT, c);
+ fflush (cout);
+ break;
+ default:
+ break;
+ }
+ continue;
+ }
+ dig++;
+ if (c == EOF) {
+ if (expecteof) {
+ signal (SIGINT, oldintr);
+ code = 221;
+ return (0);
+ }
+ lostpeer (0);
+ if (verbose) {
+ printf ("421 Service not available, remote server has closed connection\n");
+ fflush (stdout);
+ }
+ code = 421;
+ return (4);
+ }
+ if (c != '\r' && (verbose > 0 ||
+ (verbose > -1 && n == '5' && dig > 4))) {
+ if (proxflag &&
+ (dig == 1 || dig == 5 && verbose == 0))
+ printf ("%s:", hostname);
+ putchar (c);
+ }
+ if (dig < 4 && isdigit (c))
+ code = code * 10 + (c - '0');
+ if (!pflag && code == 227)
+ pflag = 1;
+ if (dig > 4 && pflag == 1 && isdigit (c))
+ pflag = 2;
+ if (pflag == 2) {
+ if (c != '\r' && c != ')')
+ *pt++ = c;
+ else {
+ *pt = '\0';
+ pflag = 3;
+ }
+ }
+ if (dig == 4 && c == '-') {
+ if (continuation)
+ code = 0;
+ continuation++;
+ }
+ if (n == 0)
+ n = c;
+ if (cp < &reply_string[sizeof (reply_string) - 1])
+ *cp++ = c;
+ }
+ if (verbose > 0 || verbose > -1 && n == '5') {
+ putchar (c);
+ fflush (stdout);
+ }
+ if (continuation && code != originalcode) {
+ if (originalcode == 0)
+ originalcode = code;
+ continue;
+ }
+ *cp = '\0';
+ if(sec_complete){
+ if(code == 631)
+ sec_read_msg(reply_string, prot_safe);
+ else if(code == 632)
+ sec_read_msg(reply_string, prot_private);
+ else if(code == 633)
+ sec_read_msg(reply_string, prot_confidential);
+ n = code / 100 + '0';
+ }
+ if (n != '1')
+ cpend = 0;
+ signal (SIGINT, oldintr);
+ if (code == 421 || originalcode == 421)
+ lostpeer (0);
+ if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
+ (*oldintr) (SIGINT);
+ return (n - '0');
+ }
+}
+
+#endif
+
+int
+empty (fd_set * mask, int sec)
+{
+ struct timeval t;
+
+ t.tv_sec = (long) sec;
+ t.tv_usec = 0;
+ return (select (32, mask, NULL, NULL, &t));
+}
+
+jmp_buf sendabort;
+
+static RETSIGTYPE
+abortsend (int sig)
+{
+
+ mflag = 0;
+ abrtflag = 0;
+ printf ("\nsend aborted\nwaiting for remote to finish abort\n");
+ fflush (stdout);
+ longjmp (sendabort, 1);
+}
+
+#define HASHBYTES 1024
+
+static int
+copy_stream (FILE * from, FILE * to)
+{
+ static size_t bufsize;
+ static char *buf;
+ int n;
+ int bytes = 0;
+ int werr = 0;
+ int hashbytes = HASHBYTES;
+ struct stat st;
+
+#if defined(HAVE_MMAP) && !defined(NO_MMAP)
+ void *chunk;
+
+#ifndef MAP_FAILED
+#define MAP_FAILED (-1)
+#endif
+
+ if (fstat (fileno (from), &st) == 0 && S_ISREG (st.st_mode)) {
+ /*
+ * mmap zero bytes has potential of loosing, don't do it.
+ */
+ if (st.st_size == 0)
+ return 0;
+ chunk = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fileno (from), 0);
+ if (chunk != (void *) MAP_FAILED) {
+ int res;
+
+ res = sec_write (fileno (to), chunk, st.st_size);
+ if (munmap (chunk, st.st_size) < 0)
+ warn ("munmap");
+ sec_fflush (to);
+ return res;
+ }
+ }
+#endif
+
+ buf = alloc_buffer (buf, &bufsize,
+ fstat (fileno (from), &st) >= 0 ? &st : NULL);
+ if (buf == NULL)
+ return -1;
+
+ while ((n = read (fileno (from), buf, bufsize)) > 0) {
+ werr = sec_write (fileno (to), buf, n);
+ if (werr < 0)
+ break;
+ bytes += werr;
+ while (hash && bytes > hashbytes) {
+ putchar ('#');
+ hashbytes += HASHBYTES;
+ }
+ }
+ sec_fflush (to);
+ if (n < 0)
+ warn ("local");
+
+ if (werr < 0) {
+ if (errno != EPIPE)
+ warn ("netout");
+ bytes = -1;
+ }
+ return bytes;
+}
+
+void
+sendrequest (char *cmd, char *local, char *remote, char *lmode, int printnames)
+{
+ struct stat st;
+ struct timeval start, stop;
+ int c, d;
+ FILE *fin, *dout = 0;
+ int (*closefunc) (FILE *);
+ RETSIGTYPE (*oldintr)(), (*oldintp)();
+ long bytes = 0, hashbytes = HASHBYTES;
+ char *rmode = "w";
+
+ if (verbose && printnames) {
+ if (local && strcmp (local, "-") != 0)
+ printf ("local: %s ", local);
+ if (remote)
+ printf ("remote: %s\n", remote);
+ }
+ if (proxy) {
+ proxtrans (cmd, local, remote);
+ return;
+ }
+ if (curtype != type)
+ changetype (type, 0);
+ closefunc = NULL;
+ oldintr = NULL;
+ oldintp = NULL;
+
+ if (setjmp (sendabort)) {
+ while (cpend) {
+ getreply (0);
+ }
+ if (data >= 0) {
+ close (data);
+ data = -1;
+ }
+ if (oldintr)
+ signal (SIGINT, oldintr);
+ if (oldintp)
+ signal (SIGPIPE, oldintp);
+ code = -1;
+ return;
+ }
+ oldintr = signal (SIGINT, abortsend);
+ if (strcmp (local, "-") == 0)
+ fin = stdin;
+ else if (*local == '|') {
+ oldintp = signal (SIGPIPE, SIG_IGN);
+ fin = popen (local + 1, lmode);
+ if (fin == NULL) {
+ warn ("%s", local + 1);
+ signal (SIGINT, oldintr);
+ signal (SIGPIPE, oldintp);
+ code = -1;
+ return;
+ }
+ closefunc = pclose;
+ } else {
+ fin = fopen (local, lmode);
+ if (fin == NULL) {
+ warn ("local: %s", local);
+ signal (SIGINT, oldintr);
+ code = -1;
+ return;
+ }
+ closefunc = fclose;
+ if (fstat (fileno (fin), &st) < 0 ||
+ (st.st_mode & S_IFMT) != S_IFREG) {
+ fprintf (stdout, "%s: not a plain file.\n", local);
+ signal (SIGINT, oldintr);
+ fclose (fin);
+ code = -1;
+ return;
+ }
+ }
+ if (initconn ()) {
+ signal (SIGINT, oldintr);
+ if (oldintp)
+ signal (SIGPIPE, oldintp);
+ code = -1;
+ if (closefunc != NULL)
+ (*closefunc) (fin);
+ return;
+ }
+ if (setjmp (sendabort))
+ goto abort;
+
+ if (restart_point &&
+ (strcmp (cmd, "STOR") == 0 || strcmp (cmd, "APPE") == 0)) {
+ int rc;
+
+ switch (curtype) {
+ case TYPE_A:
+ rc = fseek (fin, (long) restart_point, SEEK_SET);
+ break;
+ case TYPE_I:
+ case TYPE_L:
+ rc = lseek (fileno (fin), restart_point, SEEK_SET);
+ break;
+ }
+ if (rc < 0) {
+ warn ("local: %s", local);
+ restart_point = 0;
+ if (closefunc != NULL)
+ (*closefunc) (fin);
+ return;
+ }
+ if (command ("REST %ld", (long) restart_point)
+ != CONTINUE) {
+ restart_point = 0;
+ if (closefunc != NULL)
+ (*closefunc) (fin);
+ return;
+ }
+ restart_point = 0;
+ rmode = "r+w";
+ }
+ if (remote) {
+ if (command ("%s %s", cmd, remote) != PRELIM) {
+ signal (SIGINT, oldintr);
+ if (oldintp)
+ signal (SIGPIPE, oldintp);
+ if (closefunc != NULL)
+ (*closefunc) (fin);
+ return;
+ }
+ } else if (command ("%s", cmd) != PRELIM) {
+ signal(SIGINT, oldintr);
+ if (oldintp)
+ signal(SIGPIPE, oldintp);
+ if (closefunc != NULL)
+ (*closefunc)(fin);
+ return;
+ }
+ dout = dataconn(rmode);
+ if (dout == NULL)
+ goto abort;
+ set_buffer_size (fileno (dout), 0);
+ gettimeofday (&start, (struct timezone *) 0);
+ oldintp = signal (SIGPIPE, SIG_IGN);
+ switch (curtype) {
+
+ case TYPE_I:
+ case TYPE_L:
+ errno = d = c = 0;
+ bytes = copy_stream (fin, dout);
+ break;
+
+ case TYPE_A:
+ while ((c = getc (fin)) != EOF) {
+ if (c == '\n') {
+ while (hash && (bytes >= hashbytes)) {
+ putchar ('#');
+ fflush (stdout);
+ hashbytes += HASHBYTES;
+ }
+ if (ferror (dout))
+ break;
+ sec_putc ('\r', dout);
+ bytes++;
+ }
+ sec_putc (c, dout);
+ bytes++;
+ }
+ sec_fflush (dout);
+ if (hash) {
+ if (bytes < hashbytes)
+ putchar ('#');
+ putchar ('\n');
+ fflush (stdout);
+ }
+ if (ferror (fin))
+ warn ("local: %s", local);
+ if (ferror (dout)) {
+ if (errno != EPIPE)
+ warn ("netout");
+ bytes = -1;
+ }
+ break;
+ }
+ if (closefunc != NULL)
+ (*closefunc) (fin);
+ fclose (dout);
+ gettimeofday (&stop, (struct timezone *) 0);
+ getreply (0);
+ signal (SIGINT, oldintr);
+ if (oldintp)
+ signal (SIGPIPE, oldintp);
+ if (bytes > 0)
+ ptransfer ("sent", bytes, &start, &stop);
+ return;
+abort:
+ signal (SIGINT, oldintr);
+ if (oldintp)
+ signal (SIGPIPE, oldintp);
+ if (!cpend) {
+ code = -1;
+ return;
+ }
+ if (data >= 0) {
+ close (data);
+ data = -1;
+ }
+ if (dout)
+ fclose (dout);
+ getreply (0);
+ code = -1;
+ if (closefunc != NULL && fin != NULL)
+ (*closefunc) (fin);
+ gettimeofday (&stop, (struct timezone *) 0);
+ if (bytes > 0)
+ ptransfer ("sent", bytes, &start, &stop);
+}
+
+jmp_buf recvabort;
+
+void
+abortrecv (int sig)
+{
+
+ mflag = 0;
+ abrtflag = 0;
+ printf ("\nreceive aborted\nwaiting for remote to finish abort\n");
+ fflush (stdout);
+ longjmp (recvabort, 1);
+}
+
+void
+recvrequest (char *cmd, char *local, char *remote,
+ char *lmode, int printnames, int local_given)
+{
+ FILE *fout, *din = 0;
+ int (*closefunc) (FILE *);
+ sighand oldintr, oldintp;
+ int c, d, is_retr, tcrflag, bare_lfs = 0;
+ static size_t bufsize;
+ static char *buf;
+ long bytes = 0, hashbytes = HASHBYTES;
+ struct timeval start, stop;
+ struct stat st;
+
+ is_retr = strcmp (cmd, "RETR") == 0;
+ if (is_retr && verbose && printnames) {
+ if (local && strcmp (local, "-") != 0)
+ printf ("local: %s ", local);
+ if (remote)
+ printf ("remote: %s\n", remote);
+ }
+ if (proxy && is_retr) {
+ proxtrans (cmd, local, remote);
+ return;
+ }
+ closefunc = NULL;
+ oldintr = NULL;
+ oldintp = NULL;
+ tcrflag = !crflag && is_retr;
+ if (setjmp (recvabort)) {
+ while (cpend) {
+ getreply (0);
+ }
+ if (data >= 0) {
+ close (data);
+ data = -1;
+ }
+ if (oldintr)
+ signal (SIGINT, oldintr);
+ code = -1;
+ return;
+ }
+ oldintr = signal (SIGINT, abortrecv);
+ if (!local_given || (strcmp (local, "-") && *local != '|')) {
+ if (access (local, 2) < 0) {
+ char *dir = strrchr (local, '/');
+
+ if (errno != ENOENT && errno != EACCES) {
+ warn ("local: %s", local);
+ signal (SIGINT, oldintr);
+ code = -1;
+ return;
+ }
+ if (dir != NULL)
+ *dir = 0;
+ d = access (dir ? local : ".", 2);
+ if (dir != NULL)
+ *dir = '/';
+ if (d < 0) {
+ warn ("local: %s", local);
+ signal (SIGINT, oldintr);
+ code = -1;
+ return;
+ }
+ if (!runique && errno == EACCES &&
+ chmod (local, 0600) < 0) {
+ warn ("local: %s", local);
+ signal (SIGINT, oldintr);
+ signal (SIGINT, oldintr);
+ code = -1;
+ return;
+ }
+ if (runique && errno == EACCES &&
+ (local = gunique (local)) == NULL) {
+ signal (SIGINT, oldintr);
+ code = -1;
+ return;
+ }
+ } else if (runique && (local = gunique (local)) == NULL) {
+ signal(SIGINT, oldintr);
+ code = -1;
+ return;
+ }
+ }
+ if (!is_retr) {
+ if (curtype != TYPE_A)
+ changetype (TYPE_A, 0);
+ } else if (curtype != type)
+ changetype (type, 0);
+ if (initconn ()) {
+ signal (SIGINT, oldintr);
+ code = -1;
+ return;
+ }
+ if (setjmp (recvabort))
+ goto abort;
+ if (is_retr && restart_point &&
+ command ("REST %ld", (long) restart_point) != CONTINUE)
+ return;
+ if (remote) {
+ if (command ("%s %s", cmd, remote) != PRELIM) {
+ signal (SIGINT, oldintr);
+ return;
+ }
+ } else {
+ if (command ("%s", cmd) != PRELIM) {
+ signal (SIGINT, oldintr);
+ return;
+ }
+ }
+ din = dataconn ("r");
+ if (din == NULL)
+ goto abort;
+ set_buffer_size (fileno (din), 1);
+ if (local_given && strcmp (local, "-") == 0)
+ fout = stdout;
+ else if (local_given && *local == '|') {
+ oldintp = signal (SIGPIPE, SIG_IGN);
+ fout = popen (local + 1, "w");
+ if (fout == NULL) {
+ warn ("%s", local + 1);
+ goto abort;
+ }
+ closefunc = pclose;
+ } else {
+ fout = fopen (local, lmode);
+ if (fout == NULL) {
+ warn ("local: %s", local);
+ goto abort;
+ }
+ closefunc = fclose;
+ }
+ buf = alloc_buffer (buf, &bufsize,
+ fstat (fileno (fout), &st) >= 0 ? &st : NULL);
+ if (buf == NULL)
+ goto abort;
+
+ gettimeofday (&start, (struct timezone *) 0);
+ switch (curtype) {
+
+ case TYPE_I:
+ case TYPE_L:
+ if (restart_point &&
+ lseek (fileno (fout), restart_point, SEEK_SET) < 0) {
+ warn ("local: %s", local);
+ if (closefunc != NULL)
+ (*closefunc) (fout);
+ return;
+ }
+ errno = d = 0;
+ while ((c = sec_read (fileno (din), buf, bufsize)) > 0) {
+ if ((d = write (fileno (fout), buf, c)) != c)
+ break;
+ bytes += c;
+ if (hash) {
+ while (bytes >= hashbytes) {
+ putchar ('#');
+ hashbytes += HASHBYTES;
+ }
+ fflush (stdout);
+ }
+ }
+ if (hash && bytes > 0) {
+ if (bytes < HASHBYTES)
+ putchar ('#');
+ putchar ('\n');
+ fflush (stdout);
+ }
+ if (c < 0) {
+ if (errno != EPIPE)
+ warn ("netin");
+ bytes = -1;
+ }
+ if (d < c) {
+ if (d < 0)
+ warn ("local: %s", local);
+ else
+ warnx ("%s: short write", local);
+ }
+ break;
+
+ case TYPE_A:
+ if (restart_point) {
+ int i, n, ch;
+
+ if (fseek (fout, 0L, SEEK_SET) < 0)
+ goto done;
+ n = restart_point;
+ for (i = 0; i++ < n;) {
+ if ((ch = sec_getc (fout)) == EOF)
+ goto done;
+ if (ch == '\n')
+ i++;
+ }
+ if (fseek (fout, 0L, SEEK_CUR) < 0) {
+ done:
+ warn ("local: %s", local);
+ if (closefunc != NULL)
+ (*closefunc) (fout);
+ return;
+ }
+ }
+ while ((c = sec_getc(din)) != EOF) {
+ if (c == '\n')
+ bare_lfs++;
+ while (c == '\r') {
+ while (hash && (bytes >= hashbytes)) {
+ putchar ('#');
+ fflush (stdout);
+ hashbytes += HASHBYTES;
+ }
+ bytes++;
+ if ((c = sec_getc (din)) != '\n' || tcrflag) {
+ if (ferror (fout))
+ goto break2;
+ putc ('\r', fout);
+ if (c == '\0') {
+ bytes++;
+ goto contin2;
+ }
+ if (c == EOF)
+ goto contin2;
+ }
+ }
+ putc (c, fout);
+ bytes++;
+ contin2:;
+ }
+break2:
+ if (bare_lfs) {
+ printf ("WARNING! %d bare linefeeds received in ASCII mode\n",
+ bare_lfs);
+ printf ("File may not have transferred correctly.\n");
+ }
+ if (hash) {
+ if (bytes < hashbytes)
+ putchar ('#');
+ putchar ('\n');
+ fflush (stdout);
+ }
+ if (ferror (din)) {
+ if (errno != EPIPE)
+ warn ("netin");
+ bytes = -1;
+ }
+ if (ferror (fout))
+ warn ("local: %s", local);
+ break;
+ }
+ if (closefunc != NULL)
+ (*closefunc) (fout);
+ signal (SIGINT, oldintr);
+ if (oldintp)
+ signal (SIGPIPE, oldintp);
+ fclose (din);
+ gettimeofday (&stop, (struct timezone *) 0);
+ getreply (0);
+ if (bytes > 0 && is_retr)
+ ptransfer ("received", bytes, &start, &stop);
+ return;
+abort:
+
+ /* abort using RFC959 recommended IP,SYNC sequence */
+
+ if (oldintp)
+ signal (SIGPIPE, oldintr);
+ signal (SIGINT, SIG_IGN);
+ if (!cpend) {
+ code = -1;
+ signal (SIGINT, oldintr);
+ return;
+ }
+ abort_remote(din);
+ code = -1;
+ if (data >= 0) {
+ close (data);
+ data = -1;
+ }
+ if (closefunc != NULL && fout != NULL)
+ (*closefunc) (fout);
+ if (din)
+ fclose (din);
+ gettimeofday (&stop, (struct timezone *) 0);
+ if (bytes > 0)
+ ptransfer ("received", bytes, &start, &stop);
+ signal (SIGINT, oldintr);
+}
+
+static int
+parse_epsv (const char *str)
+{
+ char sep;
+ char *end;
+ int port;
+
+ if (*str == '\0')
+ return -1;
+ sep = *str++;
+ if (sep != *str++)
+ return -1;
+ if (sep != *str++)
+ return -1;
+ port = strtol (str, &end, 0);
+ if (str == end)
+ return -1;
+ if (end[0] != sep || end[1] != '\0')
+ return -1;
+ return htons(port);
+}
+
+static int
+parse_pasv (struct sockaddr_in *sin, const char *str)
+{
+ int a0, a1, a2, a3, p0, p1;
+
+ /*
+ * What we've got at this point is a string of comma separated
+ * one-byte unsigned integer values. The first four are the an IP
+ * address. The fifth is the MSB of the port number, the sixth is the
+ * LSB. From that we'll prepare a sockaddr_in.
+ */
+
+ if (sscanf (str, "%d,%d,%d,%d,%d,%d",
+ &a0, &a1, &a2, &a3, &p0, &p1) != 6) {
+ printf ("Passive mode address scan failure. "
+ "Shouldn't happen!\n");
+ return -1;
+ }
+ if (a0 < 0 || a0 > 255 ||
+ a1 < 0 || a1 > 255 ||
+ a2 < 0 || a2 > 255 ||
+ a3 < 0 || a3 > 255 ||
+ p0 < 0 || p0 > 255 ||
+ p1 < 0 || p1 > 255) {
+ printf ("Can't parse passive mode string.\n");
+ return -1;
+ }
+ memset (sin, 0, sizeof(*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = htonl ((a0 << 24) | (a1 << 16) |
+ (a2 << 8) | a3);
+ sin->sin_port = htons ((p0 << 8) | p1);
+ return 0;
+}
+
+static int
+passive_mode (void)
+{
+ int port;
+
+ data = socket (myctladdr->sa_family, SOCK_STREAM, 0);
+ if (data < 0) {
+ warn ("socket");
+ return (1);
+ }
+ if (options & SO_DEBUG)
+ socket_set_debug (data);
+ if (command ("EPSV") != COMPLETE) {
+ if (command ("PASV") != COMPLETE) {
+ printf ("Passive mode refused.\n");
+ goto bad;
+ }
+ }
+
+ /*
+ * Parse the reply to EPSV or PASV
+ */
+
+ port = parse_epsv (pasv);
+ if (port > 0) {
+ data_addr->sa_family = myctladdr->sa_family;
+ socket_set_address_and_port (data_addr,
+ socket_get_address (hisctladdr),
+ port);
+ } else {
+ if (parse_pasv ((struct sockaddr_in *)data_addr, pasv) < 0)
+ goto bad;
+ }
+
+ if (connect (data, data_addr, socket_sockaddr_size (data_addr)) < 0) {
+ warn ("connect");
+ goto bad;
+ }
+#ifdef IPTOS_THROUGHPUT
+ socket_set_tos (data, IPTOS_THROUGHPUT);
+#endif
+ return (0);
+bad:
+ close (data);
+ data = -1;
+ sendport = 1;
+ return (1);
+}
+
+
+static int
+active_mode (void)
+{
+ int tmpno = 0;
+ int len;
+ int result;
+
+noport:
+ data_addr->sa_family = myctladdr->sa_family;
+ socket_set_address_and_port (data_addr, socket_get_address (myctladdr),
+ sendport ? 0 : socket_get_port (myctladdr));
+
+ if (data != -1)
+ close (data);
+ data = socket (data_addr->sa_family, SOCK_STREAM, 0);
+ if (data < 0) {
+ warn ("socket");
+ if (tmpno)
+ sendport = 1;
+ return (1);
+ }
+ if (!sendport)
+ socket_set_reuseaddr (data, 1);
+ if (bind (data, data_addr, socket_sockaddr_size (data_addr)) < 0) {
+ warn ("bind");
+ goto bad;
+ }
+ if (options & SO_DEBUG)
+ socket_set_debug (data);
+ len = sizeof (data_addr_ss);
+ if (getsockname (data, data_addr, &len) < 0) {
+ warn ("getsockname");
+ goto bad;
+ }
+ if (listen (data, 1) < 0)
+ warn ("listen");
+ if (sendport) {
+ char *cmd;
+ char addr_str[256];
+ int inet_af;
+ int overbose;
+
+ if (inet_ntop (data_addr->sa_family, socket_get_address (data_addr),
+ addr_str, sizeof(addr_str)) == NULL)
+ errx (1, "inet_ntop failed");
+ switch (data_addr->sa_family) {
+ case AF_INET :
+ inet_af = 1;
+ break;
+#ifdef HAVE_IPV6
+ case AF_INET6 :
+ inet_af = 2;
+ break;
+#endif
+ default :
+ errx (1, "bad address family %d", data_addr->sa_family);
+ }
+
+ asprintf (&cmd, "EPRT |%d|%s|%d|",
+ inet_af, addr_str, ntohs(socket_get_port (data_addr)));
+
+ overbose = verbose;
+ if (debug == 0)
+ verbose = -1;
+
+ result = command (cmd);
+
+ verbose = overbose;
+
+ if (result == ERROR) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)data_addr;
+
+ unsigned int a = ntohl(sin->sin_addr.s_addr);
+ unsigned int p = ntohs(sin->sin_port);
+
+ if (data_addr->sa_family != AF_INET) {
+ warnx ("remote server doesn't support EPRT");
+ goto bad;
+ }
+
+ result = command("PORT %d,%d,%d,%d,%d,%d",
+ (a >> 24) & 0xff,
+ (a >> 16) & 0xff,
+ (a >> 8) & 0xff,
+ a & 0xff,
+ (p >> 8) & 0xff,
+ p & 0xff);
+ if (result == ERROR && sendport == -1) {
+ sendport = 0;
+ tmpno = 1;
+ goto noport;
+ }
+ return (result != COMPLETE);
+ }
+ return result != COMPLETE;
+ }
+ if (tmpno)
+ sendport = 1;
+
+
+#ifdef IPTOS_THROUGHPUT
+ socket_set_tos (data, IPTOS_THROUGHPUT);
+#endif
+ return (0);
+bad:
+ close (data);
+ data = -1;
+ if (tmpno)
+ sendport = 1;
+ return (1);
+}
+
+/*
+ * Need to start a listen on the data channel before we send the command,
+ * otherwise the server's connect may fail.
+ */
+int
+initconn (void)
+{
+ if (passivemode)
+ return passive_mode ();
+ else
+ return active_mode ();
+}
+
+FILE *
+dataconn (const char *lmode)
+{
+ struct sockaddr_storage from_ss;
+ struct sockaddr *from = (struct sockaddr *)&from_ss;
+ int s, fromlen = sizeof (from_ss);
+
+ if (passivemode)
+ return (fdopen (data, lmode));
+
+ s = accept (data, from, &fromlen);
+ if (s < 0) {
+ warn ("accept");
+ close (data), data = -1;
+ return (NULL);
+ }
+ close (data);
+ data = s;
+#ifdef IPTOS_THROUGHPUT
+ socket_set_tos (s, IPTOS_THROUGHPUT);
+#endif
+ return (fdopen (data, lmode));
+}
+
+void
+ptransfer (char *direction, long int bytes,
+ struct timeval * t0, struct timeval * t1)
+{
+ struct timeval td;
+ float s;
+ float bs;
+ int prec;
+ char *unit;
+
+ if (verbose) {
+ td.tv_sec = t1->tv_sec - t0->tv_sec;
+ td.tv_usec = t1->tv_usec - t0->tv_usec;
+ if (td.tv_usec < 0) {
+ td.tv_sec--;
+ td.tv_usec += 1000000;
+ }
+ s = td.tv_sec + (td.tv_usec / 1000000.);
+ bs = bytes / (s ? s : 1);
+ if (bs >= 1048576) {
+ bs /= 1048576;
+ unit = "M";
+ prec = 2;
+ } else if (bs >= 1024) {
+ bs /= 1024;
+ unit = "k";
+ prec = 1;
+ } else {
+ unit = "";
+ prec = 0;
+ }
+
+ printf ("%ld bytes %s in %.3g seconds (%.*f %sbyte/s)\n",
+ bytes, direction, s, prec, bs, unit);
+ }
+}
+
+void
+psabort (int sig)
+{
+
+ abrtflag++;
+}
+
+void
+pswitch (int flag)
+{
+ sighand oldintr;
+ static struct comvars {
+ int connect;
+ char name[MaxHostNameLen];
+ struct sockaddr_storage mctl;
+ struct sockaddr_storage hctl;
+ FILE *in;
+ FILE *out;
+ int tpe;
+ int curtpe;
+ int cpnd;
+ int sunqe;
+ int runqe;
+ int mcse;
+ int ntflg;
+ char nti[17];
+ char nto[17];
+ int mapflg;
+ char mi[MaxPathLen];
+ char mo[MaxPathLen];
+ } proxstruct, tmpstruct;
+ struct comvars *ip, *op;
+
+ abrtflag = 0;
+ oldintr = signal (SIGINT, psabort);
+ if (flag) {
+ if (proxy)
+ return;
+ ip = &tmpstruct;
+ op = &proxstruct;
+ proxy++;
+ } else {
+ if (!proxy)
+ return;
+ ip = &proxstruct;
+ op = &tmpstruct;
+ proxy = 0;
+ }
+ ip->connect = connected;
+ connected = op->connect;
+ if (hostname) {
+ strlcpy (ip->name, hostname, sizeof (ip->name));
+ } else
+ ip->name[0] = 0;
+ hostname = op->name;
+ ip->hctl = hisctladdr_ss;
+ hisctladdr_ss = op->hctl;
+ ip->mctl = myctladdr_ss;
+ myctladdr_ss = op->mctl;
+ ip->in = cin;
+ cin = op->in;
+ ip->out = cout;
+ cout = op->out;
+ ip->tpe = type;
+ type = op->tpe;
+ ip->curtpe = curtype;
+ curtype = op->curtpe;
+ ip->cpnd = cpend;
+ cpend = op->cpnd;
+ ip->sunqe = sunique;
+ sunique = op->sunqe;
+ ip->runqe = runique;
+ runique = op->runqe;
+ ip->mcse = mcase;
+ mcase = op->mcse;
+ ip->ntflg = ntflag;
+ ntflag = op->ntflg;
+ strlcpy (ip->nti, ntin, sizeof (ip->nti));
+ strlcpy (ntin, op->nti, 17);
+ strlcpy (ip->nto, ntout, sizeof (ip->nto));
+ strlcpy (ntout, op->nto, 17);
+ ip->mapflg = mapflag;
+ mapflag = op->mapflg;
+ strlcpy (ip->mi, mapin, MaxPathLen);
+ strlcpy (mapin, op->mi, MaxPathLen);
+ strlcpy (ip->mo, mapout, MaxPathLen);
+ strlcpy (mapout, op->mo, MaxPathLen);
+ signal(SIGINT, oldintr);
+ if (abrtflag) {
+ abrtflag = 0;
+ (*oldintr) (SIGINT);
+ }
+}
+
+void
+abortpt (int sig)
+{
+
+ printf ("\n");
+ fflush (stdout);
+ ptabflg++;
+ mflag = 0;
+ abrtflag = 0;
+ longjmp (ptabort, 1);
+}
+
+void
+proxtrans (char *cmd, char *local, char *remote)
+{
+ sighand oldintr;
+ int secndflag = 0, prox_type, nfnd;
+ char *cmd2;
+ fd_set mask;
+
+ if (strcmp (cmd, "RETR"))
+ cmd2 = "RETR";
+ else
+ cmd2 = runique ? "STOU" : "STOR";
+ if ((prox_type = type) == 0) {
+ if (unix_server && unix_proxy)
+ prox_type = TYPE_I;
+ else
+ prox_type = TYPE_A;
+ }
+ if (curtype != prox_type)
+ changetype (prox_type, 1);
+ if (command ("PASV") != COMPLETE) {
+ printf ("proxy server does not support third party transfers.\n");
+ return;
+ }
+ pswitch (0);
+ if (!connected) {
+ printf ("No primary connection\n");
+ pswitch (1);
+ code = -1;
+ return;
+ }
+ if (curtype != prox_type)
+ changetype (prox_type, 1);
+ if (command ("PORT %s", pasv) != COMPLETE) {
+ pswitch (1);
+ return;
+ }
+ if (setjmp (ptabort))
+ goto abort;
+ oldintr = signal (SIGINT, abortpt);
+ if (command ("%s %s", cmd, remote) != PRELIM) {
+ signal (SIGINT, oldintr);
+ pswitch (1);
+ return;
+ }
+ sleep (2);
+ pswitch (1);
+ secndflag++;
+ if (command ("%s %s", cmd2, local) != PRELIM)
+ goto abort;
+ ptflag++;
+ getreply (0);
+ pswitch (0);
+ getreply (0);
+ signal (SIGINT, oldintr);
+ pswitch (1);
+ ptflag = 0;
+ printf ("local: %s remote: %s\n", local, remote);
+ return;
+abort:
+ signal (SIGINT, SIG_IGN);
+ ptflag = 0;
+ if (strcmp (cmd, "RETR") && !proxy)
+ pswitch (1);
+ else if (!strcmp (cmd, "RETR") && proxy)
+ pswitch (0);
+ if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */
+ if (command ("%s %s", cmd2, local) != PRELIM) {
+ pswitch (0);
+ if (cpend)
+ abort_remote ((FILE *) NULL);
+ }
+ pswitch (1);
+ if (ptabflg)
+ code = -1;
+ signal (SIGINT, oldintr);
+ return;
+ }
+ if (cpend)
+ abort_remote ((FILE *) NULL);
+ pswitch (!proxy);
+ if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */
+ if (command ("%s %s", cmd2, local) != PRELIM) {
+ pswitch (0);
+ if (cpend)
+ abort_remote ((FILE *) NULL);
+ pswitch (1);
+ if (ptabflg)
+ code = -1;
+ signal (SIGINT, oldintr);
+ return;
+ }
+ }
+ if (cpend)
+ abort_remote ((FILE *) NULL);
+ pswitch (!proxy);
+ if (cpend) {
+ FD_ZERO (&mask);
+ FD_SET (fileno (cin), &mask);
+ if ((nfnd = empty (&mask, 10)) <= 0) {
+ if (nfnd < 0) {
+ warn ("abort");
+ }
+ if (ptabflg)
+ code = -1;
+ lostpeer (0);
+ }
+ getreply (0);
+ getreply (0);
+ }
+ if (proxy)
+ pswitch (0);
+ pswitch (1);
+ if (ptabflg)
+ code = -1;
+ signal (SIGINT, oldintr);
+}
+
+void
+reset (int argc, char **argv)
+{
+ fd_set mask;
+ int nfnd = 1;
+
+ FD_ZERO (&mask);
+ while (nfnd > 0) {
+ FD_SET (fileno (cin), &mask);
+ if ((nfnd = empty (&mask, 0)) < 0) {
+ warn ("reset");
+ code = -1;
+ lostpeer(0);
+ } else if (nfnd) {
+ getreply(0);
+ }
+ }
+}
+
+char *
+gunique (char *local)
+{
+ static char new[MaxPathLen];
+ char *cp = strrchr (local, '/');
+ int d, count = 0;
+ char ext = '1';
+
+ if (cp)
+ *cp = '\0';
+ d = access (cp ? local : ".", 2);
+ if (cp)
+ *cp = '/';
+ if (d < 0) {
+ warn ("local: %s", local);
+ return NULL;
+ }
+ strlcpy (new, local, sizeof(new));
+ cp = new + strlen(new);
+ *cp++ = '.';
+ while (!d) {
+ if (++count == 100) {
+ printf ("runique: can't find unique file name.\n");
+ return NULL;
+ }
+ *cp++ = ext;
+ *cp = '\0';
+ if (ext == '9')
+ ext = '0';
+ else
+ ext++;
+ if ((d = access (new, 0)) < 0)
+ break;
+ if (ext != '0')
+ cp--;
+ else if (*(cp - 2) == '.')
+ *(cp - 1) = '1';
+ else {
+ *(cp - 2) = *(cp - 2) + 1;
+ cp--;
+ }
+ }
+ return (new);
+}
+
+void
+abort_remote (FILE * din)
+{
+ char buf[BUFSIZ];
+ int nfnd;
+ fd_set mask;
+
+ /*
+ * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
+ * after urgent byte rather than before as is protocol now
+ */
+ snprintf (buf, sizeof (buf), "%c%c%c", IAC, IP, IAC);
+ if (send (fileno (cout), buf, 3, MSG_OOB) != 3)
+ warn ("abort");
+ fprintf (cout, "%cABOR\r\n", DM);
+ fflush (cout);
+ FD_ZERO (&mask);
+ FD_SET (fileno (cin), &mask);
+ if (din) {
+ FD_SET (fileno (din), &mask);
+ }
+ if ((nfnd = empty (&mask, 10)) <= 0) {
+ if (nfnd < 0) {
+ warn ("abort");
+ }
+ if (ptabflg)
+ code = -1;
+ lostpeer (0);
+ }
+ if (din && FD_ISSET (fileno (din), &mask)) {
+ while (read (fileno (din), buf, BUFSIZ) > 0)
+ /* LOOP */ ;
+ }
+ if (getreply (0) == ERROR && code == 552) {
+ /* 552 needed for nic style abort */
+ getreply (0);
+ }
+ getreply (0);
+}
diff --git a/crypto/heimdal/appl/ftp/ftp/ftp_locl.h b/crypto/heimdal/appl/ftp/ftp/ftp_locl.h
new file mode 100644
index 000000000000..49c2b2f45bcb
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/ftp_locl.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: ftp_locl.h,v 1.34 1999/12/02 16:58:29 joda Exp $ */
+
+#ifndef __FTP_LOCL_H__
+#define __FTP_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
+
+#ifdef HAVE_ARPA_FTP_H
+#include <arpa/ftp.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_TELNET_H
+#include <arpa/telnet.h>
+#endif
+
+#include <errno.h>
+#include <ctype.h>
+#include <glob.h>
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#include <err.h>
+
+#ifdef SOCKS
+#include <socks.h>
+extern int LIBPREFIX(fclose) (FILE *);
+
+/* This doesn't belong here. */
+struct tm *localtime(const time_t *);
+struct hostent *gethostbyname(const char *);
+
+#endif
+
+#include "ftp_var.h"
+#include "extern.h"
+#include "common.h"
+#include "pathnames.h"
+
+#include "roken.h"
+#include "security.h"
+#include <des.h> /* for des_read_pw_string */
+
+#if defined(__sun__) && !defined(__svr4)
+int fclose(FILE*);
+int pclose(FILE*);
+#endif
+
+#endif /* __FTP_LOCL_H__ */
diff --git a/crypto/heimdal/appl/ftp/ftp/ftp_var.h b/crypto/heimdal/appl/ftp/ftp/ftp_var.h
new file mode 100644
index 000000000000..ffac59a50fa9
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/ftp_var.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)ftp_var.h 8.4 (Berkeley) 10/9/94
+ */
+
+/*
+ * FTP global variables.
+ */
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <setjmp.h>
+
+/*
+ * Options and other state info.
+ */
+extern int trace; /* trace packets exchanged */
+extern int hash; /* print # for each buffer transferred */
+extern int sendport; /* use PORT cmd for each data connection */
+extern int verbose; /* print messages coming back from server */
+extern int connected; /* connected to server */
+extern int fromatty; /* input is from a terminal */
+extern int interactive; /* interactively prompt on m* cmds */
+extern int debug; /* debugging level */
+extern int bell; /* ring bell on cmd completion */
+extern int doglob; /* glob local file names */
+extern int autologin; /* establish user account on connection */
+extern int proxy; /* proxy server connection active */
+extern int proxflag; /* proxy connection exists */
+extern int sunique; /* store files on server with unique name */
+extern int runique; /* store local files with unique name */
+extern int mcase; /* map upper to lower case for mget names */
+extern int ntflag; /* use ntin ntout tables for name translation */
+extern int mapflag; /* use mapin mapout templates on file names */
+extern int code; /* return/reply code for ftp command */
+extern int crflag; /* if 1, strip car. rets. on ascii gets */
+extern char pasv[64]; /* passive port for proxy data connection */
+extern int passivemode; /* passive mode enabled */
+extern char *altarg; /* argv[1] with no shell-like preprocessing */
+extern char ntin[17]; /* input translation table */
+extern char ntout[17]; /* output translation table */
+extern char mapin[MaxPathLen]; /* input map template */
+extern char mapout[MaxPathLen]; /* output map template */
+extern char typename[32]; /* name of file transfer type */
+extern int type; /* requested file transfer type */
+extern int curtype; /* current file transfer type */
+extern char structname[32]; /* name of file transfer structure */
+extern int stru; /* file transfer structure */
+extern char formname[32]; /* name of file transfer format */
+extern int form; /* file transfer format */
+extern char modename[32]; /* name of file transfer mode */
+extern int mode; /* file transfer mode */
+extern char bytename[32]; /* local byte size in ascii */
+extern int bytesize; /* local byte size in binary */
+
+extern char *hostname; /* name of host connected to */
+extern int unix_server; /* server is unix, can use binary for ascii */
+extern int unix_proxy; /* proxy is unix, can use binary for ascii */
+
+extern jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
+
+extern char line[200]; /* input line buffer */
+extern char *stringbase; /* current scan point in line buffer */
+extern char argbuf[200]; /* argument storage buffer */
+extern char *argbase; /* current storage point in arg buffer */
+extern int margc; /* count of arguments on input line */
+extern char **margv; /* args parsed from input line */
+extern int margvlen; /* how large margv is currently */
+extern int cpend; /* flag: if != 0, then pending server reply */
+extern int mflag; /* flag: if != 0, then active multi command */
+
+extern int options; /* used during socket creation */
+
+/*
+ * Format of command table.
+ */
+struct cmd {
+ char *c_name; /* name of command */
+ char *c_help; /* help string */
+ char c_bell; /* give bell when command completes */
+ char c_conn; /* must be connected to use command */
+ char c_proxy; /* proxy server may execute */
+ void (*c_handler) (int, char **); /* function to call */
+};
+
+struct macel {
+ char mac_name[9]; /* macro name */
+ char *mac_start; /* start of macro in macbuf */
+ char *mac_end; /* end of macro in macbuf */
+};
+
+extern int macnum; /* number of defined macros */
+extern struct macel macros[16];
+extern char macbuf[4096];
+
+
diff --git a/crypto/heimdal/appl/ftp/ftp/globals.c b/crypto/heimdal/appl/ftp/ftp/globals.c
new file mode 100644
index 000000000000..7199e65c8c35
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/globals.c
@@ -0,0 +1,76 @@
+#include "ftp_locl.h"
+RCSID("$Id: globals.c,v 1.6 1996/08/26 22:46:26 assar Exp $");
+
+/*
+ * Options and other state info.
+ */
+int trace; /* trace packets exchanged */
+int hash; /* print # for each buffer transferred */
+int sendport; /* use PORT cmd for each data connection */
+int verbose; /* print messages coming back from server */
+int connected; /* connected to server */
+int fromatty; /* input is from a terminal */
+int interactive; /* interactively prompt on m* cmds */
+int debug; /* debugging level */
+int bell; /* ring bell on cmd completion */
+int doglob; /* glob local file names */
+int autologin; /* establish user account on connection */
+int proxy; /* proxy server connection active */
+int proxflag; /* proxy connection exists */
+int sunique; /* store files on server with unique name */
+int runique; /* store local files with unique name */
+int mcase; /* map upper to lower case for mget names */
+int ntflag; /* use ntin ntout tables for name translation */
+int mapflag; /* use mapin mapout templates on file names */
+int code; /* return/reply code for ftp command */
+int crflag; /* if 1, strip car. rets. on ascii gets */
+char pasv[64]; /* passive port for proxy data connection */
+int passivemode; /* passive mode enabled */
+char *altarg; /* argv[1] with no shell-like preprocessing */
+char ntin[17]; /* input translation table */
+char ntout[17]; /* output translation table */
+char mapin[MaxPathLen]; /* input map template */
+char mapout[MaxPathLen]; /* output map template */
+char typename[32]; /* name of file transfer type */
+int type; /* requested file transfer type */
+int curtype; /* current file transfer type */
+char structname[32]; /* name of file transfer structure */
+int stru; /* file transfer structure */
+char formname[32]; /* name of file transfer format */
+int form; /* file transfer format */
+char modename[32]; /* name of file transfer mode */
+int mode; /* file transfer mode */
+char bytename[32]; /* local byte size in ascii */
+int bytesize; /* local byte size in binary */
+
+char *hostname; /* name of host connected to */
+int unix_server; /* server is unix, can use binary for ascii */
+int unix_proxy; /* proxy is unix, can use binary for ascii */
+
+jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
+
+char line[200]; /* input line buffer */
+char *stringbase; /* current scan point in line buffer */
+char argbuf[200]; /* argument storage buffer */
+char *argbase; /* current storage point in arg buffer */
+int margc; /* count of arguments on input line */
+char **margv; /* args parsed from input line */
+int margvlen; /* how large margv is currently */
+int cpend; /* flag: if != 0, then pending server reply */
+int mflag; /* flag: if != 0, then active multi command */
+
+int options; /* used during socket creation */
+
+/*
+ * Format of command table.
+ */
+
+int macnum; /* number of defined macros */
+struct macel macros[16];
+char macbuf[4096];
+
+char username[32];
+
+/* these are set in ruserpass */
+char myhostname[MaxHostNameLen];
+char *mydomain;
diff --git a/crypto/heimdal/appl/ftp/ftp/gssapi.c b/crypto/heimdal/appl/ftp/ftp/gssapi.c
new file mode 100644
index 000000000000..d06b5d62d29d
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/gssapi.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef FTP_SERVER
+#include "ftpd_locl.h"
+#else
+#include "ftp_locl.h"
+#endif
+#include <gssapi.h>
+
+RCSID("$Id: gssapi.c,v 1.13 1999/12/02 16:58:29 joda Exp $");
+
+struct gss_data {
+ gss_ctx_id_t context_hdl;
+ char *client_name;
+};
+
+static int
+gss_init(void *app_data)
+{
+ struct gss_data *d = app_data;
+ d->context_hdl = GSS_C_NO_CONTEXT;
+ return 0;
+}
+
+static int
+gss_check_prot(void *app_data, int level)
+{
+ if(level == prot_confidential)
+ return -1;
+ return 0;
+}
+
+static int
+gss_decode(void *app_data, void *buf, int len, int level)
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_buffer_desc input, output;
+ gss_qop_t qop_state;
+ int conf_state;
+ struct gss_data *d = app_data;
+
+ input.length = len;
+ input.value = buf;
+ maj_stat = gss_unwrap (&min_stat,
+ d->context_hdl,
+ &input,
+ &output,
+ &conf_state,
+ &qop_state);
+ if(GSS_ERROR(maj_stat))
+ return -1;
+ memmove(buf, output.value, output.length);
+ return output.length;
+}
+
+static int
+gss_overhead(void *app_data, int level, int len)
+{
+ return 100; /* dunno? */
+}
+
+
+static int
+gss_encode(void *app_data, void *from, int length, int level, void **to)
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_buffer_desc input, output;
+ int conf_state;
+ struct gss_data *d = app_data;
+
+ input.length = length;
+ input.value = from;
+ maj_stat = gss_wrap (&min_stat,
+ d->context_hdl,
+ level == prot_private,
+ GSS_C_QOP_DEFAULT,
+ &input,
+ &conf_state,
+ &output);
+ *to = output.value;
+ return output.length;
+}
+
+static void
+sockaddr_to_gss_address (const struct sockaddr *sa,
+ OM_uint32 *addr_type,
+ gss_buffer_desc *gss_addr)
+{
+ switch (sa->sa_family) {
+#ifdef HAVE_IPV6
+ case AF_INET6 : {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ gss_addr->length = 16;
+ gss_addr->value = &sin6->sin6_addr;
+ *addr_type = GSS_C_AF_INET6;
+ break;
+ }
+#endif
+ case AF_INET : {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ gss_addr->length = 4;
+ gss_addr->value = &sin->sin_addr;
+ *addr_type = GSS_C_AF_INET;
+ break;
+ }
+ default :
+ errx (1, "unknown address family %d", sa->sa_family);
+
+ }
+}
+
+/* end common stuff */
+
+#ifdef FTP_SERVER
+
+static int
+gss_adat(void *app_data, void *buf, size_t len)
+{
+ char *p = NULL;
+ gss_buffer_desc input_token, output_token;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t client_name;
+ struct gss_data *d = app_data;
+
+ gss_channel_bindings_t bindings = malloc(sizeof(*bindings));
+ sockaddr_to_gss_address (his_addr,
+ &bindings->initiator_addrtype,
+ &bindings->initiator_address);
+ sockaddr_to_gss_address (ctrl_addr,
+ &bindings->acceptor_addrtype,
+ &bindings->acceptor_address);
+
+ bindings->application_data.length = 0;
+ bindings->application_data.value = NULL;
+
+ input_token.value = buf;
+ input_token.length = len;
+
+ maj_stat = gss_accept_sec_context (&min_stat,
+ &d->context_hdl,
+ GSS_C_NO_CREDENTIAL,
+ &input_token,
+ bindings,
+ &client_name,
+ NULL,
+ &output_token,
+ NULL,
+ NULL,
+ NULL);
+
+ if(output_token.length) {
+ if(base64_encode(output_token.value, output_token.length, &p) < 0) {
+ reply(535, "Out of memory base64-encoding.");
+ return -1;
+ }
+ }
+ if(maj_stat == GSS_S_COMPLETE){
+ char *name;
+ gss_buffer_desc export_name;
+ maj_stat = gss_export_name(&min_stat, client_name, &export_name);
+ if(maj_stat != 0) {
+ reply(500, "Error exporting name");
+ goto out;
+ }
+ name = realloc(export_name.value, export_name.length + 1);
+ if(name == NULL) {
+ reply(500, "Out of memory");
+ free(export_name.value);
+ goto out;
+ }
+ name[export_name.length] = '\0';
+ d->client_name = name;
+ if(p)
+ reply(235, "ADAT=%s", p);
+ else
+ reply(235, "ADAT Complete");
+ sec_complete = 1;
+
+ } else if(maj_stat == GSS_S_CONTINUE_NEEDED) {
+ if(p)
+ reply(335, "ADAT=%s", p);
+ else
+ reply(335, "OK, need more data");
+ } else
+ reply(535, "foo?");
+out:
+ free(p);
+ return 0;
+}
+
+int gss_userok(void*, char*);
+
+struct sec_server_mech gss_server_mech = {
+ "GSSAPI",
+ sizeof(struct gss_data),
+ gss_init, /* init */
+ NULL, /* end */
+ gss_check_prot,
+ gss_overhead,
+ gss_encode,
+ gss_decode,
+ /* */
+ NULL,
+ gss_adat,
+ NULL, /* pbsz */
+ NULL, /* ccc */
+ gss_userok
+};
+
+#else /* FTP_SERVER */
+
+extern struct sockaddr *hisctladdr, *myctladdr;
+
+static int
+gss_auth(void *app_data, char *host)
+{
+
+ OM_uint32 maj_stat, min_stat;
+ gss_buffer_desc name;
+ gss_name_t target_name;
+ gss_buffer_desc input, output_token;
+ int context_established = 0;
+ char *p;
+ int n;
+ gss_channel_bindings_t bindings;
+ struct gss_data *d = app_data;
+
+ name.length = asprintf((char**)&name.value, "ftp@%s", host);
+ maj_stat = gss_import_name(&min_stat,
+ &name,
+ GSS_C_NT_HOSTBASED_SERVICE,
+ &target_name);
+ if (GSS_ERROR(maj_stat)) {
+ OM_uint32 new_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+
+ gss_display_status(&new_stat,
+ min_stat,
+ GSS_C_MECH_CODE,
+ GSS_C_NO_OID,
+ &msg_ctx,
+ &status_string);
+ printf("Error importing name %s: %s\n",
+ (char *)name.value,
+ (char *)status_string.value);
+ gss_release_buffer(&new_stat, &status_string);
+ return AUTH_ERROR;
+ }
+ free(name.value);
+
+
+ input.length = 0;
+ input.value = NULL;
+
+ bindings = malloc(sizeof(*bindings));
+
+ sockaddr_to_gss_address (myctladdr,
+ &bindings->initiator_addrtype,
+ &bindings->initiator_address);
+ sockaddr_to_gss_address (hisctladdr,
+ &bindings->acceptor_addrtype,
+ &bindings->acceptor_address);
+
+ bindings->application_data.length = 0;
+ bindings->application_data.value = NULL;
+
+ while(!context_established) {
+ maj_stat = gss_init_sec_context(&min_stat,
+ GSS_C_NO_CREDENTIAL,
+ &d->context_hdl,
+ target_name,
+ GSS_C_NO_OID,
+ GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG,
+ 0,
+ bindings,
+ &input,
+ NULL,
+ &output_token,
+ NULL,
+ NULL);
+ if (GSS_ERROR(maj_stat)) {
+ OM_uint32 new_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+
+ gss_display_status(&new_stat,
+ min_stat,
+ GSS_C_MECH_CODE,
+ GSS_C_NO_OID,
+ &msg_ctx,
+ &status_string);
+ printf("Error initializing security context: %s\n",
+ (char*)status_string.value);
+ gss_release_buffer(&new_stat, &status_string);
+ return AUTH_CONTINUE;
+ }
+
+ gss_release_buffer(&min_stat, &input);
+ if (output_token.length != 0) {
+ base64_encode(output_token.value, output_token.length, &p);
+ gss_release_buffer(&min_stat, &output_token);
+ n = command("ADAT %s", p);
+ free(p);
+ }
+ if (GSS_ERROR(maj_stat)) {
+ if (d->context_hdl != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context (&min_stat,
+ &d->context_hdl,
+ GSS_C_NO_BUFFER);
+ break;
+ }
+ if (maj_stat & GSS_S_CONTINUE_NEEDED) {
+ p = strstr(reply_string, "ADAT=");
+ if(p == NULL){
+ printf("Error: expected ADAT in reply.\n");
+ return AUTH_ERROR;
+ } else {
+ p+=5;
+ input.value = malloc(strlen(p));
+ input.length = base64_decode(p, input.value);
+ }
+ } else {
+ if(code != 235) {
+ printf("Unrecognized response code: %d\n", code);
+ return AUTH_ERROR;
+ }
+ context_established = 1;
+ }
+ }
+ return AUTH_OK;
+}
+
+struct sec_client_mech gss_client_mech = {
+ "GSSAPI",
+ sizeof(struct gss_data),
+ gss_init,
+ gss_auth,
+ NULL, /* end */
+ gss_check_prot,
+ gss_overhead,
+ gss_encode,
+ gss_decode,
+};
+
+#endif /* FTP_SERVER */
diff --git a/crypto/heimdal/appl/ftp/ftp/kauth.c b/crypto/heimdal/appl/ftp/ftp/kauth.c
new file mode 100644
index 000000000000..613593a71290
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/kauth.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 1995-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ftp_locl.h"
+#include <krb.h>
+RCSID("$Id: kauth.c,v 1.20 1999/12/02 16:58:29 joda Exp $");
+
+void
+kauth(int argc, char **argv)
+{
+ int ret;
+ char buf[1024];
+ des_cblock key;
+ des_key_schedule schedule;
+ KTEXT_ST tkt, tktcopy;
+ char *name;
+ char *p;
+ int overbose;
+ char passwd[100];
+ int tmp;
+
+ int save;
+
+ if(argc > 2){
+ printf("usage: %s [principal]\n", argv[0]);
+ code = -1;
+ return;
+ }
+ if(argc == 2)
+ name = argv[1];
+ else
+ name = username;
+
+ overbose = verbose;
+ verbose = 0;
+
+ save = set_command_prot(prot_private);
+ ret = command("SITE KAUTH %s", name);
+ if(ret != CONTINUE){
+ verbose = overbose;
+ set_command_prot(save);
+ code = -1;
+ return;
+ }
+ verbose = overbose;
+ p = strstr(reply_string, "T=");
+ if(!p){
+ printf("Bad reply from server.\n");
+ set_command_prot(save);
+ code = -1;
+ return;
+ }
+ p += 2;
+ tmp = base64_decode(p, &tkt.dat);
+ if(tmp < 0){
+ printf("Failed to decode base64 in reply.\n");
+ set_command_prot(save);
+ code = -1;
+ return;
+ }
+ tkt.length = tmp;
+ tktcopy.length = tkt.length;
+
+ p = strstr(reply_string, "P=");
+ if(!p){
+ printf("Bad reply from server.\n");
+ verbose = overbose;
+ set_command_prot(save);
+ code = -1;
+ return;
+ }
+ name = p + 2;
+ for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
+ *p = 0;
+
+ snprintf(buf, sizeof(buf), "Password for %s:", name);
+ if (des_read_pw_string (passwd, sizeof(passwd)-1, buf, 0))
+ *passwd = '\0';
+ des_string_to_key (passwd, &key);
+
+ des_key_sched(&key, schedule);
+
+ des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
+ tkt.length,
+ schedule, &key, DES_DECRYPT);
+ if (strcmp ((char*)tktcopy.dat + 8,
+ KRB_TICKET_GRANTING_TICKET) != 0) {
+ afs_string_to_key (passwd, krb_realmofhost(hostname), &key);
+ des_key_sched (&key, schedule);
+ des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
+ tkt.length,
+ schedule, &key, DES_DECRYPT);
+ }
+ memset(key, 0, sizeof(key));
+ memset(schedule, 0, sizeof(schedule));
+ memset(passwd, 0, sizeof(passwd));
+ if(base64_encode(tktcopy.dat, tktcopy.length, &p) < 0) {
+ printf("Out of memory base64-encoding.\n");
+ set_command_prot(save);
+ code = -1;
+ return;
+ }
+ memset (tktcopy.dat, 0, tktcopy.length);
+ ret = command("SITE KAUTH %s %s", name, p);
+ free(p);
+ set_command_prot(save);
+ if(ret != COMPLETE){
+ code = -1;
+ return;
+ }
+ code = 0;
+}
+
+void
+klist(int argc, char **argv)
+{
+ int ret;
+ if(argc != 1){
+ printf("usage: %s\n", argv[0]);
+ code = -1;
+ return;
+ }
+
+ ret = command("SITE KLIST");
+ code = (ret == COMPLETE);
+}
+
+void
+kdestroy(int argc, char **argv)
+{
+ int ret;
+ if (argc != 1) {
+ printf("usage: %s\n", argv[0]);
+ code = -1;
+ return;
+ }
+ ret = command("SITE KDESTROY");
+ code = (ret == COMPLETE);
+}
+
+void
+krbtkfile(int argc, char **argv)
+{
+ int ret;
+ if(argc != 2) {
+ printf("usage: %s tktfile\n", argv[0]);
+ code = -1;
+ return;
+ }
+ ret = command("SITE KRBTKFILE %s", argv[1]);
+ code = (ret == COMPLETE);
+}
+
+void
+afslog(int argc, char **argv)
+{
+ int ret;
+ if(argc > 2) {
+ printf("usage: %s [cell]\n", argv[0]);
+ code = -1;
+ return;
+ }
+ if(argc == 2)
+ ret = command("SITE AFSLOG %s", argv[1]);
+ else
+ ret = command("SITE AFSLOG");
+ code = (ret == COMPLETE);
+}
diff --git a/crypto/heimdal/appl/ftp/ftp/krb4.c b/crypto/heimdal/appl/ftp/ftp/krb4.c
new file mode 100644
index 000000000000..c89ba95b2450
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/krb4.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef FTP_SERVER
+#include "ftpd_locl.h"
+#else
+#include "ftp_locl.h"
+#endif
+#include <krb.h>
+
+RCSID("$Id: krb4.c,v 1.37 1999/12/06 17:10:13 assar Exp $");
+
+#ifdef FTP_SERVER
+#define LOCAL_ADDR ctrl_addr
+#define REMOTE_ADDR his_addr
+#else
+#define LOCAL_ADDR myctladdr
+#define REMOTE_ADDR hisctladdr
+#endif
+
+extern struct sockaddr *LOCAL_ADDR, *REMOTE_ADDR;
+
+struct krb4_data {
+ des_cblock key;
+ des_key_schedule schedule;
+ char name[ANAME_SZ];
+ char instance[INST_SZ];
+ char realm[REALM_SZ];
+};
+
+static int
+krb4_check_prot(void *app_data, int level)
+{
+ if(level == prot_confidential)
+ return -1;
+ return 0;
+}
+
+static int
+krb4_decode(void *app_data, void *buf, int len, int level)
+{
+ MSG_DAT m;
+ int e;
+ struct krb4_data *d = app_data;
+
+ if(level == prot_safe)
+ e = krb_rd_safe(buf, len, &d->key,
+ (struct sockaddr_in *)REMOTE_ADDR,
+ (struct sockaddr_in *)LOCAL_ADDR, &m);
+ else
+ e = krb_rd_priv(buf, len, d->schedule, &d->key,
+ (struct sockaddr_in *)REMOTE_ADDR,
+ (struct sockaddr_in *)LOCAL_ADDR, &m);
+ if(e){
+ syslog(LOG_ERR, "krb4_decode: %s", krb_get_err_text(e));
+ return -1;
+ }
+ memmove(buf, m.app_data, m.app_length);
+ return m.app_length;
+}
+
+static int
+krb4_overhead(void *app_data, int level, int len)
+{
+ return 31;
+}
+
+static int
+krb4_encode(void *app_data, void *from, int length, int level, void **to)
+{
+ struct krb4_data *d = app_data;
+ *to = malloc(length + 31);
+ if(level == prot_safe)
+ return krb_mk_safe(from, *to, length, &d->key,
+ (struct sockaddr_in *)LOCAL_ADDR,
+ (struct sockaddr_in *)REMOTE_ADDR);
+ else if(level == prot_private)
+ return krb_mk_priv(from, *to, length, d->schedule, &d->key,
+ (struct sockaddr_in *)LOCAL_ADDR,
+ (struct sockaddr_in *)REMOTE_ADDR);
+ else
+ return -1;
+}
+
+#ifdef FTP_SERVER
+
+static int
+krb4_adat(void *app_data, void *buf, size_t len)
+{
+ KTEXT_ST tkt;
+ AUTH_DAT auth_dat;
+ char *p;
+ int kerror;
+ u_int32_t cs;
+ char msg[35]; /* size of encrypted block */
+ int tmp_len;
+ struct krb4_data *d = app_data;
+ char inst[INST_SZ];
+ struct sockaddr_in *his_addr_sin = (struct sockaddr_in *)his_addr;
+
+ memcpy(tkt.dat, buf, len);
+ tkt.length = len;
+
+ k_getsockinst(0, inst, sizeof(inst));
+ kerror = krb_rd_req(&tkt, "ftp", inst,
+ his_addr_sin->sin_addr.s_addr, &auth_dat, "");
+ if(kerror == RD_AP_UNDEC){
+ k_getsockinst(0, inst, sizeof(inst));
+ kerror = krb_rd_req(&tkt, "rcmd", inst,
+ his_addr_sin->sin_addr.s_addr, &auth_dat, "");
+ }
+
+ if(kerror){
+ reply(535, "Error reading request: %s.", krb_get_err_text(kerror));
+ return -1;
+ }
+
+ memcpy(d->key, auth_dat.session, sizeof(d->key));
+ des_set_key(&d->key, d->schedule);
+
+ strlcpy(d->name, auth_dat.pname, sizeof(d->name));
+ strlcpy(d->instance, auth_dat.pinst, sizeof(d->instance));
+ strlcpy(d->realm, auth_dat.prealm, sizeof(d->instance));
+
+ cs = auth_dat.checksum + 1;
+ {
+ unsigned char tmp[4];
+ KRB_PUT_INT(cs, tmp, 4, sizeof(tmp));
+ tmp_len = krb_mk_safe(tmp, msg, 4, &d->key,
+ (struct sockaddr_in *)LOCAL_ADDR,
+ (struct sockaddr_in *)REMOTE_ADDR);
+ }
+ if(tmp_len < 0){
+ reply(535, "Error creating reply: %s.", strerror(errno));
+ return -1;
+ }
+ len = tmp_len;
+ if(base64_encode(msg, len, &p) < 0) {
+ reply(535, "Out of memory base64-encoding.");
+ return -1;
+ }
+ reply(235, "ADAT=%s", p);
+ sec_complete = 1;
+ free(p);
+ return 0;
+}
+
+static int
+krb4_userok(void *app_data, char *user)
+{
+ struct krb4_data *d = app_data;
+ return krb_kuserok(d->name, d->instance, d->realm, user);
+}
+
+struct sec_server_mech krb4_server_mech = {
+ "KERBEROS_V4",
+ sizeof(struct krb4_data),
+ NULL, /* init */
+ NULL, /* end */
+ krb4_check_prot,
+ krb4_overhead,
+ krb4_encode,
+ krb4_decode,
+ /* */
+ NULL,
+ krb4_adat,
+ NULL, /* pbsz */
+ NULL, /* ccc */
+ krb4_userok
+};
+
+#else /* FTP_SERVER */
+
+static int
+mk_auth(struct krb4_data *d, KTEXT adat,
+ char *service, char *host, int checksum)
+{
+ int ret;
+ CREDENTIALS cred;
+ char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ];
+
+ strlcpy(sname, service, sizeof(sname));
+ strlcpy(inst, krb_get_phost(host), sizeof(inst));
+ strlcpy(realm, krb_realmofhost(host), sizeof(realm));
+ ret = krb_mk_req(adat, sname, inst, realm, checksum);
+ if(ret)
+ return ret;
+ strlcpy(sname, service, sizeof(sname));
+ strlcpy(inst, krb_get_phost(host), sizeof(inst));
+ strlcpy(realm, krb_realmofhost(host), sizeof(realm));
+ ret = krb_get_cred(sname, inst, realm, &cred);
+ memmove(&d->key, &cred.session, sizeof(des_cblock));
+ des_key_sched(&d->key, d->schedule);
+ memset(&cred, 0, sizeof(cred));
+ return ret;
+}
+
+static int
+krb4_auth(void *app_data, char *host)
+{
+ int ret;
+ char *p;
+ int len;
+ KTEXT_ST adat;
+ MSG_DAT msg_data;
+ int checksum;
+ u_int32_t cs;
+ struct krb4_data *d = app_data;
+ struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
+ struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR;
+
+ checksum = getpid();
+ ret = mk_auth(d, &adat, "ftp", host, checksum);
+ if(ret == KDC_PR_UNKNOWN)
+ ret = mk_auth(d, &adat, "rcmd", host, checksum);
+ if(ret){
+ printf("%s\n", krb_get_err_text(ret));
+ return AUTH_CONTINUE;
+ }
+
+#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
+ if (krb_get_config_bool("nat_in_use")) {
+ struct in_addr natAddr;
+
+ if (krb_get_our_ip_for_realm(krb_realmofhost(host),
+ &natAddr) != KSUCCESS
+ && krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS)
+ printf("Can't get address for realm %s\n",
+ krb_realmofhost(host));
+ else {
+ if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
+ printf("Using NAT IP address (%s) for kerberos 4\n",
+ inet_ntoa(natAddr));
+ localaddr->sin_addr = natAddr;
+
+ /*
+ * This not the best place to do this, but it
+ * is here we know that (probably) NAT is in
+ * use!
+ */
+
+ passivemode = 1;
+ printf("Setting: Passive mode on.\n");
+ }
+ }
+ }
+#endif
+
+ printf("Local address is %s\n", inet_ntoa(localaddr->sin_addr));
+ printf("Remote address is %s\n", inet_ntoa(remoteaddr->sin_addr));
+
+ if(base64_encode(adat.dat, adat.length, &p) < 0) {
+ printf("Out of memory base64-encoding.\n");
+ return AUTH_CONTINUE;
+ }
+ ret = command("ADAT %s", p);
+ free(p);
+
+ if(ret != COMPLETE){
+ printf("Server didn't accept auth data.\n");
+ return AUTH_ERROR;
+ }
+
+ p = strstr(reply_string, "ADAT=");
+ if(!p){
+ printf("Remote host didn't send adat reply.\n");
+ return AUTH_ERROR;
+ }
+ p += 5;
+ len = base64_decode(p, adat.dat);
+ if(len < 0){
+ printf("Failed to decode base64 from server.\n");
+ return AUTH_ERROR;
+ }
+ adat.length = len;
+ ret = krb_rd_safe(adat.dat, adat.length, &d->key,
+ (struct sockaddr_in *)hisctladdr,
+ (struct sockaddr_in *)myctladdr, &msg_data);
+ if(ret){
+ printf("Error reading reply from server: %s.\n",
+ krb_get_err_text(ret));
+ return AUTH_ERROR;
+ }
+ krb_get_int(msg_data.app_data, &cs, 4, 0);
+ if(cs - checksum != 1){
+ printf("Bad checksum returned from server.\n");
+ return AUTH_ERROR;
+ }
+ return AUTH_OK;
+}
+
+struct sec_client_mech krb4_client_mech = {
+ "KERBEROS_V4",
+ sizeof(struct krb4_data),
+ NULL, /* init */
+ krb4_auth,
+ NULL, /* end */
+ krb4_check_prot,
+ krb4_overhead,
+ krb4_encode,
+ krb4_decode
+};
+
+#endif /* FTP_SERVER */
diff --git a/crypto/heimdal/appl/ftp/ftp/main.c b/crypto/heimdal/appl/ftp/ftp/main.c
new file mode 100644
index 000000000000..dfe9e882bc1f
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/main.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 1985, 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+/*
+ * FTP User Program -- Command Interface.
+ */
+
+#include "ftp_locl.h"
+RCSID("$Id: main.c,v 1.27 1999/11/13 06:18:02 assar Exp $");
+
+int
+main(int argc, char **argv)
+{
+ int ch, top;
+ struct passwd *pw = NULL;
+ char homedir[MaxPathLen];
+ struct servent *sp;
+
+ set_progname(argv[0]);
+
+ sp = getservbyname("ftp", "tcp");
+ if (sp == 0)
+ errx(1, "ftp/tcp: unknown service");
+ doglob = 1;
+ interactive = 1;
+ autologin = 1;
+ passivemode = 0; /* passive mode not active */
+
+ while ((ch = getopt(argc, argv, "dginptv")) != -1) {
+ switch (ch) {
+ case 'd':
+ options |= SO_DEBUG;
+ debug++;
+ break;
+
+ case 'g':
+ doglob = 0;
+ break;
+
+ case 'i':
+ interactive = 0;
+ break;
+
+ case 'n':
+ autologin = 0;
+ break;
+
+ case 'p':
+ passivemode = 1;
+ break;
+ case 't':
+ trace++;
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
+ default:
+ fprintf(stderr,
+ "usage: ftp [-dginptv] [host [port]]\n");
+ exit(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ fromatty = isatty(fileno(stdin));
+ if (fromatty)
+ verbose++;
+ cpend = 0; /* no pending replies */
+ proxy = 0; /* proxy not active */
+ crflag = 1; /* strip c.r. on ascii gets */
+ sendport = -1; /* not using ports */
+ /*
+ * Set up the home directory in case we're globbing.
+ */
+ pw = k_getpwuid(getuid());
+ if (pw != NULL) {
+ strlcpy(homedir, pw->pw_dir, sizeof(homedir));
+ home = homedir;
+ }
+ if (argc > 0) {
+ char *xargv[5];
+
+ if (setjmp(toplevel))
+ exit(0);
+ signal(SIGINT, intr);
+ signal(SIGPIPE, lostpeer);
+ xargv[0] = (char*)__progname;
+ xargv[1] = argv[0];
+ xargv[2] = argv[1];
+ xargv[3] = argv[2];
+ xargv[4] = NULL;
+ setpeer(argc+1, xargv);
+ }
+ if(setjmp(toplevel) == 0)
+ top = 1;
+ else
+ top = 0;
+ if (top) {
+ signal(SIGINT, intr);
+ signal(SIGPIPE, lostpeer);
+ }
+ for (;;) {
+ cmdscanner(top);
+ top = 1;
+ }
+}
+
+void
+intr(int sig)
+{
+
+ longjmp(toplevel, 1);
+}
+
+#ifndef SHUT_RDWR
+#define SHUT_RDWR 2
+#endif
+
+RETSIGTYPE
+lostpeer(int sig)
+{
+
+ if (connected) {
+ if (cout != NULL) {
+ shutdown(fileno(cout), SHUT_RDWR);
+ fclose(cout);
+ cout = NULL;
+ }
+ if (data >= 0) {
+ shutdown(data, SHUT_RDWR);
+ close(data);
+ data = -1;
+ }
+ connected = 0;
+ }
+ pswitch(1);
+ if (connected) {
+ if (cout != NULL) {
+ shutdown(fileno(cout), SHUT_RDWR);
+ fclose(cout);
+ cout = NULL;
+ }
+ connected = 0;
+ }
+ proxflag = 0;
+ pswitch(0);
+ sec_end();
+ SIGRETURN(0);
+}
+
+/*
+char *
+tail(filename)
+ char *filename;
+{
+ char *s;
+
+ while (*filename) {
+ s = strrchr(filename, '/');
+ if (s == NULL)
+ break;
+ if (s[1])
+ return (s + 1);
+ *s = '\0';
+ }
+ return (filename);
+}
+*/
+
+#ifndef HAVE_READLINE
+
+static char *
+readline(char *prompt)
+{
+ char buf[BUFSIZ];
+ printf ("%s", prompt);
+ fflush (stdout);
+ if(fgets(buf, sizeof(buf), stdin) == NULL)
+ return NULL;
+ if (buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ return strdup(buf);
+}
+
+static void
+add_history(char *p)
+{
+}
+
+#else
+
+/* These should not really be here */
+
+char *readline(char *);
+void add_history(char *);
+
+#endif
+
+/*
+ * Command parser.
+ */
+void
+cmdscanner(int top)
+{
+ struct cmd *c;
+ int l;
+
+ if (!top)
+ putchar('\n');
+ for (;;) {
+ if (fromatty) {
+ char *p;
+ p = readline("ftp> ");
+ if(p == NULL)
+ quit(0, 0);
+ strlcpy(line, p, sizeof(line));
+ add_history(p);
+ free(p);
+ } else{
+ if (fgets(line, sizeof line, stdin) == NULL)
+ quit(0, 0);
+ }
+ /* XXX will break on long lines */
+ l = strlen(line);
+ if (l == 0)
+ break;
+ if (line[--l] == '\n') {
+ if (l == 0)
+ break;
+ line[l] = '\0';
+ } else if (l == sizeof(line) - 2) {
+ printf("sorry, input line too long\n");
+ while ((l = getchar()) != '\n' && l != EOF)
+ /* void */;
+ break;
+ } /* else it was a line without a newline */
+ makeargv();
+ if (margc == 0) {
+ continue;
+ }
+ c = getcmd(margv[0]);
+ if (c == (struct cmd *)-1) {
+ printf("?Ambiguous command\n");
+ continue;
+ }
+ if (c == 0) {
+ printf("?Invalid command\n");
+ continue;
+ }
+ if (c->c_conn && !connected) {
+ printf("Not connected.\n");
+ continue;
+ }
+ (*c->c_handler)(margc, margv);
+ if (bell && c->c_bell)
+ putchar('\007');
+ if (c->c_handler != help)
+ break;
+ }
+ signal(SIGINT, intr);
+ signal(SIGPIPE, lostpeer);
+}
+
+struct cmd *
+getcmd(char *name)
+{
+ char *p, *q;
+ struct cmd *c, *found;
+ int nmatches, longest;
+
+ longest = 0;
+ nmatches = 0;
+ found = 0;
+ for (c = cmdtab; (p = c->c_name); c++) {
+ for (q = name; *q == *p++; q++)
+ if (*q == 0) /* exact match? */
+ return (c);
+ if (!*q) { /* the name was a prefix */
+ if (q - name > longest) {
+ longest = q - name;
+ nmatches = 1;
+ found = c;
+ } else if (q - name == longest)
+ nmatches++;
+ }
+ }
+ if (nmatches > 1)
+ return ((struct cmd *)-1);
+ return (found);
+}
+
+/*
+ * Slice a string up into argc/argv.
+ */
+
+int slrflag;
+
+void
+makeargv(void)
+{
+ char **argp;
+
+ argp = margv;
+ stringbase = line; /* scan from first of buffer */
+ argbase = argbuf; /* store from first of buffer */
+ slrflag = 0;
+ for (margc = 0; ; margc++) {
+ /* Expand array if necessary */
+ if (margc == margvlen) {
+ int i;
+
+ margv = (margvlen == 0)
+ ? (char **)malloc(20 * sizeof(char *))
+ : (char **)realloc(margv,
+ (margvlen + 20)*sizeof(char *));
+ if (margv == NULL)
+ errx(1, "cannot realloc argv array");
+ for(i = margvlen; i < margvlen + 20; ++i)
+ margv[i] = NULL;
+ margvlen += 20;
+ argp = margv + margc;
+ }
+
+ if ((*argp++ = slurpstring()) == NULL)
+ break;
+ }
+
+}
+
+/*
+ * Parse string into argbuf;
+ * implemented with FSM to
+ * handle quoting and strings
+ */
+char *
+slurpstring(void)
+{
+ int got_one = 0;
+ char *sb = stringbase;
+ char *ap = argbase;
+ char *tmp = argbase; /* will return this if token found */
+
+ if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
+ switch (slrflag) { /* and $ as token for macro invoke */
+ case 0:
+ slrflag++;
+ stringbase++;
+ return ((*sb == '!') ? "!" : "$");
+ /* NOTREACHED */
+ case 1:
+ slrflag++;
+ altarg = stringbase;
+ break;
+ default:
+ break;
+ }
+ }
+
+S0:
+ switch (*sb) {
+
+ case '\0':
+ goto OUT;
+
+ case ' ':
+ case '\t':
+ sb++; goto S0;
+
+ default:
+ switch (slrflag) {
+ case 0:
+ slrflag++;
+ break;
+ case 1:
+ slrflag++;
+ altarg = sb;
+ break;
+ default:
+ break;
+ }
+ goto S1;
+ }
+
+S1:
+ switch (*sb) {
+
+ case ' ':
+ case '\t':
+ case '\0':
+ goto OUT; /* end of token */
+
+ case '\\':
+ sb++; goto S2; /* slurp next character */
+
+ case '"':
+ sb++; goto S3; /* slurp quoted string */
+
+ default:
+ *ap++ = *sb++; /* add character to token */
+ got_one = 1;
+ goto S1;
+ }
+
+S2:
+ switch (*sb) {
+
+ case '\0':
+ goto OUT;
+
+ default:
+ *ap++ = *sb++;
+ got_one = 1;
+ goto S1;
+ }
+
+S3:
+ switch (*sb) {
+
+ case '\0':
+ goto OUT;
+
+ case '"':
+ sb++; goto S1;
+
+ default:
+ *ap++ = *sb++;
+ got_one = 1;
+ goto S3;
+ }
+
+OUT:
+ if (got_one)
+ *ap++ = '\0';
+ argbase = ap; /* update storage pointer */
+ stringbase = sb; /* update scan pointer */
+ if (got_one) {
+ return (tmp);
+ }
+ switch (slrflag) {
+ case 0:
+ slrflag++;
+ break;
+ case 1:
+ slrflag++;
+ altarg = (char *) 0;
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+#define HELPINDENT ((int) sizeof ("directory"))
+
+/*
+ * Help command.
+ * Call each command handler with argc == 0 and argv[0] == name.
+ */
+void
+help(int argc, char **argv)
+{
+ struct cmd *c;
+
+ if (argc == 1) {
+ int i, j, w, k;
+ int columns, width = 0, lines;
+
+ printf("Commands may be abbreviated. Commands are:\n\n");
+ for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
+ int len = strlen(c->c_name);
+
+ if (len > width)
+ width = len;
+ }
+ width = (width + 8) &~ 7;
+ columns = 80 / width;
+ if (columns == 0)
+ columns = 1;
+ lines = (NCMDS + columns - 1) / columns;
+ for (i = 0; i < lines; i++) {
+ for (j = 0; j < columns; j++) {
+ c = cmdtab + j * lines + i;
+ if (c->c_name && (!proxy || c->c_proxy)) {
+ printf("%s", c->c_name);
+ }
+ else if (c->c_name) {
+ for (k=0; k < strlen(c->c_name); k++) {
+ putchar(' ');
+ }
+ }
+ if (c + lines >= &cmdtab[NCMDS]) {
+ printf("\n");
+ break;
+ }
+ w = strlen(c->c_name);
+ while (w < width) {
+ w = (w + 8) &~ 7;
+ putchar('\t');
+ }
+ }
+ }
+ return;
+ }
+ while (--argc > 0) {
+ char *arg;
+ arg = *++argv;
+ c = getcmd(arg);
+ if (c == (struct cmd *)-1)
+ printf("?Ambiguous help command %s\n", arg);
+ else if (c == (struct cmd *)0)
+ printf("?Invalid help command %s\n", arg);
+ else
+ printf("%-*s\t%s\n", HELPINDENT,
+ c->c_name, c->c_help);
+ }
+}
diff --git a/crypto/heimdal/appl/ftp/ftp/pathnames.h b/crypto/heimdal/appl/ftp/ftp/pathnames.h
new file mode 100644
index 000000000000..f7c1fb391d69
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/pathnames.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/6/93
+ */
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#define _PATH_TMP_XXX "/tmp/ftpXXXXXX"
+
+#ifndef _PATH_BSHELL
+#define _PATH_BSHELL "/bin/sh"
+#endif
diff --git a/crypto/heimdal/appl/ftp/ftp/ruserpass.c b/crypto/heimdal/appl/ftp/ftp/ruserpass.c
new file mode 100644
index 000000000000..b22f6997ee8e
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/ruserpass.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 1985, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#include "ftp_locl.h"
+RCSID("$Id: ruserpass.c,v 1.19 2000/01/08 07:45:11 assar Exp $");
+
+static int token (void);
+static FILE *cfile;
+
+#define DEFAULT 1
+#define LOGIN 2
+#define PASSWD 3
+#define ACCOUNT 4
+#define MACDEF 5
+#define PROT 6
+#define ID 10
+#define MACH 11
+
+static char tokval[100];
+
+static struct toktab {
+ char *tokstr;
+ int tval;
+} toktab[]= {
+ { "default", DEFAULT },
+ { "login", LOGIN },
+ { "password", PASSWD },
+ { "passwd", PASSWD },
+ { "account", ACCOUNT },
+ { "machine", MACH },
+ { "macdef", MACDEF },
+ { "prot", PROT },
+ { NULL, 0 }
+};
+
+/*
+ * Write a copy of the hostname into `hostname, sz' and return a guess
+ * as to the `domain' of that hostname.
+ */
+
+static char *
+guess_domain (char *hostname, size_t sz)
+{
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char *dot;
+
+ if (gethostname (hostname, sz) < 0) {
+ strlcpy (hostname, "", sz);
+ return "";
+ }
+ dot = strchr (hostname, '.');
+ if (dot != NULL)
+ return dot + 1;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+
+ error = getaddrinfo (hostname, NULL, &hints, &ai);
+ if (error)
+ return hostname;
+
+ for (a = ai; a != NULL; a = a->ai_next)
+ if (a->ai_canonname != NULL) {
+ strlcpy (hostname, ai->ai_canonname, sz);
+ break;
+ }
+ freeaddrinfo (ai);
+ dot = strchr (hostname, '.');
+ if (dot != NULL)
+ return dot + 1;
+ else
+ return hostname;
+}
+
+int
+ruserpass(char *host, char **aname, char **apass, char **aacct)
+{
+ char *hdir, buf[BUFSIZ], *tmp;
+ int t, i, c, usedefault = 0;
+ struct stat stb;
+
+ mydomain = guess_domain (myhostname, MaxHostNameLen);
+
+ hdir = getenv("HOME");
+ if (hdir == NULL)
+ hdir = ".";
+ snprintf(buf, sizeof(buf), "%s/.netrc", hdir);
+ cfile = fopen(buf, "r");
+ if (cfile == NULL) {
+ if (errno != ENOENT)
+ warn("%s", buf);
+ return (0);
+ }
+
+next:
+ while ((t = token())) switch(t) {
+
+ case DEFAULT:
+ usedefault = 1;
+ /* FALL THROUGH */
+
+ case MACH:
+ if (!usedefault) {
+ if (token() != ID)
+ continue;
+ /*
+ * Allow match either for user's input host name
+ * or official hostname. Also allow match of
+ * incompletely-specified host in local domain.
+ */
+ if (strcasecmp(host, tokval) == 0)
+ goto match;
+ if (strcasecmp(hostname, tokval) == 0)
+ goto match;
+ if ((tmp = strchr(hostname, '.')) != NULL &&
+ tmp++ &&
+ strcasecmp(tmp, mydomain) == 0 &&
+ strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
+ tokval[tmp - hostname] == '\0')
+ goto match;
+ if ((tmp = strchr(host, '.')) != NULL &&
+ tmp++ &&
+ strcasecmp(tmp, mydomain) == 0 &&
+ strncasecmp(host, tokval, tmp - host) == 0 &&
+ tokval[tmp - host] == '\0')
+ goto match;
+ continue;
+ }
+ match:
+ while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
+
+ case LOGIN:
+ if (token()) {
+ if (*aname == 0) {
+ *aname = strdup(tokval);
+ } else {
+ if (strcmp(*aname, tokval))
+ goto next;
+ }
+ }
+ break;
+ case PASSWD:
+ if ((*aname == NULL || strcmp(*aname, "anonymous")) &&
+ fstat(fileno(cfile), &stb) >= 0 &&
+ (stb.st_mode & 077) != 0) {
+ warnx("Error: .netrc file is readable by others.");
+ warnx("Remove password or make file unreadable by others.");
+ goto bad;
+ }
+ if (token() && *apass == 0) {
+ *apass = strdup(tokval);
+ }
+ break;
+ case ACCOUNT:
+ if (fstat(fileno(cfile), &stb) >= 0
+ && (stb.st_mode & 077) != 0) {
+ warnx("Error: .netrc file is readable by others.");
+ warnx("Remove account or make file unreadable by others.");
+ goto bad;
+ }
+ if (token() && *aacct == 0) {
+ *aacct = strdup(tokval);
+ }
+ break;
+ case MACDEF:
+ if (proxy) {
+ fclose(cfile);
+ return (0);
+ }
+ while ((c=getc(cfile)) != EOF &&
+ (c == ' ' || c == '\t'));
+ if (c == EOF || c == '\n') {
+ printf("Missing macdef name argument.\n");
+ goto bad;
+ }
+ if (macnum == 16) {
+ printf("Limit of 16 macros have already been defined\n");
+ goto bad;
+ }
+ tmp = macros[macnum].mac_name;
+ *tmp++ = c;
+ for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
+ !isspace(c); ++i) {
+ *tmp++ = c;
+ }
+ if (c == EOF) {
+ printf("Macro definition missing null line terminator.\n");
+ goto bad;
+ }
+ *tmp = '\0';
+ if (c != '\n') {
+ while ((c=getc(cfile)) != EOF && c != '\n');
+ }
+ if (c == EOF) {
+ printf("Macro definition missing null line terminator.\n");
+ goto bad;
+ }
+ if (macnum == 0) {
+ macros[macnum].mac_start = macbuf;
+ }
+ else {
+ macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
+ }
+ tmp = macros[macnum].mac_start;
+ while (tmp != macbuf + 4096) {
+ if ((c=getc(cfile)) == EOF) {
+ printf("Macro definition missing null line terminator.\n");
+ goto bad;
+ }
+ *tmp = c;
+ if (*tmp == '\n') {
+ if (*(tmp-1) == '\0') {
+ macros[macnum++].mac_end = tmp - 1;
+ break;
+ }
+ *tmp = '\0';
+ }
+ tmp++;
+ }
+ if (tmp == macbuf + 4096) {
+ printf("4K macro buffer exceeded\n");
+ goto bad;
+ }
+ break;
+ case PROT:
+ token();
+ if(sec_request_prot(tokval) < 0)
+ warnx("Unknown protection level \"%s\"", tokval);
+ break;
+ default:
+ warnx("Unknown .netrc keyword %s", tokval);
+ break;
+ }
+ goto done;
+ }
+done:
+ fclose(cfile);
+ return (0);
+bad:
+ fclose(cfile);
+ return (-1);
+}
+
+static int
+token(void)
+{
+ char *cp;
+ int c;
+ struct toktab *t;
+
+ if (feof(cfile) || ferror(cfile))
+ return (0);
+ while ((c = getc(cfile)) != EOF &&
+ (c == '\n' || c == '\t' || c == ' ' || c == ','))
+ continue;
+ if (c == EOF)
+ return (0);
+ cp = tokval;
+ if (c == '"') {
+ while ((c = getc(cfile)) != EOF && c != '"') {
+ if (c == '\\')
+ c = getc(cfile);
+ *cp++ = c;
+ }
+ } else {
+ *cp++ = c;
+ while ((c = getc(cfile)) != EOF
+ && c != '\n' && c != '\t' && c != ' ' && c != ',') {
+ if (c == '\\')
+ c = getc(cfile);
+ *cp++ = c;
+ }
+ }
+ *cp = 0;
+ if (tokval[0] == 0)
+ return (0);
+ for (t = toktab; t->tokstr; t++)
+ if (!strcmp(t->tokstr, tokval))
+ return (t->tval);
+ return (ID);
+}
diff --git a/crypto/heimdal/appl/ftp/ftp/security.c b/crypto/heimdal/appl/ftp/ftp/security.c
new file mode 100644
index 000000000000..ca7eb0036a53
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/security.c
@@ -0,0 +1,785 @@
+/*
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef FTP_SERVER
+#include "ftpd_locl.h"
+#else
+#include "ftp_locl.h"
+#endif
+
+RCSID("$Id: security.c,v 1.15 1999/12/02 16:58:30 joda Exp $");
+
+static enum protection_level command_prot;
+static enum protection_level data_prot;
+static size_t buffer_size;
+
+struct buffer {
+ void *data;
+ size_t size;
+ size_t index;
+ int eof_flag;
+};
+
+static struct buffer in_buffer, out_buffer;
+int sec_complete;
+
+static struct {
+ enum protection_level level;
+ const char *name;
+} level_names[] = {
+ { prot_clear, "clear" },
+ { prot_safe, "safe" },
+ { prot_confidential, "confidential" },
+ { prot_private, "private" }
+};
+
+static const char *
+level_to_name(enum protection_level level)
+{
+ int i;
+ for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++)
+ if(level_names[i].level == level)
+ return level_names[i].name;
+ return "unknown";
+}
+
+#ifndef FTP_SERVER /* not used in server */
+static enum protection_level
+name_to_level(const char *name)
+{
+ int i;
+ for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++)
+ if(!strncasecmp(level_names[i].name, name, strlen(name)))
+ return level_names[i].level;
+ return (enum protection_level)-1;
+}
+#endif
+
+#ifdef FTP_SERVER
+
+static struct sec_server_mech *mechs[] = {
+#ifdef KRB5
+ &gss_server_mech,
+#endif
+#ifdef KRB4
+ &krb4_server_mech,
+#endif
+ NULL
+};
+
+static struct sec_server_mech *mech;
+
+#else
+
+static struct sec_client_mech *mechs[] = {
+#ifdef KRB5
+ &gss_client_mech,
+#endif
+#ifdef KRB4
+ &krb4_client_mech,
+#endif
+ NULL
+};
+
+static struct sec_client_mech *mech;
+
+#endif
+
+static void *app_data;
+
+int
+sec_getc(FILE *F)
+{
+ if(sec_complete && data_prot) {
+ char c;
+ if(sec_read(fileno(F), &c, 1) <= 0)
+ return EOF;
+ return c;
+ } else
+ return getc(F);
+}
+
+static int
+block_read(int fd, void *buf, size_t len)
+{
+ unsigned char *p = buf;
+ int b;
+ while(len) {
+ b = read(fd, p, len);
+ if (b == 0)
+ return 0;
+ else if (b < 0)
+ return -1;
+ len -= b;
+ p += b;
+ }
+ return p - (unsigned char*)buf;
+}
+
+static int
+block_write(int fd, void *buf, size_t len)
+{
+ unsigned char *p = buf;
+ int b;
+ while(len) {
+ b = write(fd, p, len);
+ if(b < 0)
+ return -1;
+ len -= b;
+ p += b;
+ }
+ return p - (unsigned char*)buf;
+}
+
+static int
+sec_get_data(int fd, struct buffer *buf, int level)
+{
+ int len;
+ int b;
+
+ b = block_read(fd, &len, sizeof(len));
+ if (b == 0)
+ return 0;
+ else if (b < 0)
+ return -1;
+ len = ntohl(len);
+ buf->data = realloc(buf->data, len);
+ b = block_read(fd, buf->data, len);
+ if (b == 0)
+ return 0;
+ else if (b < 0)
+ return -1;
+ buf->size = (*mech->decode)(app_data, buf->data, len, data_prot);
+ buf->index = 0;
+ return 0;
+}
+
+static size_t
+buffer_read(struct buffer *buf, void *data, size_t len)
+{
+ len = min(len, buf->size - buf->index);
+ memcpy(data, (char*)buf->data + buf->index, len);
+ buf->index += len;
+ return len;
+}
+
+static size_t
+buffer_write(struct buffer *buf, void *data, size_t len)
+{
+ if(buf->index + len > buf->size) {
+ void *tmp;
+ if(buf->data == NULL)
+ tmp = malloc(1024);
+ else
+ tmp = realloc(buf->data, buf->index + len);
+ if(tmp == NULL)
+ return -1;
+ buf->data = tmp;
+ buf->size = buf->index + len;
+ }
+ memcpy((char*)buf->data + buf->index, data, len);
+ buf->index += len;
+ return len;
+}
+
+int
+sec_read(int fd, void *data, int length)
+{
+ size_t len;
+ int rx = 0;
+
+ if(sec_complete == 0 || data_prot == 0)
+ return read(fd, data, length);
+
+ if(in_buffer.eof_flag){
+ in_buffer.eof_flag = 0;
+ return 0;
+ }
+
+ len = buffer_read(&in_buffer, data, length);
+ length -= len;
+ rx += len;
+ data = (char*)data + len;
+
+ while(length){
+ if(sec_get_data(fd, &in_buffer, data_prot) < 0)
+ return -1;
+ if(in_buffer.size == 0) {
+ if(rx)
+ in_buffer.eof_flag = 1;
+ return rx;
+ }
+ len = buffer_read(&in_buffer, data, length);
+ length -= len;
+ rx += len;
+ data = (char*)data + len;
+ }
+ return rx;
+}
+
+static int
+sec_send(int fd, char *from, int length)
+{
+ int bytes;
+ void *buf;
+ bytes = (*mech->encode)(app_data, from, length, data_prot, &buf);
+ bytes = htonl(bytes);
+ block_write(fd, &bytes, sizeof(bytes));
+ block_write(fd, buf, ntohl(bytes));
+ free(buf);
+ return length;
+}
+
+int
+sec_fflush(FILE *F)
+{
+ if(data_prot != prot_clear) {
+ if(out_buffer.index > 0){
+ sec_write(fileno(F), out_buffer.data, out_buffer.index);
+ out_buffer.index = 0;
+ }
+ sec_send(fileno(F), NULL, 0);
+ }
+ fflush(F);
+ return 0;
+}
+
+int
+sec_write(int fd, char *data, int length)
+{
+ int len = buffer_size;
+ int tx = 0;
+
+ if(data_prot == prot_clear)
+ return write(fd, data, length);
+
+ len -= (*mech->overhead)(app_data, data_prot, len);
+ while(length){
+ if(length < len)
+ len = length;
+ sec_send(fd, data, len);
+ length -= len;
+ data += len;
+ tx += len;
+ }
+ return tx;
+}
+
+int
+sec_vfprintf2(FILE *f, const char *fmt, va_list ap)
+{
+ char *buf;
+ int ret;
+ if(data_prot == prot_clear)
+ return vfprintf(f, fmt, ap);
+ else {
+ vasprintf(&buf, fmt, ap);
+ ret = buffer_write(&out_buffer, buf, strlen(buf));
+ free(buf);
+ return ret;
+ }
+}
+
+int
+sec_fprintf2(FILE *f, const char *fmt, ...)
+{
+ int ret;
+ va_list ap;
+ va_start(ap, fmt);
+ ret = sec_vfprintf2(f, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+sec_putc(int c, FILE *F)
+{
+ char ch = c;
+ if(data_prot == prot_clear)
+ return putc(c, F);
+
+ buffer_write(&out_buffer, &ch, 1);
+ if(c == '\n' || out_buffer.index >= 1024 /* XXX */) {
+ sec_write(fileno(F), out_buffer.data, out_buffer.index);
+ out_buffer.index = 0;
+ }
+ return c;
+}
+
+int
+sec_read_msg(char *s, int level)
+{
+ int len;
+ char *buf;
+ int code;
+
+ buf = malloc(strlen(s));
+ len = base64_decode(s + 4, buf); /* XXX */
+
+ len = (*mech->decode)(app_data, buf, len, level);
+ if(len < 0)
+ return -1;
+
+ buf[len] = '\0';
+
+ if(buf[3] == '-')
+ code = 0;
+ else
+ sscanf(buf, "%d", &code);
+ if(buf[len-1] == '\n')
+ buf[len-1] = '\0';
+ strcpy(s, buf);
+ free(buf);
+ return code;
+}
+
+int
+sec_vfprintf(FILE *f, const char *fmt, va_list ap)
+{
+ char *buf;
+ void *enc;
+ int len;
+ if(!sec_complete)
+ return vfprintf(f, fmt, ap);
+
+ vasprintf(&buf, fmt, ap);
+ len = (*mech->encode)(app_data, buf, strlen(buf), command_prot, &enc);
+ free(buf);
+ if(len < 0) {
+ printf("Failed to encode command.\n");
+ return -1;
+ }
+ if(base64_encode(enc, len, &buf) < 0){
+ printf("Out of memory base64-encoding.\n");
+ return -1;
+ }
+#ifdef FTP_SERVER
+ if(command_prot == prot_safe)
+ fprintf(f, "631 %s\r\n", buf);
+ else if(command_prot == prot_private)
+ fprintf(f, "632 %s\r\n", buf);
+ else if(command_prot == prot_confidential)
+ fprintf(f, "633 %s\r\n", buf);
+#else
+ if(command_prot == prot_safe)
+ fprintf(f, "MIC %s", buf);
+ else if(command_prot == prot_private)
+ fprintf(f, "ENC %s", buf);
+ else if(command_prot == prot_confidential)
+ fprintf(f, "CONF %s", buf);
+#endif
+ free(buf);
+ return 0;
+}
+
+int
+sec_fprintf(FILE *f, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, fmt);
+ ret = sec_vfprintf(f, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+/* end common stuff */
+
+#ifdef FTP_SERVER
+
+void
+auth(char *auth_name)
+{
+ int i;
+ for(i = 0; (mech = mechs[i]) != NULL; i++){
+ if(!strcasecmp(auth_name, mech->name)){
+ app_data = realloc(app_data, mech->size);
+ if(mech->init && (*mech->init)(app_data) != 0) {
+ reply(431, "Unable to accept %s at this time", mech->name);
+ return;
+ }
+ if(mech->auth) {
+ (*mech->auth)(app_data);
+ return;
+ }
+ if(mech->adat)
+ reply(334, "Send authorization data.");
+ else
+ reply(234, "Authorization complete.");
+ return;
+ }
+ }
+ free (app_data);
+ reply(504, "%s is unknown to me", auth_name);
+}
+
+void
+adat(char *auth_data)
+{
+ if(mech && !sec_complete) {
+ void *buf = malloc(strlen(auth_data));
+ size_t len;
+ len = base64_decode(auth_data, buf);
+ (*mech->adat)(app_data, buf, len);
+ free(buf);
+ } else
+ reply(503, "You must %sissue an AUTH first.", mech ? "re-" : "");
+}
+
+void pbsz(int size)
+{
+ size_t new = size;
+ if(!sec_complete)
+ reply(503, "Incomplete security data exchange.");
+ if(mech->pbsz)
+ new = (*mech->pbsz)(app_data, size);
+ if(buffer_size != new){
+ buffer_size = size;
+ }
+ if(new != size)
+ reply(200, "PBSZ=%lu", (unsigned long)new);
+ else
+ reply(200, "OK");
+}
+
+void
+prot(char *pl)
+{
+ int p = -1;
+
+ if(buffer_size == 0){
+ reply(503, "No protection buffer size negotiated.");
+ return;
+ }
+
+ if(!strcasecmp(pl, "C"))
+ p = prot_clear;
+ else if(!strcasecmp(pl, "S"))
+ p = prot_safe;
+ else if(!strcasecmp(pl, "E"))
+ p = prot_confidential;
+ else if(!strcasecmp(pl, "P"))
+ p = prot_private;
+ else {
+ reply(504, "Unrecognized protection level.");
+ return;
+ }
+
+ if(sec_complete){
+ if((*mech->check_prot)(app_data, p)){
+ reply(536, "%s does not support %s protection.",
+ mech->name, level_to_name(p));
+ }else{
+ data_prot = (enum protection_level)p;
+ reply(200, "Data protection is %s.", level_to_name(p));
+ }
+ }else{
+ reply(503, "Incomplete security data exchange.");
+ }
+}
+
+void ccc(void)
+{
+ if(sec_complete){
+ if(mech->ccc && (*mech->ccc)(app_data) == 0)
+ command_prot = data_prot = prot_clear;
+ else
+ reply(534, "You must be joking.");
+ }else
+ reply(503, "Incomplete security data exchange.");
+}
+
+void mec(char *msg, enum protection_level level)
+{
+ void *buf;
+ size_t len;
+ if(!sec_complete) {
+ reply(503, "Incomplete security data exchange.");
+ return;
+ }
+ buf = malloc(strlen(msg) + 2); /* XXX go figure out where that 2
+ comes from :-) */
+ len = base64_decode(msg, buf);
+ command_prot = level;
+ if(len == (size_t)-1) {
+ reply(501, "Failed to base64-decode command");
+ return;
+ }
+ len = (*mech->decode)(app_data, buf, len, level);
+ if(len == (size_t)-1) {
+ reply(535, "Failed to decode command");
+ return;
+ }
+ ((char*)buf)[len] = '\0';
+ if(strstr((char*)buf, "\r\n") == NULL)
+ strcat((char*)buf, "\r\n");
+ new_ftp_command(buf);
+}
+
+/* ------------------------------------------------------------ */
+
+int
+sec_userok(char *user)
+{
+ if(sec_complete)
+ return (*mech->userok)(app_data, user);
+ return 0;
+}
+
+char *ftp_command;
+
+void
+new_ftp_command(char *command)
+{
+ ftp_command = command;
+}
+
+void
+delete_ftp_command(void)
+{
+ free(ftp_command);
+ ftp_command = NULL;
+}
+
+int
+secure_command(void)
+{
+ return ftp_command != NULL;
+}
+
+enum protection_level
+get_command_prot(void)
+{
+ return command_prot;
+}
+
+#else /* FTP_SERVER */
+
+void
+sec_status(void)
+{
+ if(sec_complete){
+ printf("Using %s for authentication.\n", mech->name);
+ printf("Using %s command channel.\n", level_to_name(command_prot));
+ printf("Using %s data channel.\n", level_to_name(data_prot));
+ if(buffer_size > 0)
+ printf("Protection buffer size: %lu.\n",
+ (unsigned long)buffer_size);
+ }else{
+ printf("Not using any security mechanism.\n");
+ }
+}
+
+static int
+sec_prot_internal(int level)
+{
+ int ret;
+ char *p;
+ unsigned int s = 1048576;
+
+ int old_verbose = verbose;
+ verbose = 0;
+
+ if(!sec_complete){
+ printf("No security data exchange has taken place.\n");
+ return -1;
+ }
+
+ if(level){
+ ret = command("PBSZ %u", s);
+ if(ret != COMPLETE){
+ printf("Failed to set protection buffer size.\n");
+ return -1;
+ }
+ buffer_size = s;
+ p = strstr(reply_string, "PBSZ=");
+ if(p)
+ sscanf(p, "PBSZ=%u", &s);
+ if(s < buffer_size)
+ buffer_size = s;
+ }
+ verbose = old_verbose;
+ ret = command("PROT %c", level["CSEP"]); /* XXX :-) */
+ if(ret != COMPLETE){
+ printf("Failed to set protection level.\n");
+ return -1;
+ }
+
+ data_prot = (enum protection_level)level;
+ return 0;
+}
+
+enum protection_level
+set_command_prot(enum protection_level level)
+{
+ enum protection_level old = command_prot;
+ command_prot = level;
+ return old;
+}
+
+void
+sec_prot(int argc, char **argv)
+{
+ int level = -1;
+
+ if(argc < 2 || argc > 3)
+ goto usage;
+ if(!sec_complete) {
+ printf("No security data exchange has taken place.\n");
+ code = -1;
+ return;
+ }
+ level = name_to_level(argv[argc - 1]);
+
+ if(level == -1)
+ goto usage;
+
+ if((*mech->check_prot)(app_data, level)) {
+ printf("%s does not implement %s protection.\n",
+ mech->name, level_to_name(level));
+ code = -1;
+ return;
+ }
+
+ if(argc == 2 || strncasecmp(argv[1], "data", strlen(argv[1])) == 0) {
+ if(sec_prot_internal(level) < 0){
+ code = -1;
+ return;
+ }
+ } else if(strncasecmp(argv[1], "command", strlen(argv[1])) == 0)
+ set_command_prot(level);
+ else
+ goto usage;
+ code = 0;
+ return;
+ usage:
+ printf("usage: %s [command|data] [clear|safe|confidential|private]\n",
+ argv[0]);
+ code = -1;
+}
+
+static enum protection_level request_data_prot;
+
+void
+sec_set_protection_level(void)
+{
+ if(sec_complete && data_prot != request_data_prot)
+ sec_prot_internal(request_data_prot);
+}
+
+
+int
+sec_request_prot(char *level)
+{
+ int l = name_to_level(level);
+ if(l == -1)
+ return -1;
+ request_data_prot = (enum protection_level)l;
+ return 0;
+}
+
+int
+sec_login(char *host)
+{
+ int ret;
+ struct sec_client_mech **m;
+ int old_verbose = verbose;
+
+ verbose = -1; /* shut up all messages this will produce (they
+ are usually not very user friendly) */
+
+ for(m = mechs; *m && (*m)->name; m++) {
+ void *tmp;
+
+ tmp = realloc(app_data, (*m)->size);
+ if (tmp == NULL) {
+ warnx ("realloc %u failed", (*m)->size);
+ return -1;
+ }
+ app_data = tmp;
+
+ if((*m)->init && (*(*m)->init)(app_data) != 0) {
+ printf("Skipping %s...\n", (*m)->name);
+ continue;
+ }
+ printf("Trying %s...\n", (*m)->name);
+ ret = command("AUTH %s", (*m)->name);
+ if(ret != CONTINUE){
+ if(code == 504){
+ printf("%s is not supported by the server.\n", (*m)->name);
+ }else if(code == 534){
+ printf("%s rejected as security mechanism.\n", (*m)->name);
+ }else if(ret == ERROR) {
+ printf("The server doesn't support the FTP "
+ "security extensions.\n");
+ verbose = old_verbose;
+ return -1;
+ }
+ continue;
+ }
+
+ ret = (*(*m)->auth)(app_data, host);
+
+ if(ret == AUTH_CONTINUE)
+ continue;
+ else if(ret != AUTH_OK){
+ /* mechanism is supposed to output error string */
+ verbose = old_verbose;
+ return -1;
+ }
+ mech = *m;
+ sec_complete = 1;
+ command_prot = prot_safe;
+ break;
+ }
+
+ verbose = old_verbose;
+ return *m == NULL;
+}
+
+void
+sec_end(void)
+{
+ if (mech != NULL) {
+ if(mech->end)
+ (*mech->end)(app_data);
+ memset(app_data, 0, mech->size);
+ free(app_data);
+ app_data = NULL;
+ }
+ sec_complete = 0;
+ data_prot = (enum protection_level)0;
+}
+
+#endif /* FTP_SERVER */
+
diff --git a/crypto/heimdal/appl/ftp/ftp/security.h b/crypto/heimdal/appl/ftp/ftp/security.h
new file mode 100644
index 000000000000..6fe06946c570
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftp/security.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: security.h,v 1.7 1999/12/02 16:58:30 joda Exp $ */
+
+#ifndef __security_h__
+#define __security_h__
+
+enum protection_level {
+ prot_clear,
+ prot_safe,
+ prot_confidential,
+ prot_private
+};
+
+struct sec_client_mech {
+ char *name;
+ size_t size;
+ int (*init)(void *);
+ int (*auth)(void *, char*);
+ void (*end)(void *);
+ int (*check_prot)(void *, int);
+ int (*overhead)(void *, int, int);
+ int (*encode)(void *, void*, int, int, void**);
+ int (*decode)(void *, void*, int, int);
+};
+
+struct sec_server_mech {
+ char *name;
+ size_t size;
+ int (*init)(void *);
+ void (*end)(void *);
+ int (*check_prot)(void *, int);
+ int (*overhead)(void *, int, int);
+ int (*encode)(void *, void*, int, int, void**);
+ int (*decode)(void *, void*, int, int);
+
+ int (*auth)(void *);
+ int (*adat)(void *, void*, size_t);
+ size_t (*pbsz)(void *, size_t);
+ int (*ccc)(void*);
+ int (*userok)(void*, char*);
+};
+
+#define AUTH_OK 0
+#define AUTH_CONTINUE 1
+#define AUTH_ERROR 2
+
+#ifdef FTP_SERVER
+extern struct sec_server_mech krb4_server_mech, gss_server_mech;
+#else
+extern struct sec_client_mech krb4_client_mech, gss_client_mech;
+#endif
+
+extern int sec_complete;
+
+#ifdef FTP_SERVER
+extern char *ftp_command;
+void new_ftp_command(char*);
+void delete_ftp_command(void);
+#endif
+
+/* ---- */
+
+
+int sec_fflush (FILE *);
+int sec_fprintf (FILE *, const char *, ...);
+int sec_getc (FILE *);
+int sec_putc (int, FILE *);
+int sec_read (int, void *, int);
+int sec_read_msg (char *, int);
+int sec_vfprintf (FILE *, const char *, va_list);
+int sec_fprintf2(FILE *f, const char *fmt, ...);
+int sec_vfprintf2(FILE *, const char *, va_list);
+int sec_write (int, char *, int);
+
+#ifdef FTP_SERVER
+void adat (char *);
+void auth (char *);
+void ccc (void);
+void mec (char *, enum protection_level);
+void pbsz (int);
+void prot (char *);
+void delete_ftp_command (void);
+void new_ftp_command (char *);
+int sec_userok (char *);
+int secure_command (void);
+enum protection_level get_command_prot(void);
+#else
+void sec_end (void);
+int sec_login (char *);
+void sec_prot (int, char **);
+int sec_request_prot (char *);
+void sec_set_protection_level (void);
+void sec_status (void);
+
+enum protection_level set_command_prot(enum protection_level);
+
+#endif
+
+#endif /* __security_h__ */
diff --git a/crypto/heimdal/appl/ftp/ftpd/Makefile.am b/crypto/heimdal/appl/ftp/ftpd/Makefile.am
new file mode 100644
index 000000000000..92d8e7c40d4f
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/Makefile.am
@@ -0,0 +1,56 @@
+# $Id: Makefile.am,v 1.21 2000/01/06 15:10:57 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += -I$(srcdir)/../common $(INCLUDE_krb4) -DFTP_SERVER
+
+libexec_PROGRAMS = ftpd
+
+CHECK_LOCAL =
+
+if KRB4
+krb4_sources = krb4.c kauth.c
+endif
+if KRB5
+krb5_sources = gssapi.c gss_userok.c
+endif
+
+ftpd_SOURCES = \
+ extern.h \
+ ftpcmd.y \
+ ftpd.c \
+ ftpd_locl.h \
+ logwtmp.c \
+ ls.c \
+ pathnames.h \
+ popen.c \
+ security.c \
+ $(krb4_sources) \
+ $(krb5_sources)
+
+EXTRA_ftpd_SOURCES = krb4.c kauth.c gssapi.c gss_userok.c
+
+$(ftpd_OBJECTS): security.h
+
+security.c:
+ @test -f security.c || $(LN_S) $(srcdir)/../ftp/security.c .
+security.h:
+ @test -f security.h || $(LN_S) $(srcdir)/../ftp/security.h .
+krb4.c:
+ @test -f krb4.c || $(LN_S) $(srcdir)/../ftp/krb4.c .
+gssapi.c:
+ @test -f gssapi.c || $(LN_S) $(srcdir)/../ftp/gssapi.c .
+
+CLEANFILES = security.c security.h krb4.c gssapi.c ftpcmd.c
+
+man_MANS = ftpd.8 ftpusers.5
+
+LDADD = ../common/libcommon.a \
+ $(LIB_kafs) \
+ $(LIB_gssapi) \
+ $(LIB_krb5) \
+ $(LIB_krb4) \
+ $(LIB_otp) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(LIB_roken) \
+ $(DBLIB)
diff --git a/crypto/heimdal/appl/ftp/ftpd/Makefile.in b/crypto/heimdal/appl/ftp/ftpd/Makefile.in
new file mode 100644
index 000000000000..1cd211bfc0c3
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/Makefile.in
@@ -0,0 +1,768 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.21 2000/01/06 15:10:57 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include -I$(srcdir)/../common $(INCLUDE_krb4) -DFTP_SERVER
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL =
+
+libexec_PROGRAMS = ftpd
+
+@KRB4_TRUE@krb4_sources = krb4.c kauth.c
+@KRB5_TRUE@krb5_sources = gssapi.c gss_userok.c
+
+ftpd_SOURCES = extern.h ftpcmd.y ftpd.c ftpd_locl.h logwtmp.c ls.c pathnames.h popen.c security.c $(krb4_sources) $(krb5_sources)
+
+
+EXTRA_ftpd_SOURCES = krb4.c kauth.c gssapi.c gss_userok.c
+
+CLEANFILES = security.c security.h krb4.c gssapi.c ftpcmd.c
+
+man_MANS = ftpd.8 ftpusers.5
+
+LDADD = ../common/libcommon.a $(LIB_kafs) $(LIB_gssapi) $(LIB_krb5) $(LIB_krb4) $(LIB_otp) $(top_builddir)/lib/des/libdes.la $(LIB_roken) $(DBLIB)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../../include/config.h
+CONFIG_CLEAN_FILES =
+libexec_PROGRAMS = ftpd$(EXEEXT)
+PROGRAMS = $(libexec_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+@KRB4_TRUE@@KRB5_FALSE@ftpd_OBJECTS = ftpcmd.$(OBJEXT) ftpd.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_FALSE@logwtmp.$(OBJEXT) ls.$(OBJEXT) popen.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_FALSE@security.$(OBJEXT) krb4.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_FALSE@kauth.$(OBJEXT)
+@KRB4_FALSE@@KRB5_TRUE@ftpd_OBJECTS = ftpcmd.$(OBJEXT) ftpd.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_TRUE@logwtmp.$(OBJEXT) ls.$(OBJEXT) popen.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_TRUE@security.$(OBJEXT) gssapi.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_TRUE@gss_userok.$(OBJEXT)
+@KRB4_FALSE@@KRB5_FALSE@ftpd_OBJECTS = ftpcmd.$(OBJEXT) ftpd.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_FALSE@logwtmp.$(OBJEXT) ls.$(OBJEXT) popen.$(OBJEXT) \
+@KRB4_FALSE@@KRB5_FALSE@security.$(OBJEXT)
+@KRB4_TRUE@@KRB5_TRUE@ftpd_OBJECTS = ftpcmd.$(OBJEXT) ftpd.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_TRUE@logwtmp.$(OBJEXT) ls.$(OBJEXT) popen.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_TRUE@security.$(OBJEXT) krb4.$(OBJEXT) kauth.$(OBJEXT) \
+@KRB4_TRUE@@KRB5_TRUE@gssapi.$(OBJEXT) gss_userok.$(OBJEXT)
+ftpd_LDADD = $(LDADD)
+@KRB4_TRUE@@KRB5_FALSE@ftpd_DEPENDENCIES = ../common/libcommon.a \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_TRUE@ftpd_DEPENDENCIES = ../common/libcommon.a \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/gssapi/libgssapi.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_FALSE@ftpd_DEPENDENCIES = ../common/libcommon.a \
+@KRB4_FALSE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_TRUE@@KRB5_TRUE@ftpd_DEPENDENCIES = ../common/libcommon.a \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/gssapi/libgssapi.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+ftpd_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+MANS = $(man_MANS)
+DIST_COMMON = Makefile.am Makefile.in ftpcmd.c
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(ftpd_SOURCES) $(EXTRA_ftpd_SOURCES)
+OBJECTS = $(ftpd_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x .y
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/ftp/ftpd/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libexecPROGRAMS:
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+
+distclean-libexecPROGRAMS:
+
+maintainer-clean-libexecPROGRAMS:
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+ftpd$(EXEEXT): $(ftpd_OBJECTS) $(ftpd_DEPENDENCIES)
+ @rm -f ftpd$(EXEEXT)
+ $(LINK) $(ftpd_LDFLAGS) $(ftpd_OBJECTS) $(ftpd_LDADD) $(LIBS)
+.y.c:
+ $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c
+ if test -f y.tab.h; then \
+ if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
+ else :; fi
+ftpcmd.h: ftpcmd.c
+
+
+install-man5:
+ $(mkinstalldirs) $(DESTDIR)$(man5dir)
+ @list='$(man5_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst; \
+ done
+
+uninstall-man5:
+ @list='$(man5_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man5dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man5dir)/$$inst; \
+ done
+
+install-man8:
+ $(mkinstalldirs) $(DESTDIR)$(man8dir)
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
+ done
+
+uninstall-man8:
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man8dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man5 install-man8
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man5 uninstall-man8
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/ftp/ftpd
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libexecPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-man install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libexecPROGRAMS uninstall-man
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(MANS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir) $(DESTDIR)$(mandir)/man5 \
+ $(DESTDIR)$(mandir)/man8
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ -test -z "ftpcmdhftpcmdc" || rm -f ftpcmdh ftpcmdc
+mostlyclean-am: mostlyclean-libexecPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libexecPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libexecPROGRAMS distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libexecPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libexecPROGRAMS distclean-libexecPROGRAMS \
+clean-libexecPROGRAMS maintainer-clean-libexecPROGRAMS \
+uninstall-libexecPROGRAMS install-libexecPROGRAMS mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool install-man5 uninstall-man5 install-man8 \
+uninstall-man8 install-man uninstall-man tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+$(ftpd_OBJECTS): security.h
+
+security.c:
+ @test -f security.c || $(LN_S) $(srcdir)/../ftp/security.c .
+security.h:
+ @test -f security.h || $(LN_S) $(srcdir)/../ftp/security.h .
+krb4.c:
+ @test -f krb4.c || $(LN_S) $(srcdir)/../ftp/krb4.c .
+gssapi.c:
+ @test -f gssapi.c || $(LN_S) $(srcdir)/../ftp/gssapi.c .
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/ftp/ftpd/extern.h b/crypto/heimdal/appl/ftp/ftpd/extern.h
new file mode 100644
index 000000000000..2e1e0d08c432
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/extern.h
@@ -0,0 +1,160 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)extern.h 8.2 (Berkeley) 4/4/94
+ */
+
+#ifndef _EXTERN_H_
+#define _EXTERN_H_
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifndef NBBY
+#define NBBY CHAR_BIT
+#endif
+
+void abor(void);
+void blkfree(char **);
+char **copyblk(char **);
+void cwd(char *);
+void do_delete(char *);
+void dologout(int);
+void eprt(char *);
+void epsv(char *);
+void fatal(char *);
+int filename_check(char *);
+int ftpd_pclose(FILE *);
+FILE *ftpd_popen(char *, char *, int, int);
+char *ftpd_getline(char *, int);
+void ftpd_logwtmp(char *, char *, char *);
+void lreply(int, const char *, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 2, 3)))
+#endif
+;
+void makedir(char *);
+void nack(char *);
+void nreply(const char *, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 1, 2)))
+#endif
+;
+void pass(char *);
+void pasv(void);
+void perror_reply(int, const char *);
+void pwd(void);
+void removedir(char *);
+void renamecmd(char *, char *);
+char *renamefrom(char *);
+void reply(int, const char *, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 2, 3)))
+#endif
+;
+void retrieve(const char *, char *);
+void send_file_list(char *);
+void setproctitle(const char *, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 1, 2)))
+#endif
+;
+void statcmd(void);
+void statfilecmd(char *);
+void do_store(char *, char *, int);
+void upper(char *);
+void user(char *);
+void yyerror(char *);
+
+void list_file(char*);
+
+void kauth(char *, char*);
+void klist(void);
+void cond_kdestroy(void);
+void kdestroy(void);
+void krbtkfile(const char *tkfile);
+void afslog(const char *cell);
+void afsunlog(void);
+
+int find(char *);
+
+void builtin_ls(FILE*, const char*);
+
+int do_login(int code, char *passwd);
+int klogin(char *name, char *password);
+
+const char *ftp_rooted(const char *path);
+
+extern struct sockaddr *ctrl_addr, *his_addr;
+extern char hostname[];
+
+extern struct sockaddr *data_dest;
+extern int logged_in;
+extern struct passwd *pw;
+extern int guest;
+extern int logging;
+extern int type;
+extern int oobflag;
+extern off_t file_size;
+extern off_t byte_count;
+extern jmp_buf urgcatch;
+
+extern int form;
+extern int debug;
+extern int ftpd_timeout;
+extern int maxtimeout;
+extern int pdata;
+extern char hostname[], remotehost[];
+extern char proctitle[];
+extern int usedefault;
+extern int transflag;
+extern char tmpline[];
+
+#endif /* _EXTERN_H_ */
diff --git a/crypto/heimdal/appl/ftp/ftpd/ftpcmd.y b/crypto/heimdal/appl/ftp/ftpd/ftpcmd.y
new file mode 100644
index 000000000000..07ff9a5b2d8d
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/ftpcmd.y
@@ -0,0 +1,1455 @@
+/* $NetBSD: ftpcmd.y,v 1.6 1995/06/03 22:46:45 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1985, 1988, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)ftpcmd.y 8.3 (Berkeley) 4/6/94
+ */
+
+/*
+ * Grammar for FTP commands.
+ * See RFC 959.
+ */
+
+%{
+
+#include "ftpd_locl.h"
+RCSID("$Id: ftpcmd.y,v 1.56 1999/10/26 11:56:23 assar Exp $");
+
+off_t restart_point;
+
+static int cmd_type;
+static int cmd_form;
+static int cmd_bytesz;
+char cbuf[2048];
+char *fromname;
+
+struct tab {
+ char *name;
+ short token;
+ short state;
+ short implemented; /* 1 if command is implemented */
+ char *help;
+};
+
+extern struct tab cmdtab[];
+extern struct tab sitetab[];
+
+static char *copy (char *);
+static void help (struct tab *, char *);
+static struct tab *
+ lookup (struct tab *, char *);
+static void sizecmd (char *);
+static RETSIGTYPE toolong (int);
+static int yylex (void);
+
+/* This is for bison */
+
+#if !defined(alloca) && !defined(HAVE_ALLOCA)
+#define alloca(x) malloc(x)
+#endif
+
+%}
+
+%union {
+ int i;
+ char *s;
+}
+
+%token
+ A B C E F I
+ L N P R S T
+
+ SP CRLF COMMA
+
+ USER PASS ACCT REIN QUIT PORT
+ PASV TYPE STRU MODE RETR STOR
+ APPE MLFL MAIL MSND MSOM MSAM
+ MRSQ MRCP ALLO REST RNFR RNTO
+ ABOR DELE CWD LIST NLST SITE
+ sTAT HELP NOOP MKD RMD PWD
+ CDUP STOU SMNT SYST SIZE MDTM
+ EPRT EPSV
+
+ UMASK IDLE CHMOD
+
+ AUTH ADAT PROT PBSZ CCC MIC
+ CONF ENC
+
+ KAUTH KLIST KDESTROY KRBTKFILE AFSLOG
+ LOCATE URL
+
+ FEAT OPTS
+
+ LEXERR
+
+%token <s> STRING
+%token <i> NUMBER
+
+%type <i> check_login check_login_no_guest check_secure octal_number byte_size
+%type <i> struct_code mode_code type_code form_code
+%type <s> pathstring pathname password username
+
+%start cmd_list
+
+%%
+
+cmd_list
+ : /* empty */
+ | cmd_list cmd
+ {
+ fromname = (char *) 0;
+ restart_point = (off_t) 0;
+ }
+ | cmd_list rcmd
+ ;
+
+cmd
+ : USER SP username CRLF
+ {
+ user($3);
+ free($3);
+ }
+ | PASS SP password CRLF
+ {
+ pass($3);
+ memset ($3, 0, strlen($3));
+ free($3);
+ }
+ | PORT SP host_port CRLF
+ {
+ usedefault = 0;
+ if (pdata >= 0) {
+ close(pdata);
+ pdata = -1;
+ }
+ reply(200, "PORT command successful.");
+ }
+ | EPRT SP STRING CRLF
+ {
+ eprt ($3);
+ free ($3);
+ }
+ | PASV CRLF
+ {
+ pasv ();
+ }
+ | EPSV CRLF
+ {
+ epsv (NULL);
+ }
+ | EPSV SP STRING CRLF
+ {
+ epsv ($3);
+ free ($3);
+ }
+ | TYPE SP type_code CRLF
+ {
+ switch (cmd_type) {
+
+ case TYPE_A:
+ if (cmd_form == FORM_N) {
+ reply(200, "Type set to A.");
+ type = cmd_type;
+ form = cmd_form;
+ } else
+ reply(504, "Form must be N.");
+ break;
+
+ case TYPE_E:
+ reply(504, "Type E not implemented.");
+ break;
+
+ case TYPE_I:
+ reply(200, "Type set to I.");
+ type = cmd_type;
+ break;
+
+ case TYPE_L:
+#if NBBY == 8
+ if (cmd_bytesz == 8) {
+ reply(200,
+ "Type set to L (byte size 8).");
+ type = cmd_type;
+ } else
+ reply(504, "Byte size must be 8.");
+#else /* NBBY == 8 */
+ UNIMPLEMENTED for NBBY != 8
+#endif /* NBBY == 8 */
+ }
+ }
+ | STRU SP struct_code CRLF
+ {
+ switch ($3) {
+
+ case STRU_F:
+ reply(200, "STRU F ok.");
+ break;
+
+ default:
+ reply(504, "Unimplemented STRU type.");
+ }
+ }
+ | MODE SP mode_code CRLF
+ {
+ switch ($3) {
+
+ case MODE_S:
+ reply(200, "MODE S ok.");
+ break;
+
+ default:
+ reply(502, "Unimplemented MODE type.");
+ }
+ }
+ | ALLO SP NUMBER CRLF
+ {
+ reply(202, "ALLO command ignored.");
+ }
+ | ALLO SP NUMBER SP R SP NUMBER CRLF
+ {
+ reply(202, "ALLO command ignored.");
+ }
+ | RETR SP pathname CRLF check_login
+ {
+ char *name = $3;
+
+ if ($5 && name != NULL)
+ retrieve(0, name);
+ if (name != NULL)
+ free(name);
+ }
+ | STOR SP pathname CRLF check_login
+ {
+ char *name = $3;
+
+ if ($5 && name != NULL)
+ do_store(name, "w", 0);
+ if (name != NULL)
+ free(name);
+ }
+ | APPE SP pathname CRLF check_login
+ {
+ char *name = $3;
+
+ if ($5 && name != NULL)
+ do_store(name, "a", 0);
+ if (name != NULL)
+ free(name);
+ }
+ | NLST CRLF check_login
+ {
+ if ($3)
+ send_file_list(".");
+ }
+ | NLST SP STRING CRLF check_login
+ {
+ char *name = $3;
+
+ if ($5 && name != NULL)
+ send_file_list(name);
+ if (name != NULL)
+ free(name);
+ }
+ | LIST CRLF check_login
+ {
+ if($3)
+ list_file(".");
+ }
+ | LIST SP pathname CRLF check_login
+ {
+ if($5)
+ list_file($3);
+ free($3);
+ }
+ | sTAT SP pathname CRLF check_login
+ {
+ if ($5 && $3 != NULL)
+ statfilecmd($3);
+ if ($3 != NULL)
+ free($3);
+ }
+ | sTAT CRLF
+ {
+ if(oobflag){
+ if (file_size != (off_t) -1)
+ reply(213, "Status: %lu of %lu bytes transferred",
+ (unsigned long)byte_count,
+ (unsigned long)file_size);
+ else
+ reply(213, "Status: %lu bytes transferred",
+ (unsigned long)byte_count);
+ }else
+ statcmd();
+ }
+ | DELE SP pathname CRLF check_login_no_guest
+ {
+ if ($5 && $3 != NULL)
+ do_delete($3);
+ if ($3 != NULL)
+ free($3);
+ }
+ | RNTO SP pathname CRLF check_login_no_guest
+ {
+ if($5){
+ if (fromname) {
+ renamecmd(fromname, $3);
+ free(fromname);
+ fromname = (char *) 0;
+ } else {
+ reply(503, "Bad sequence of commands.");
+ }
+ }
+ if ($3 != NULL)
+ free($3);
+ }
+ | ABOR CRLF
+ {
+ if(oobflag){
+ reply(426, "Transfer aborted. Data connection closed.");
+ reply(226, "Abort successful");
+ oobflag = 0;
+ longjmp(urgcatch, 1);
+ }else
+ reply(225, "ABOR command successful.");
+ }
+ | CWD CRLF check_login
+ {
+ if ($3)
+ cwd(pw->pw_dir);
+ }
+ | CWD SP pathname CRLF check_login
+ {
+ if ($5 && $3 != NULL)
+ cwd($3);
+ if ($3 != NULL)
+ free($3);
+ }
+ | HELP CRLF
+ {
+ help(cmdtab, (char *) 0);
+ }
+ | HELP SP STRING CRLF
+ {
+ char *cp = $3;
+
+ if (strncasecmp(cp, "SITE", 4) == 0) {
+ cp = $3 + 4;
+ if (*cp == ' ')
+ cp++;
+ if (*cp)
+ help(sitetab, cp);
+ else
+ help(sitetab, (char *) 0);
+ } else
+ help(cmdtab, $3);
+ }
+ | NOOP CRLF
+ {
+ reply(200, "NOOP command successful.");
+ }
+ | MKD SP pathname CRLF check_login
+ {
+ if ($5 && $3 != NULL)
+ makedir($3);
+ if ($3 != NULL)
+ free($3);
+ }
+ | RMD SP pathname CRLF check_login_no_guest
+ {
+ if ($5 && $3 != NULL)
+ removedir($3);
+ if ($3 != NULL)
+ free($3);
+ }
+ | PWD CRLF check_login
+ {
+ if ($3)
+ pwd();
+ }
+ | CDUP CRLF check_login
+ {
+ if ($3)
+ cwd("..");
+ }
+ | FEAT CRLF
+ {
+ lreply(211, "Supported features:");
+ lreply(0, " MDTM");
+ lreply(0, " REST STREAM");
+ lreply(0, " SIZE");
+ reply(211, "End");
+ }
+ | OPTS SP STRING CRLF
+ {
+ free ($3);
+ reply(501, "Bad options");
+ }
+
+ | SITE SP HELP CRLF
+ {
+ help(sitetab, (char *) 0);
+ }
+ | SITE SP HELP SP STRING CRLF
+ {
+ help(sitetab, $5);
+ }
+ | SITE SP UMASK CRLF check_login
+ {
+ if ($5) {
+ int oldmask = umask(0);
+ umask(oldmask);
+ reply(200, "Current UMASK is %03o", oldmask);
+ }
+ }
+ | SITE SP UMASK SP octal_number CRLF check_login_no_guest
+ {
+ if ($7) {
+ if (($5 == -1) || ($5 > 0777)) {
+ reply(501, "Bad UMASK value");
+ } else {
+ int oldmask = umask($5);
+ reply(200,
+ "UMASK set to %03o (was %03o)",
+ $5, oldmask);
+ }
+ }
+ }
+ | SITE SP CHMOD SP octal_number SP pathname CRLF check_login_no_guest
+ {
+ if ($9 && $7 != NULL) {
+ if ($5 > 0777)
+ reply(501,
+ "CHMOD: Mode value must be between 0 and 0777");
+ else if (chmod($7, $5) < 0)
+ perror_reply(550, $7);
+ else
+ reply(200, "CHMOD command successful.");
+ }
+ if ($7 != NULL)
+ free($7);
+ }
+ | SITE SP IDLE CRLF
+ {
+ reply(200,
+ "Current IDLE time limit is %d seconds; max %d",
+ ftpd_timeout, maxtimeout);
+ }
+ | SITE SP IDLE SP NUMBER CRLF
+ {
+ if ($5 < 30 || $5 > maxtimeout) {
+ reply(501,
+ "Maximum IDLE time must be between 30 and %d seconds",
+ maxtimeout);
+ } else {
+ ftpd_timeout = $5;
+ alarm((unsigned) ftpd_timeout);
+ reply(200,
+ "Maximum IDLE time set to %d seconds",
+ ftpd_timeout);
+ }
+ }
+
+ | SITE SP KAUTH SP STRING CRLF check_login
+ {
+#ifdef KRB4
+ char *p;
+
+ if(guest)
+ reply(500, "Can't be done as guest.");
+ else{
+ if($7 && $5 != NULL){
+ p = strpbrk($5, " \t");
+ if(p){
+ *p++ = 0;
+ kauth($5, p + strspn(p, " \t"));
+ }else
+ kauth($5, NULL);
+ }
+ }
+ if($5 != NULL)
+ free($5);
+#else
+ reply(500, "Command not implemented.");
+#endif
+ }
+ | SITE SP KLIST CRLF check_login
+ {
+#ifdef KRB4
+ if($5)
+ klist();
+#else
+ reply(500, "Command not implemented.");
+#endif
+ }
+ | SITE SP KDESTROY CRLF check_login
+ {
+#ifdef KRB4
+ if($5)
+ kdestroy();
+#else
+ reply(500, "Command not implemented.");
+#endif
+ }
+ | SITE SP KRBTKFILE SP STRING CRLF check_login
+ {
+#ifdef KRB4
+ if(guest)
+ reply(500, "Can't be done as guest.");
+ else if($7 && $5)
+ krbtkfile($5);
+ if($5)
+ free($5);
+#else
+ reply(500, "Command not implemented.");
+#endif
+ }
+ | SITE SP AFSLOG CRLF check_login
+ {
+#ifdef KRB4
+ if(guest)
+ reply(500, "Can't be done as guest.");
+ else if($5)
+ afslog(NULL);
+#else
+ reply(500, "Command not implemented.");
+#endif
+ }
+ | SITE SP AFSLOG SP STRING CRLF check_login
+ {
+#ifdef KRB4
+ if(guest)
+ reply(500, "Can't be done as guest.");
+ else if($7)
+ afslog($5);
+ if($5)
+ free($5);
+#else
+ reply(500, "Command not implemented.");
+#endif
+ }
+ | SITE SP LOCATE SP STRING CRLF check_login
+ {
+ if($7 && $5 != NULL)
+ find($5);
+ if($5 != NULL)
+ free($5);
+ }
+ | SITE SP URL CRLF
+ {
+ reply(200, "http://www.pdc.kth.se/kth-krb/");
+ }
+ | STOU SP pathname CRLF check_login
+ {
+ if ($5 && $3 != NULL)
+ do_store($3, "w", 1);
+ if ($3 != NULL)
+ free($3);
+ }
+ | SYST CRLF
+ {
+#if defined(unix) || defined(__unix__) || defined(__unix) || defined(_AIX) || defined(_CRAY)
+ reply(215, "UNIX Type: L%d", NBBY);
+#else
+ reply(215, "UNKNOWN Type: L%d", NBBY);
+#endif
+ }
+
+ /*
+ * SIZE is not in RFC959, but Postel has blessed it and
+ * it will be in the updated RFC.
+ *
+ * Return size of file in a format suitable for
+ * using with RESTART (we just count bytes).
+ */
+ | SIZE SP pathname CRLF check_login
+ {
+ if ($5 && $3 != NULL)
+ sizecmd($3);
+ if ($3 != NULL)
+ free($3);
+ }
+
+ /*
+ * MDTM is not in RFC959, but Postel has blessed it and
+ * it will be in the updated RFC.
+ *
+ * Return modification time of file as an ISO 3307
+ * style time. E.g. YYYYMMDDHHMMSS or YYYYMMDDHHMMSS.xxx
+ * where xxx is the fractional second (of any precision,
+ * not necessarily 3 digits)
+ */
+ | MDTM SP pathname CRLF check_login
+ {
+ if ($5 && $3 != NULL) {
+ struct stat stbuf;
+ if (stat($3, &stbuf) < 0)
+ reply(550, "%s: %s",
+ $3, strerror(errno));
+ else if (!S_ISREG(stbuf.st_mode)) {
+ reply(550,
+ "%s: not a plain file.", $3);
+ } else {
+ struct tm *t;
+ t = gmtime(&stbuf.st_mtime);
+ reply(213,
+ "%04d%02d%02d%02d%02d%02d",
+ t->tm_year + 1900,
+ t->tm_mon + 1,
+ t->tm_mday,
+ t->tm_hour,
+ t->tm_min,
+ t->tm_sec);
+ }
+ }
+ if ($3 != NULL)
+ free($3);
+ }
+ | QUIT CRLF
+ {
+ reply(221, "Goodbye.");
+ dologout(0);
+ }
+ | error CRLF
+ {
+ yyerrok;
+ }
+ ;
+rcmd
+ : RNFR SP pathname CRLF check_login_no_guest
+ {
+ restart_point = (off_t) 0;
+ if ($5 && $3) {
+ fromname = renamefrom($3);
+ if (fromname == (char *) 0 && $3) {
+ free($3);
+ }
+ }
+ }
+ | REST SP byte_size CRLF
+ {
+ fromname = (char *) 0;
+ restart_point = $3; /* XXX $3 is only "int" */
+ reply(350, "Restarting at %ld. %s",
+ (long)restart_point,
+ "Send STORE or RETRIEVE to initiate transfer.");
+ }
+ | AUTH SP STRING CRLF
+ {
+ auth($3);
+ free($3);
+ }
+ | ADAT SP STRING CRLF
+ {
+ adat($3);
+ free($3);
+ }
+ | PBSZ SP NUMBER CRLF
+ {
+ pbsz($3);
+ }
+ | PROT SP STRING CRLF
+ {
+ prot($3);
+ }
+ | CCC CRLF
+ {
+ ccc();
+ }
+ | MIC SP STRING CRLF
+ {
+ mec($3, prot_safe);
+ free($3);
+ }
+ | CONF SP STRING CRLF
+ {
+ mec($3, prot_confidential);
+ free($3);
+ }
+ | ENC SP STRING CRLF
+ {
+ mec($3, prot_private);
+ free($3);
+ }
+ ;
+
+username
+ : STRING
+ ;
+
+password
+ : /* empty */
+ {
+ $$ = (char *)calloc(1, sizeof(char));
+ }
+ | STRING
+ ;
+
+byte_size
+ : NUMBER
+ ;
+
+host_port
+ : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA
+ NUMBER COMMA NUMBER
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in *)data_dest;
+
+ sin->sin_family = AF_INET;
+ sin->sin_port = htons($9 * 256 + $11);
+ sin->sin_addr.s_addr =
+ htonl(($1 << 24) | ($3 << 16) | ($5 << 8) | $7);
+ }
+ ;
+
+form_code
+ : N
+ {
+ $$ = FORM_N;
+ }
+ | T
+ {
+ $$ = FORM_T;
+ }
+ | C
+ {
+ $$ = FORM_C;
+ }
+ ;
+
+type_code
+ : A
+ {
+ cmd_type = TYPE_A;
+ cmd_form = FORM_N;
+ }
+ | A SP form_code
+ {
+ cmd_type = TYPE_A;
+ cmd_form = $3;
+ }
+ | E
+ {
+ cmd_type = TYPE_E;
+ cmd_form = FORM_N;
+ }
+ | E SP form_code
+ {
+ cmd_type = TYPE_E;
+ cmd_form = $3;
+ }
+ | I
+ {
+ cmd_type = TYPE_I;
+ }
+ | L
+ {
+ cmd_type = TYPE_L;
+ cmd_bytesz = NBBY;
+ }
+ | L SP byte_size
+ {
+ cmd_type = TYPE_L;
+ cmd_bytesz = $3;
+ }
+ /* this is for a bug in the BBN ftp */
+ | L byte_size
+ {
+ cmd_type = TYPE_L;
+ cmd_bytesz = $2;
+ }
+ ;
+
+struct_code
+ : F
+ {
+ $$ = STRU_F;
+ }
+ | R
+ {
+ $$ = STRU_R;
+ }
+ | P
+ {
+ $$ = STRU_P;
+ }
+ ;
+
+mode_code
+ : S
+ {
+ $$ = MODE_S;
+ }
+ | B
+ {
+ $$ = MODE_B;
+ }
+ | C
+ {
+ $$ = MODE_C;
+ }
+ ;
+
+pathname
+ : pathstring
+ {
+ /*
+ * Problem: this production is used for all pathname
+ * processing, but only gives a 550 error reply.
+ * This is a valid reply in some cases but not in others.
+ */
+ if (logged_in && $1 && *$1 == '~') {
+ glob_t gl;
+ int flags =
+ GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+
+ memset(&gl, 0, sizeof(gl));
+ if (glob($1, flags, NULL, &gl) ||
+ gl.gl_pathc == 0) {
+ reply(550, "not found");
+ $$ = NULL;
+ } else {
+ $$ = strdup(gl.gl_pathv[0]);
+ }
+ globfree(&gl);
+ free($1);
+ } else
+ $$ = $1;
+ }
+ ;
+
+pathstring
+ : STRING
+ ;
+
+octal_number
+ : NUMBER
+ {
+ int ret, dec, multby, digit;
+
+ /*
+ * Convert a number that was read as decimal number
+ * to what it would be if it had been read as octal.
+ */
+ dec = $1;
+ multby = 1;
+ ret = 0;
+ while (dec) {
+ digit = dec%10;
+ if (digit > 7) {
+ ret = -1;
+ break;
+ }
+ ret += digit * multby;
+ multby *= 8;
+ dec /= 10;
+ }
+ $$ = ret;
+ }
+ ;
+
+
+check_login_no_guest : check_login
+ {
+ $$ = $1 && !guest;
+ if($1 && !$$)
+ reply(550, "Permission denied");
+ }
+ ;
+
+check_login : check_secure
+ {
+ if($1) {
+ if(($$ = logged_in) == 0)
+ reply(530, "Please login with USER and PASS.");
+ } else
+ $$ = 0;
+ }
+ ;
+
+check_secure : /* empty */
+ {
+ $$ = 1;
+ if(sec_complete && !secure_command()) {
+ $$ = 0;
+ reply(533, "Command protection level denied "
+ "for paranoid reasons.");
+ }
+ }
+ ;
+
+%%
+
+extern jmp_buf errcatch;
+
+#define CMD 0 /* beginning of command */
+#define ARGS 1 /* expect miscellaneous arguments */
+#define STR1 2 /* expect SP followed by STRING */
+#define STR2 3 /* expect STRING */
+#define OSTR 4 /* optional SP then STRING */
+#define ZSTR1 5 /* SP then optional STRING */
+#define ZSTR2 6 /* optional STRING after SP */
+#define SITECMD 7 /* SITE command */
+#define NSTR 8 /* Number followed by a string */
+
+struct tab cmdtab[] = { /* In order defined in RFC 765 */
+ { "USER", USER, STR1, 1, "<sp> username" },
+ { "PASS", PASS, ZSTR1, 1, "<sp> password" },
+ { "ACCT", ACCT, STR1, 0, "(specify account)" },
+ { "SMNT", SMNT, ARGS, 0, "(structure mount)" },
+ { "REIN", REIN, ARGS, 0, "(reinitialize server state)" },
+ { "QUIT", QUIT, ARGS, 1, "(terminate service)", },
+ { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" },
+ { "EPRT", EPRT, STR1, 1, "<sp> string" },
+ { "PASV", PASV, ARGS, 1, "(set server in passive mode)" },
+ { "EPSV", EPSV, OSTR, 1, "[<sp> foo]" },
+ { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" },
+ { "STRU", STRU, ARGS, 1, "(specify file structure)" },
+ { "MODE", MODE, ARGS, 1, "(specify transfer mode)" },
+ { "RETR", RETR, STR1, 1, "<sp> file-name" },
+ { "STOR", STOR, STR1, 1, "<sp> file-name" },
+ { "APPE", APPE, STR1, 1, "<sp> file-name" },
+ { "MLFL", MLFL, OSTR, 0, "(mail file)" },
+ { "MAIL", MAIL, OSTR, 0, "(mail to user)" },
+ { "MSND", MSND, OSTR, 0, "(mail send to terminal)" },
+ { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" },
+ { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" },
+ { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" },
+ { "MRCP", MRCP, STR1, 0, "(mail recipient)" },
+ { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" },
+ { "REST", REST, ARGS, 1, "<sp> offset (restart command)" },
+ { "RNFR", RNFR, STR1, 1, "<sp> file-name" },
+ { "RNTO", RNTO, STR1, 1, "<sp> file-name" },
+ { "ABOR", ABOR, ARGS, 1, "(abort operation)" },
+ { "DELE", DELE, STR1, 1, "<sp> file-name" },
+ { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
+ { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
+ { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]" },
+ { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]" },
+ { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]" },
+ { "SYST", SYST, ARGS, 1, "(get type of operating system)" },
+ { "STAT", sTAT, OSTR, 1, "[ <sp> path-name ]" },
+ { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
+ { "NOOP", NOOP, ARGS, 1, "" },
+ { "MKD", MKD, STR1, 1, "<sp> path-name" },
+ { "XMKD", MKD, STR1, 1, "<sp> path-name" },
+ { "RMD", RMD, STR1, 1, "<sp> path-name" },
+ { "XRMD", RMD, STR1, 1, "<sp> path-name" },
+ { "PWD", PWD, ARGS, 1, "(return current directory)" },
+ { "XPWD", PWD, ARGS, 1, "(return current directory)" },
+ { "CDUP", CDUP, ARGS, 1, "(change to parent directory)" },
+ { "XCUP", CDUP, ARGS, 1, "(change to parent directory)" },
+ { "STOU", STOU, STR1, 1, "<sp> file-name" },
+ { "SIZE", SIZE, OSTR, 1, "<sp> path-name" },
+ { "MDTM", MDTM, OSTR, 1, "<sp> path-name" },
+
+ /* extensions from RFC2228 */
+ { "AUTH", AUTH, STR1, 1, "<sp> auth-type" },
+ { "ADAT", ADAT, STR1, 1, "<sp> auth-data" },
+ { "PBSZ", PBSZ, ARGS, 1, "<sp> buffer-size" },
+ { "PROT", PROT, STR1, 1, "<sp> prot-level" },
+ { "CCC", CCC, ARGS, 1, "" },
+ { "MIC", MIC, STR1, 1, "<sp> integrity command" },
+ { "CONF", CONF, STR1, 1, "<sp> confidentiality command" },
+ { "ENC", ENC, STR1, 1, "<sp> privacy command" },
+
+ /* RFC2389 */
+ { "FEAT", FEAT, ARGS, 1, "" },
+ { "OPTS", OPTS, ARGS, 1, "<sp> command [<sp> options]" },
+
+ { NULL, 0, 0, 0, 0 }
+};
+
+struct tab sitetab[] = {
+ { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" },
+ { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" },
+ { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" },
+ { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
+
+ { "KAUTH", KAUTH, STR1, 1, "<sp> principal [ <sp> ticket ]" },
+ { "KLIST", KLIST, ARGS, 1, "(show ticket file)" },
+ { "KDESTROY", KDESTROY, ARGS, 1, "(destroy tickets)" },
+ { "KRBTKFILE", KRBTKFILE, STR1, 1, "<sp> ticket-file" },
+ { "AFSLOG", AFSLOG, OSTR, 1, "[<sp> cell]" },
+
+ { "LOCATE", LOCATE, STR1, 1, "<sp> globexpr" },
+ { "FIND", LOCATE, STR1, 1, "<sp> globexpr" },
+
+ { "URL", URL, ARGS, 1, "?" },
+
+ { NULL, 0, 0, 0, 0 }
+};
+
+static struct tab *
+lookup(struct tab *p, char *cmd)
+{
+
+ for (; p->name != NULL; p++)
+ if (strcmp(cmd, p->name) == 0)
+ return (p);
+ return (0);
+}
+
+/*
+ * ftpd_getline - a hacked up version of fgets to ignore TELNET escape codes.
+ */
+char *
+ftpd_getline(char *s, int n)
+{
+ int c;
+ char *cs;
+
+ cs = s;
+/* tmpline may contain saved command from urgent mode interruption */
+ if(ftp_command){
+ strlcpy(s, ftp_command, n);
+ if (debug)
+ syslog(LOG_DEBUG, "command: %s", s);
+#ifdef XXX
+ fprintf(stderr, "%s\n", s);
+#endif
+ return s;
+ }
+ while ((c = getc(stdin)) != EOF) {
+ c &= 0377;
+ if (c == IAC) {
+ if ((c = getc(stdin)) != EOF) {
+ c &= 0377;
+ switch (c) {
+ case WILL:
+ case WONT:
+ c = getc(stdin);
+ printf("%c%c%c", IAC, DONT, 0377&c);
+ fflush(stdout);
+ continue;
+ case DO:
+ case DONT:
+ c = getc(stdin);
+ printf("%c%c%c", IAC, WONT, 0377&c);
+ fflush(stdout);
+ continue;
+ case IAC:
+ break;
+ default:
+ continue; /* ignore command */
+ }
+ }
+ }
+ *cs++ = c;
+ if (--n <= 0 || c == '\n')
+ break;
+ }
+ if (c == EOF && cs == s)
+ return (NULL);
+ *cs++ = '\0';
+ if (debug) {
+ if (!guest && strncasecmp("pass ", s, 5) == 0) {
+ /* Don't syslog passwords */
+ syslog(LOG_DEBUG, "command: %.5s ???", s);
+ } else {
+ char *cp;
+ int len;
+
+ /* Don't syslog trailing CR-LF */
+ len = strlen(s);
+ cp = s + len - 1;
+ while (cp >= s && (*cp == '\n' || *cp == '\r')) {
+ --cp;
+ --len;
+ }
+ syslog(LOG_DEBUG, "command: %.*s", len, s);
+ }
+ }
+#ifdef XXX
+ fprintf(stderr, "%s\n", s);
+#endif
+ return (s);
+}
+
+static RETSIGTYPE
+toolong(int signo)
+{
+
+ reply(421,
+ "Timeout (%d seconds): closing control connection.",
+ ftpd_timeout);
+ if (logging)
+ syslog(LOG_INFO, "User %s timed out after %d seconds",
+ (pw ? pw -> pw_name : "unknown"), ftpd_timeout);
+ dologout(1);
+ SIGRETURN(0);
+}
+
+static int
+yylex(void)
+{
+ static int cpos, state;
+ char *cp, *cp2;
+ struct tab *p;
+ int n;
+ char c;
+
+ for (;;) {
+ switch (state) {
+
+ case CMD:
+ signal(SIGALRM, toolong);
+ alarm((unsigned) ftpd_timeout);
+ if (ftpd_getline(cbuf, sizeof(cbuf)-1) == NULL) {
+ reply(221, "You could at least say goodbye.");
+ dologout(0);
+ }
+ alarm(0);
+#ifdef HAVE_SETPROCTITLE
+ if (strncasecmp(cbuf, "PASS", 4) != NULL)
+ setproctitle("%s: %s", proctitle, cbuf);
+#endif /* HAVE_SETPROCTITLE */
+ if ((cp = strchr(cbuf, '\r'))) {
+ *cp++ = '\n';
+ *cp = '\0';
+ }
+ if ((cp = strpbrk(cbuf, " \n")))
+ cpos = cp - cbuf;
+ if (cpos == 0)
+ cpos = 4;
+ c = cbuf[cpos];
+ cbuf[cpos] = '\0';
+ strupr(cbuf);
+ p = lookup(cmdtab, cbuf);
+ cbuf[cpos] = c;
+ if (p != 0) {
+ if (p->implemented == 0) {
+ nack(p->name);
+ longjmp(errcatch,0);
+ /* NOTREACHED */
+ }
+ state = p->state;
+ yylval.s = p->name;
+ return (p->token);
+ }
+ break;
+
+ case SITECMD:
+ if (cbuf[cpos] == ' ') {
+ cpos++;
+ return (SP);
+ }
+ cp = &cbuf[cpos];
+ if ((cp2 = strpbrk(cp, " \n")))
+ cpos = cp2 - cbuf;
+ c = cbuf[cpos];
+ cbuf[cpos] = '\0';
+ strupr(cp);
+ p = lookup(sitetab, cp);
+ cbuf[cpos] = c;
+ if (p != 0) {
+ if (p->implemented == 0) {
+ state = CMD;
+ nack(p->name);
+ longjmp(errcatch,0);
+ /* NOTREACHED */
+ }
+ state = p->state;
+ yylval.s = p->name;
+ return (p->token);
+ }
+ state = CMD;
+ break;
+
+ case OSTR:
+ if (cbuf[cpos] == '\n') {
+ state = CMD;
+ return (CRLF);
+ }
+ /* FALLTHROUGH */
+
+ case STR1:
+ case ZSTR1:
+ dostr1:
+ if (cbuf[cpos] == ' ') {
+ cpos++;
+ if(state == OSTR)
+ state = STR2;
+ else
+ state++;
+ return (SP);
+ }
+ break;
+
+ case ZSTR2:
+ if (cbuf[cpos] == '\n') {
+ state = CMD;
+ return (CRLF);
+ }
+ /* FALLTHROUGH */
+
+ case STR2:
+ cp = &cbuf[cpos];
+ n = strlen(cp);
+ cpos += n - 1;
+ /*
+ * Make sure the string is nonempty and \n terminated.
+ */
+ if (n > 1 && cbuf[cpos] == '\n') {
+ cbuf[cpos] = '\0';
+ yylval.s = copy(cp);
+ cbuf[cpos] = '\n';
+ state = ARGS;
+ return (STRING);
+ }
+ break;
+
+ case NSTR:
+ if (cbuf[cpos] == ' ') {
+ cpos++;
+ return (SP);
+ }
+ if (isdigit(cbuf[cpos])) {
+ cp = &cbuf[cpos];
+ while (isdigit(cbuf[++cpos]))
+ ;
+ c = cbuf[cpos];
+ cbuf[cpos] = '\0';
+ yylval.i = atoi(cp);
+ cbuf[cpos] = c;
+ state = STR1;
+ return (NUMBER);
+ }
+ state = STR1;
+ goto dostr1;
+
+ case ARGS:
+ if (isdigit(cbuf[cpos])) {
+ cp = &cbuf[cpos];
+ while (isdigit(cbuf[++cpos]))
+ ;
+ c = cbuf[cpos];
+ cbuf[cpos] = '\0';
+ yylval.i = atoi(cp);
+ cbuf[cpos] = c;
+ return (NUMBER);
+ }
+ switch (cbuf[cpos++]) {
+
+ case '\n':
+ state = CMD;
+ return (CRLF);
+
+ case ' ':
+ return (SP);
+
+ case ',':
+ return (COMMA);
+
+ case 'A':
+ case 'a':
+ return (A);
+
+ case 'B':
+ case 'b':
+ return (B);
+
+ case 'C':
+ case 'c':
+ return (C);
+
+ case 'E':
+ case 'e':
+ return (E);
+
+ case 'F':
+ case 'f':
+ return (F);
+
+ case 'I':
+ case 'i':
+ return (I);
+
+ case 'L':
+ case 'l':
+ return (L);
+
+ case 'N':
+ case 'n':
+ return (N);
+
+ case 'P':
+ case 'p':
+ return (P);
+
+ case 'R':
+ case 'r':
+ return (R);
+
+ case 'S':
+ case 's':
+ return (S);
+
+ case 'T':
+ case 't':
+ return (T);
+
+ }
+ break;
+
+ default:
+ fatal("Unknown state in scanner.");
+ }
+ yyerror((char *) 0);
+ state = CMD;
+ longjmp(errcatch,0);
+ }
+}
+
+static char *
+copy(char *s)
+{
+ char *p;
+
+ p = strdup(s);
+ if (p == NULL)
+ fatal("Ran out of memory.");
+ return p;
+}
+
+static void
+help(struct tab *ctab, char *s)
+{
+ struct tab *c;
+ int width, NCMDS;
+ char *type;
+ char buf[1024];
+
+ if (ctab == sitetab)
+ type = "SITE ";
+ else
+ type = "";
+ width = 0, NCMDS = 0;
+ for (c = ctab; c->name != NULL; c++) {
+ int len = strlen(c->name);
+
+ if (len > width)
+ width = len;
+ NCMDS++;
+ }
+ width = (width + 8) &~ 7;
+ if (s == 0) {
+ int i, j, w;
+ int columns, lines;
+
+ lreply(214, "The following %scommands are recognized %s.",
+ type, "(* =>'s unimplemented)");
+ columns = 76 / width;
+ if (columns == 0)
+ columns = 1;
+ lines = (NCMDS + columns - 1) / columns;
+ for (i = 0; i < lines; i++) {
+ strlcpy (buf, " ", sizeof(buf));
+ for (j = 0; j < columns; j++) {
+ c = ctab + j * lines + i;
+ snprintf (buf + strlen(buf),
+ sizeof(buf) - strlen(buf),
+ "%s%c",
+ c->name,
+ c->implemented ? ' ' : '*');
+ if (c + lines >= &ctab[NCMDS])
+ break;
+ w = strlen(c->name) + 1;
+ while (w < width) {
+ strlcat (buf,
+ " ",
+ sizeof(buf));
+ w++;
+ }
+ }
+ lreply(214, "%s", buf);
+ }
+ reply(214, "Direct comments to kth-krb-bugs@pdc.kth.se");
+ return;
+ }
+ strupr(s);
+ c = lookup(ctab, s);
+ if (c == (struct tab *)0) {
+ reply(502, "Unknown command %s.", s);
+ return;
+ }
+ if (c->implemented)
+ reply(214, "Syntax: %s%s %s", type, c->name, c->help);
+ else
+ reply(214, "%s%-*s\t%s; unimplemented.", type, width,
+ c->name, c->help);
+}
+
+static void
+sizecmd(char *filename)
+{
+ switch (type) {
+ case TYPE_L:
+ case TYPE_I: {
+ struct stat stbuf;
+ if (stat(filename, &stbuf) < 0 || !S_ISREG(stbuf.st_mode))
+ reply(550, "%s: not a plain file.", filename);
+ else
+ reply(213, "%lu", (unsigned long)stbuf.st_size);
+ break;
+ }
+ case TYPE_A: {
+ FILE *fin;
+ int c;
+ size_t count;
+ struct stat stbuf;
+ fin = fopen(filename, "r");
+ if (fin == NULL) {
+ perror_reply(550, filename);
+ return;
+ }
+ if (fstat(fileno(fin), &stbuf) < 0 || !S_ISREG(stbuf.st_mode)) {
+ reply(550, "%s: not a plain file.", filename);
+ fclose(fin);
+ return;
+ }
+
+ count = 0;
+ while((c=getc(fin)) != EOF) {
+ if (c == '\n') /* will get expanded to \r\n */
+ count++;
+ count++;
+ }
+ fclose(fin);
+
+ reply(213, "%lu", (unsigned long)count);
+ break;
+ }
+ default:
+ reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
+ }
+}
diff --git a/crypto/heimdal/appl/ftp/ftpd/ftpd.8 b/crypto/heimdal/appl/ftp/ftpd/ftpd.8
new file mode 100644
index 000000000000..c51de1ce06dc
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/ftpd.8
@@ -0,0 +1,473 @@
+.\" $NetBSD: ftpd.8,v 1.7 1995/04/11 02:44:53 cgd Exp $
+.\"
+.\" Copyright (c) 1985, 1988, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. 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.
+.\"
+.\" @(#)ftpd.8 8.2 (Berkeley) 4/19/94
+.\"
+.Dd April 19, 1997
+.Dt FTPD 8
+.Os BSD 4.2
+.Sh NAME
+.Nm ftpd
+.Nd
+Internet File Transfer Protocol server
+.Sh SYNOPSIS
+.Nm ftpd
+.Op Fl a Ar authmode
+.Op Fl dilv
+.Op Fl g Ar umask
+.Op Fl p Ar port
+.Op Fl T Ar maxtimeout
+.Op Fl t Ar timeout
+.Op Fl u Ar default umask
+.Sh DESCRIPTION
+.Nm Ftpd
+is the
+Internet File Transfer Protocol
+server process. The server uses the
+.Tn TCP
+protocol
+and listens at the port specified in the
+.Dq ftp
+service specification; see
+.Xr services 5 .
+.Pp
+Available options:
+.Bl -tag -width Ds
+.It Fl a
+Select the level of authentication required. Kerberised login can not
+be turned off. The default is to only allow kerberised login. Other
+possibilities can be turned on by giving a string of comma separated
+flags as argument to
+.Fl a .
+Recognised flags are:
+.Bl -tag -width plain
+.It Ar plain
+Allow logging in with plaintext password. The password can be a(n) OTP
+or an ordinary password.
+.It Ar otp
+Same as
+.Ar plain ,
+but only OTP is allowed.
+.It Ar ftp
+Allow anonymous login.
+.El
+
+The following combination modes exists for backwards compatibility:
+.Bl -tag -width plain
+.It Ar none
+Same as
+.Ar plain,ftp .
+.It Ar safe
+Same as
+.Ar ftp .
+.It Ar user
+Ignored.
+.El
+.It Fl d
+Debugging information is written to the syslog using LOG_FTP.
+.It Fl g
+Anonymous users will get a umask of
+.Ar umask .
+.It Fl i
+Open a socket and wait for a connection. This is mainly used for
+debugging when ftpd isn't started by inetd.
+.It Fl l
+Each successful and failed
+.Xr ftp 1
+session is logged using syslog with a facility of LOG_FTP.
+If this option is specified twice, the retrieve (get), store (put), append,
+delete, make directory, remove directory and rename operations and
+their filename arguments are also logged.
+.It Fl p
+Use
+.Ar port
+(a service name or number) instead of the default
+.Ar ftp/tcp .
+.It Fl T
+A client may also request a different timeout period;
+the maximum period allowed may be set to
+.Ar timeout
+seconds with the
+.Fl T
+option.
+The default limit is 2 hours.
+.It Fl t
+The inactivity timeout period is set to
+.Ar timeout
+seconds (the default is 15 minutes).
+.It Fl u
+Set the initial umask to something else than the default 027.
+.It Fl v
+Verbose mode.
+.El
+.Pp
+The file
+.Pa /etc/nologin
+can be used to disable ftp access.
+If the file exists,
+.Nm
+displays it and exits.
+If the file
+.Pa /etc/ftpwelcome
+exists,
+.Nm
+prints it before issuing the
+.Dq ready
+message.
+If the file
+.Pa /etc/motd
+exists,
+.Nm
+prints it after a successful login.
+.Pp
+The ftp server currently supports the following ftp requests.
+The case of the requests is ignored.
+.Bl -column "Request" -offset indent
+.It Request Ta "Description"
+.It ABOR Ta "abort previous command"
+.It ACCT Ta "specify account (ignored)"
+.It ALLO Ta "allocate storage (vacuously)"
+.It APPE Ta "append to a file"
+.It CDUP Ta "change to parent of current working directory"
+.It CWD Ta "change working directory"
+.It DELE Ta "delete a file"
+.It HELP Ta "give help information"
+.It LIST Ta "give list files in a directory" Pq Dq Li "ls -lgA"
+.It MKD Ta "make a directory"
+.It MDTM Ta "show last modification time of file"
+.It MODE Ta "specify data transfer" Em mode
+.It NLST Ta "give name list of files in directory"
+.It NOOP Ta "do nothing"
+.It PASS Ta "specify password"
+.It PASV Ta "prepare for server-to-server transfer"
+.It PORT Ta "specify data connection port"
+.It PWD Ta "print the current working directory"
+.It QUIT Ta "terminate session"
+.It REST Ta "restart incomplete transfer"
+.It RETR Ta "retrieve a file"
+.It RMD Ta "remove a directory"
+.It RNFR Ta "specify rename-from file name"
+.It RNTO Ta "specify rename-to file name"
+.It SITE Ta "non-standard commands (see next section)"
+.It SIZE Ta "return size of file"
+.It STAT Ta "return status of server"
+.It STOR Ta "store a file"
+.It STOU Ta "store a file with a unique name"
+.It STRU Ta "specify data transfer" Em structure
+.It SYST Ta "show operating system type of server system"
+.It TYPE Ta "specify data transfer" Em type
+.It USER Ta "specify user name"
+.It XCUP Ta "change to parent of current working directory (deprecated)"
+.It XCWD Ta "change working directory (deprecated)"
+.It XMKD Ta "make a directory (deprecated)"
+.It XPWD Ta "print the current working directory (deprecated)"
+.It XRMD Ta "remove a directory (deprecated)"
+.El
+.Pp
+The following commands are specified by RFC2228.
+.Bl -column Request -offset indent
+.It AUTH Ta "authentication/security mechanism"
+.It ADAT Ta "authentication/security data"
+.It PROT Ta "data channel protection level"
+.It PBSZ Ta "protection buffer size"
+.It MIC Ta "integrity protected command"
+.It CONF Ta "confidentiality protected command"
+.It ENC Ta "privacy protected command"
+.It CCC Ta "clear command channel"
+.El
+.Pp
+The following non-standard or
+.Tn UNIX
+specific commands are supported
+by the
+SITE request.
+.Pp
+.Bl -column Request -offset indent
+.It UMASK Ta change umask, (e.g.
+.Ic "SITE UMASK 002" )
+.It IDLE Ta set idle-timer, (e.g.
+.Ic "SITE IDLE 60" )
+.It CHMOD Ta change mode of a file (e.g.
+.Ic "SITE CHMOD 755 filename" )
+.It FIND Ta quickly find a specific file with GNU
+.Xr locate 1 .
+.It HELP Ta give help information.
+.El
+.Pp
+The following Kerberos related site commands are understood.
+.Bl -column Request -offset indent
+.It KAUTH Ta obtain remote tickets.
+.It KLIST Ta show remote tickets
+.El
+.Pp
+The remaining ftp requests specified in Internet RFC 959
+are
+recognized, but not implemented.
+MDTM and SIZE are not specified in RFC 959, but will appear in the
+next updated FTP RFC.
+.Pp
+The ftp server will abort an active file transfer only when the
+ABOR
+command is preceded by a Telnet "Interrupt Process" (IP)
+signal and a Telnet "Synch" signal in the command Telnet stream,
+as described in Internet RFC 959.
+If a
+STAT
+command is received during a data transfer, preceded by a Telnet IP
+and Synch, transfer status will be returned.
+.Pp
+.Nm Ftpd
+interprets file names according to the
+.Dq globbing
+conventions used by
+.Xr csh 1 .
+This allows users to utilize the metacharacters
+.Dq Li \&*?[]{}~ .
+.Pp
+.Nm Ftpd
+authenticates users according to these rules.
+.Pp
+.Bl -enum -offset indent
+.It
+If Kerberos authentication is used, the user must pass valid tickets
+and the principal must be allowed to login as the remote user.
+.It
+The login name must be in the password data base, and not have a null
+password (if kerberos is used the password field is not checked). In
+this case a password must be provided by the client before any file
+operations may be performed. If the user has an OTP key, the response
+from a successful USER command will include an OTP challenge. The
+client may choose to respond with a PASS command giving either a
+standard password or an OTP one-time password. The server will
+automatically determine which type of password it has been given and
+attempt to authenticate accordingly. See
+.Xr otp 1
+for more information on OTP authentication.
+.It
+The login name must not appear in the file
+.Pa /etc/ftpusers .
+.It
+The user must have a standard shell returned by
+.Xr getusershell 3 .
+.It
+If the user name appears in the file
+.Pa /etc/ftpchroot
+the session's root will be changed to the user's login directory by
+.Xr chroot 2
+as for an
+.Dq anonymous
+or
+.Dq ftp
+account (see next item). However, the user must still supply a password.
+This feature is intended as a compromise between a fully anonymous account
+and a fully privileged account. The account should also be set up as for an
+anonymous account.
+.It
+If the user name is
+.Dq anonymous
+or
+.Dq ftp ,
+an
+anonymous ftp account must be present in the password
+file (user
+.Dq ftp ) .
+In this case the user is allowed
+to log in by specifying any password (by convention an email address for
+the user should be used as the password).
+.El
+.Pp
+In the last case,
+.Nm ftpd
+takes special measures to restrict the client's access privileges.
+The server performs a
+.Xr chroot 2
+to the home directory of the
+.Dq ftp
+user.
+In order that system security is not breached, it is recommended
+that the
+.Dq ftp
+subtree be constructed with care, consider following these guidelines
+for anonymous ftp.
+
+In general all files should be owned by
+.Dq root ,
+and have non-write permissions (644 or 755 depending on the kind of
+file). No files should be owned or writable by
+.Dq ftp
+(possibly with exception for the
+.Pa ~ftp/incoming ,
+as specified below).
+.Bl -tag -width "~ftp/pub" -offset indent
+.It Pa ~ftp
+The
+.Dq ftp
+homedirectory should be owned by root.
+.It Pa ~ftp/bin
+The directory for external programs (such as
+.Xr ls 1 ) .
+These programs must either be statically linked, or you must setup an
+environment for dynamic linking when running chrooted.
+These programs will be used if present:
+.Bl -tag -width "locate" -offset indent
+.It ls
+Used when listing files.
+.It compress
+When retrieving a filename that ends in
+.Pa .Z ,
+and that file isn't present,
+.Nm
+will try to find the filename without
+.Pa .Z
+and compress it on the fly.
+.It gzip
+Same as compress, just with files ending in
+.Pa .gz .
+.It gtar
+Enables retrieval of whole directories as files ending in
+.Pa .tar .
+Can also be combined with compression. You must use GNU Tar (or some
+other that supports the
+.Fl z
+and
+.Fl Z
+flags).
+.It locate
+Will enable ``fast find'' with the
+.Ic SITE FIND
+command. You must also create a
+.Pa locatedb
+file in
+.Pa ~ftp/etc .
+.El
+.It Pa ~ftp/etc
+If you put copies of the
+.Xr passwd 5
+and
+.Xr group 5
+files here, ls will be able to produce owner names rather than
+numbers. Remember to remove any passwords from these files.
+
+The file
+.Pa motd ,
+if present, will be printed after a successful login.
+.It Pa ~ftp/dev
+Put a copy of
+.Xr /dev/null 7
+here.
+.It Pa ~ftp/pub
+Traditional place to put whatever you want to make public.
+.El
+
+If you want guests to be able to upload files, create a
+.Pa ~ftp/incoming
+directory owned by
+.Dq root ,
+and group
+.Dq ftp
+with mode 730 (make sure
+.Dq ftp
+is member of group
+.Dq ftp ) .
+The following restrictions apply to anonymous users:
+.Bl -bullet
+.It
+Directories created will have mode 700.
+.It
+Uploaded files will be created with an umask of 777, if not changed
+with the
+.Fl g
+option.
+.It
+These command are not accessible:
+.Ic DELE , RMD , RNTO , RNFR ,
+.Ic SITE UMASK ,
+and
+.Ic SITE CHMOD .
+.It
+Filenames must start with an alpha-numeric character, and consist of
+alpha-numeric characters or any of the following:
+.Li \&+
+(plus),
+.Li \&-
+(minus),
+.Li \&=
+(equal),
+.Li \&_
+(underscore),
+.Li \&.
+(period), and
+.Li \&,
+(comma).
+.El
+.Sh FILES
+.Bl -tag -width /etc/ftpwelcome -compact
+.It Pa /etc/ftpusers
+Access list for users.
+.It Pa /etc/ftpchroot
+List of normal users who should be chroot'd.
+.It Pa /etc/ftpwelcome
+Welcome notice.
+.It Pa /etc/motd
+Welcome notice after login.
+.It Pa /etc/nologin
+Displayed and access refused.
+.It Pa ~/.klogin
+Login access for Kerberos.
+.El
+.Sh SEE ALSO
+.Xr ftp 1 ,
+.Xr otp 1 ,
+.Xr getusershell 3 ,
+.Xr ftpusers 5 ,
+.Xr syslogd 8 ,
+.Sh STANDARDS
+.Bl -tag -compact -width "RFC 1938"
+.It Cm RFC 959
+FTP PROTOCOL SPECIFICATION
+.It Cm RFC 1938
+OTP Specification
+.It Cm RFC 2228
+FTP Security Extensions.
+.Sh BUGS
+The server must run as the super-user
+to create sockets with privileged port numbers. It maintains
+an effective user id of the logged in user, reverting to
+the super-user only when binding addresses to sockets. The
+possible security holes have been extensively
+scrutinized, but are possibly incomplete.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/crypto/heimdal/appl/ftp/ftpd/ftpd.c b/crypto/heimdal/appl/ftp/ftpd/ftpd.c
new file mode 100644
index 000000000000..8c5ddf32845d
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/ftpd.c
@@ -0,0 +1,2249 @@
+/*
+ * Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#define FTP_NAMES
+#include "ftpd_locl.h"
+#ifdef KRB5
+#include <krb5.h>
+#endif
+#include "getarg.h"
+
+RCSID("$Id: ftpd.c,v 1.137 2000/01/05 13:46:04 joda Exp $");
+
+static char version[] = "Version 6.00";
+
+extern off_t restart_point;
+extern char cbuf[];
+
+struct sockaddr_storage ctrl_addr_ss;
+struct sockaddr *ctrl_addr = (struct sockaddr *)&ctrl_addr_ss;
+
+struct sockaddr_storage data_source_ss;
+struct sockaddr *data_source = (struct sockaddr *)&data_source_ss;
+
+struct sockaddr_storage data_dest_ss;
+struct sockaddr *data_dest = (struct sockaddr *)&data_dest_ss;
+
+struct sockaddr_storage his_addr_ss;
+struct sockaddr *his_addr = (struct sockaddr *)&his_addr_ss;
+
+struct sockaddr_storage pasv_addr_ss;
+struct sockaddr *pasv_addr = (struct sockaddr *)&pasv_addr_ss;
+
+int data;
+jmp_buf errcatch, urgcatch;
+int oobflag;
+int logged_in;
+struct passwd *pw;
+int debug = 0;
+int ftpd_timeout = 900; /* timeout after 15 minutes of inactivity */
+int maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */
+int logging;
+int guest;
+int dochroot;
+int type;
+int form;
+int stru; /* avoid C keyword */
+int mode;
+int usedefault = 1; /* for data transfers */
+int pdata = -1; /* for passive mode */
+int transflag;
+off_t file_size;
+off_t byte_count;
+#if !defined(CMASK) || CMASK == 0
+#undef CMASK
+#define CMASK 027
+#endif
+int defumask = CMASK; /* default umask value */
+int guest_umask = 0777; /* Paranoia for anonymous users */
+char tmpline[10240];
+char hostname[MaxHostNameLen];
+char remotehost[MaxHostNameLen];
+static char ttyline[20];
+
+#define AUTH_PLAIN (1 << 0) /* allow sending passwords */
+#define AUTH_OTP (1 << 1) /* passwords are one-time */
+#define AUTH_FTP (1 << 2) /* allow anonymous login */
+
+static int auth_level = 0; /* Only allow kerberos login by default */
+
+/*
+ * Timeout intervals for retrying connections
+ * to hosts that don't accept PORT cmds. This
+ * is a kludge, but given the problems with TCP...
+ */
+#define SWAITMAX 90 /* wait at most 90 seconds */
+#define SWAITINT 5 /* interval between retries */
+
+int swaitmax = SWAITMAX;
+int swaitint = SWAITINT;
+
+#ifdef HAVE_SETPROCTITLE
+char proctitle[BUFSIZ]; /* initial part of title */
+#endif /* HAVE_SETPROCTITLE */
+
+#define LOGCMD(cmd, file) \
+ if (logging > 1) \
+ syslog(LOG_INFO,"%s %s%s", cmd, \
+ *(file) == '/' ? "" : curdir(), file);
+#define LOGCMD2(cmd, file1, file2) \
+ if (logging > 1) \
+ syslog(LOG_INFO,"%s %s%s %s%s", cmd, \
+ *(file1) == '/' ? "" : curdir(), file1, \
+ *(file2) == '/' ? "" : curdir(), file2);
+#define LOGBYTES(cmd, file, cnt) \
+ if (logging > 1) { \
+ if (cnt == (off_t)-1) \
+ syslog(LOG_INFO,"%s %s%s", cmd, \
+ *(file) == '/' ? "" : curdir(), file); \
+ else \
+ syslog(LOG_INFO, "%s %s%s = %ld bytes", \
+ cmd, (*(file) == '/') ? "" : curdir(), file, (long)cnt); \
+ }
+
+static void ack (char *);
+static void myoob (int);
+static int checkuser (char *, char *);
+static int checkaccess (char *);
+static FILE *dataconn (const char *, off_t, const char *);
+static void dolog (struct sockaddr *sa, int len);
+static void end_login (void);
+static FILE *getdatasock (const char *);
+static char *gunique (char *);
+static RETSIGTYPE lostconn (int);
+static int receive_data (FILE *, FILE *);
+static void send_data (FILE *, FILE *);
+static struct passwd * sgetpwnam (char *);
+
+static char *
+curdir(void)
+{
+ static char path[MaxPathLen+1]; /* path + '/' + '\0' */
+
+ if (getcwd(path, sizeof(path)-1) == NULL)
+ return ("");
+ if (path[1] != '\0') /* special case for root dir. */
+ strlcat(path, "/", sizeof(path));
+ /* For guest account, skip / since it's chrooted */
+ return (guest ? path+1 : path);
+}
+
+#ifndef LINE_MAX
+#define LINE_MAX 1024
+#endif
+
+static int
+parse_auth_level(char *str)
+{
+ char *p;
+ int ret = 0;
+ char *foo = NULL;
+
+ for(p = strtok_r(str, ",", &foo);
+ p;
+ p = strtok_r(NULL, ",", &foo)) {
+ if(strcmp(p, "user") == 0)
+ ;
+#ifdef OTP
+ else if(strcmp(p, "otp") == 0)
+ ret |= AUTH_PLAIN|AUTH_OTP;
+#endif
+ else if(strcmp(p, "ftp") == 0 ||
+ strcmp(p, "safe") == 0)
+ ret |= AUTH_FTP;
+ else if(strcmp(p, "plain") == 0)
+ ret |= AUTH_PLAIN;
+ else if(strcmp(p, "none") == 0)
+ ret |= AUTH_PLAIN|AUTH_FTP;
+ else
+ warnx("bad value for -a: `%s'", p);
+ }
+ return ret;
+}
+
+/*
+ * Print usage and die.
+ */
+
+static int debug_flag;
+static int interactive_flag;
+static char *guest_umask_string;
+static char *port_string;
+static char *umask_string;
+static char *auth_string;
+
+int use_builtin_ls = -1;
+
+static int help_flag;
+static int version_flag;
+
+struct getargs args[] = {
+ { NULL, 'a', arg_string, &auth_string, "required authentication" },
+ { NULL, 'i', arg_flag, &interactive_flag, "don't assume stdin is a socket" },
+ { NULL, 'p', arg_string, &port_string, "what port to listen to" },
+ { NULL, 'g', arg_string, &guest_umask_string, "umask for guest logins" },
+ { NULL, 'l', arg_counter, &logging, "log more stuff", "" },
+ { NULL, 't', arg_integer, &ftpd_timeout, "initial timeout" },
+ { NULL, 'T', arg_integer, &maxtimeout, "max timeout" },
+ { NULL, 'u', arg_string, &umask_string, "umask for user logins" },
+ { NULL, 'd', arg_flag, &debug_flag, "enable debugging" },
+ { NULL, 'v', arg_flag, &debug_flag, "enable debugging" },
+ { "builtin-ls", 'B', arg_flag, &use_builtin_ls, "use built-in ls to list files" },
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 'h', arg_flag, &help_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage (int code)
+{
+ arg_printusage(args, num_args, NULL, "");
+ exit (code);
+}
+
+/* output contents of a file */
+static int
+show_file(const char *file, int code)
+{
+ FILE *f;
+ char buf[128];
+
+ f = fopen(file, "r");
+ if(f == NULL)
+ return -1;
+ while(fgets(buf, sizeof(buf), f)){
+ buf[strcspn(buf, "\r\n")] = '\0';
+ lreply(code, "%s", buf);
+ }
+ fclose(f);
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int his_addr_len, ctrl_addr_len, on = 1, tos;
+ char *cp, line[LINE_MAX];
+ FILE *fd;
+ int port;
+ struct servent *sp;
+
+ int optind = 0;
+
+ set_progname (argv[0]);
+
+#ifdef KRB4
+ /* detach from any tickets and tokens */
+ {
+ char tkfile[1024];
+ snprintf(tkfile, sizeof(tkfile),
+ "/tmp/ftp_%u", (unsigned)getpid());
+ krb_set_tkt_string(tkfile);
+ if(k_hasafs())
+ k_setpag();
+ }
+#endif
+ if(getarg(args, num_args, argc, argv, &optind))
+ usage(1);
+
+ if(help_flag)
+ usage(0);
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ if(auth_string)
+ auth_level = parse_auth_level(auth_string);
+ {
+ char *p;
+ long val = 0;
+
+ if(guest_umask_string) {
+ val = strtol(guest_umask_string, &p, 8);
+ if (*p != '\0' || val < 0)
+ warnx("bad value for -g");
+ else
+ guest_umask = val;
+ }
+ if(umask_string) {
+ val = strtol(umask_string, &p, 8);
+ if (*p != '\0' || val < 0)
+ warnx("bad value for -u");
+ else
+ defumask = val;
+ }
+ }
+ if(port_string) {
+ sp = getservbyname(port_string, "tcp");
+ if(sp)
+ port = sp->s_port;
+ else
+ if(isdigit(port_string[0]))
+ port = htons(atoi(port_string));
+ else
+ warnx("bad value for -p");
+ } else {
+ sp = getservbyname("ftp", "tcp");
+ if(sp)
+ port = sp->s_port;
+ else
+ port = htons(21);
+ }
+
+ if (maxtimeout < ftpd_timeout)
+ maxtimeout = ftpd_timeout;
+
+#if 0
+ if (ftpd_timeout > maxtimeout)
+ ftpd_timeout = maxtimeout;
+#endif
+
+ if(interactive_flag)
+ mini_inetd (port);
+
+ /*
+ * LOG_NDELAY sets up the logging connection immediately,
+ * necessary for anonymous ftp's that chroot and can't do it later.
+ */
+ openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
+ his_addr_len = sizeof(his_addr_ss);
+ if (getpeername(STDIN_FILENO, his_addr, &his_addr_len) < 0) {
+ syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
+ exit(1);
+ }
+ ctrl_addr_len = sizeof(ctrl_addr_ss);
+ if (getsockname(STDIN_FILENO, ctrl_addr, &ctrl_addr_len) < 0) {
+ syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
+ exit(1);
+ }
+#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
+ tos = IPTOS_LOWDELAY;
+ if (setsockopt(STDIN_FILENO, IPPROTO_IP, IP_TOS,
+ (void *)&tos, sizeof(int)) < 0)
+ syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
+#endif
+ data_source->sa_family = ctrl_addr->sa_family;
+ socket_set_port (data_source,
+ htons(ntohs(socket_get_port(ctrl_addr)) - 1));
+
+ /* set this here so it can be put in wtmp */
+ snprintf(ttyline, sizeof(ttyline), "ftp%u", (unsigned)getpid());
+
+
+ /* freopen(_PATH_DEVNULL, "w", stderr); */
+ signal(SIGPIPE, lostconn);
+ signal(SIGCHLD, SIG_IGN);
+#ifdef SIGURG
+ if (signal(SIGURG, myoob) == SIG_ERR)
+ syslog(LOG_ERR, "signal: %m");
+#endif
+
+ /* Try to handle urgent data inline */
+#if defined(SO_OOBINLINE) && defined(HAVE_SETSOCKOPT)
+ if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (void *)&on,
+ sizeof(on)) < 0)
+ syslog(LOG_ERR, "setsockopt: %m");
+#endif
+
+#ifdef F_SETOWN
+ if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
+ syslog(LOG_ERR, "fcntl F_SETOWN: %m");
+#endif
+ dolog(his_addr, his_addr_len);
+ /*
+ * Set up default state
+ */
+ data = -1;
+ type = TYPE_A;
+ form = FORM_N;
+ stru = STRU_F;
+ mode = MODE_S;
+ tmpline[0] = '\0';
+
+ /* If logins are disabled, print out the message. */
+ if(show_file(_PATH_NOLOGIN, 530) == 0) {
+ reply(530, "System not available.");
+ exit(0);
+ }
+ show_file(_PATH_FTPWELCOME, 220);
+ /* reply(220,) must follow */
+ gethostname(hostname, sizeof(hostname));
+
+ reply(220, "%s FTP server (%s"
+#ifdef KRB5
+ "+%s"
+#endif
+#ifdef KRB4
+ "+%s"
+#endif
+ ") ready.", hostname, version
+#ifdef KRB5
+ ,heimdal_version
+#endif
+#ifdef KRB4
+ ,krb4_version
+#endif
+ );
+
+ setjmp(errcatch);
+ for (;;)
+ yyparse();
+ /* NOTREACHED */
+}
+
+static RETSIGTYPE
+lostconn(int signo)
+{
+
+ if (debug)
+ syslog(LOG_DEBUG, "lost connection");
+ dologout(-1);
+}
+
+/*
+ * Helper function for sgetpwnam().
+ */
+static char *
+sgetsave(char *s)
+{
+ char *new = strdup(s);
+
+ if (new == NULL) {
+ perror_reply(421, "Local resource failure: malloc");
+ dologout(1);
+ /* NOTREACHED */
+ }
+ return new;
+}
+
+/*
+ * Save the result of a getpwnam. Used for USER command, since
+ * the data returned must not be clobbered by any other command
+ * (e.g., globbing).
+ */
+static struct passwd *
+sgetpwnam(char *name)
+{
+ static struct passwd save;
+ struct passwd *p;
+
+ if ((p = k_getpwnam(name)) == NULL)
+ return (p);
+ if (save.pw_name) {
+ free(save.pw_name);
+ free(save.pw_passwd);
+ free(save.pw_gecos);
+ free(save.pw_dir);
+ free(save.pw_shell);
+ }
+ save = *p;
+ save.pw_name = sgetsave(p->pw_name);
+ save.pw_passwd = sgetsave(p->pw_passwd);
+ save.pw_gecos = sgetsave(p->pw_gecos);
+ save.pw_dir = sgetsave(p->pw_dir);
+ save.pw_shell = sgetsave(p->pw_shell);
+ return (&save);
+}
+
+static int login_attempts; /* number of failed login attempts */
+static int askpasswd; /* had user command, ask for passwd */
+static char curname[10]; /* current USER name */
+#ifdef OTP
+OtpContext otp_ctx;
+#endif
+
+/*
+ * USER command.
+ * Sets global passwd pointer pw if named account exists and is acceptable;
+ * sets askpasswd if a PASS command is expected. If logged in previously,
+ * need to reset state. If name is "ftp" or "anonymous", the name is not in
+ * _PATH_FTPUSERS, and ftp account exists, set guest and pw, then just return.
+ * If account doesn't exist, ask for passwd anyway. Otherwise, check user
+ * requesting login privileges. Disallow anyone who does not have a standard
+ * shell as returned by getusershell(). Disallow anyone mentioned in the file
+ * _PATH_FTPUSERS to allow people such as root and uucp to be avoided.
+ */
+void
+user(char *name)
+{
+ char *cp, *shell;
+
+ if(auth_level == 0 && !sec_complete){
+ reply(530, "No login allowed without authorization.");
+ return;
+ }
+
+ if (logged_in) {
+ if (guest) {
+ reply(530, "Can't change user from guest login.");
+ return;
+ } else if (dochroot) {
+ reply(530, "Can't change user from chroot user.");
+ return;
+ }
+ end_login();
+ }
+
+ guest = 0;
+ if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
+ if ((auth_level & AUTH_FTP) == 0 ||
+ checkaccess("ftp") ||
+ checkaccess("anonymous"))
+ reply(530, "User %s access denied.", name);
+ else if ((pw = sgetpwnam("ftp")) != NULL) {
+ guest = 1;
+ defumask = guest_umask; /* paranoia for incoming */
+ askpasswd = 1;
+ reply(331, "Guest login ok, type your name as password.");
+ } else
+ reply(530, "User %s unknown.", name);
+ if (!askpasswd && logging) {
+ char data_addr[256];
+
+ if (inet_ntop (his_addr->sa_family,
+ socket_get_address(his_addr),
+ data_addr, sizeof(data_addr)) == NULL)
+ strlcpy (data_addr, "unknown address",
+ sizeof(data_addr));
+
+ syslog(LOG_NOTICE,
+ "ANONYMOUS FTP LOGIN REFUSED FROM %s(%s)",
+ remotehost, data_addr);
+ }
+ return;
+ }
+ if((auth_level & AUTH_PLAIN) == 0 && !sec_complete){
+ reply(530, "Only authorized and anonymous login allowed.");
+ return;
+ }
+ if ((pw = sgetpwnam(name))) {
+ if ((shell = pw->pw_shell) == NULL || *shell == 0)
+ shell = _PATH_BSHELL;
+ while ((cp = getusershell()) != NULL)
+ if (strcmp(cp, shell) == 0)
+ break;
+ endusershell();
+
+ if (cp == NULL || checkaccess(name)) {
+ reply(530, "User %s access denied.", name);
+ if (logging) {
+ char data_addr[256];
+
+ if (inet_ntop (his_addr->sa_family,
+ socket_get_address(his_addr),
+ data_addr,
+ sizeof(data_addr)) == NULL)
+ strlcpy (data_addr,
+ "unknown address",
+ sizeof(data_addr));
+
+ syslog(LOG_NOTICE,
+ "FTP LOGIN REFUSED FROM %s(%s), %s",
+ remotehost,
+ data_addr,
+ name);
+ }
+ pw = (struct passwd *) NULL;
+ return;
+ }
+ }
+ if (logging)
+ strlcpy(curname, name, sizeof(curname));
+ if(sec_complete) {
+ if(sec_userok(name) == 0)
+ do_login(232, name);
+ else
+ reply(530, "User %s access denied.", name);
+ } else {
+ char ss[256];
+
+#ifdef OTP
+ if (otp_challenge(&otp_ctx, name, ss, sizeof(ss)) == 0) {
+ reply(331, "Password %s for %s required.",
+ ss, name);
+ askpasswd = 1;
+ } else
+#endif
+ if ((auth_level & AUTH_OTP) == 0) {
+ reply(331, "Password required for %s.", name);
+ askpasswd = 1;
+ } else {
+ char *s;
+
+#ifdef OTP
+ if ((s = otp_error (&otp_ctx)) != NULL)
+ lreply(530, "OTP: %s", s);
+#endif
+ reply(530,
+ "Only authorized, anonymous"
+#ifdef OTP
+ " and OTP "
+#endif
+ "login allowed.");
+ }
+
+ }
+ /*
+ * Delay before reading passwd after first failed
+ * attempt to slow down passwd-guessing programs.
+ */
+ if (login_attempts)
+ sleep(login_attempts);
+}
+
+/*
+ * Check if a user is in the file "fname"
+ */
+static int
+checkuser(char *fname, char *name)
+{
+ FILE *fd;
+ int found = 0;
+ char *p, line[BUFSIZ];
+
+ if ((fd = fopen(fname, "r")) != NULL) {
+ while (fgets(line, sizeof(line), fd) != NULL)
+ if ((p = strchr(line, '\n')) != NULL) {
+ *p = '\0';
+ if (line[0] == '#')
+ continue;
+ if (strcmp(line, name) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ fclose(fd);
+ }
+ return (found);
+}
+
+
+/*
+ * Determine whether a user has access, based on information in
+ * _PATH_FTPUSERS. The users are listed one per line, with `allow'
+ * or `deny' after the username. If anything other than `allow', or
+ * just nothing, is given after the username, `deny' is assumed.
+ *
+ * If the user is not found in the file, but the pseudo-user `*' is,
+ * the permission is taken from that line.
+ *
+ * This preserves the old semantics where if a user was listed in the
+ * file he was denied, otherwise he was allowed.
+ *
+ * Return 1 if the user is denied, or 0 if he is allowed. */
+
+static int
+match(const char *pattern, const char *string)
+{
+ return fnmatch(pattern, string, FNM_NOESCAPE);
+}
+
+static int
+checkaccess(char *name)
+{
+#define ALLOWED 0
+#define NOT_ALLOWED 1
+ FILE *fd;
+ int allowed = ALLOWED;
+ char *user, *perm, line[BUFSIZ];
+ char *foo;
+
+ fd = fopen(_PATH_FTPUSERS, "r");
+
+ if(fd == NULL)
+ return allowed;
+
+ while (fgets(line, sizeof(line), fd) != NULL) {
+ foo = NULL;
+ user = strtok_r(line, " \t\n", &foo);
+ if (user == NULL || user[0] == '#')
+ continue;
+ perm = strtok_r(NULL, " \t\n", &foo);
+ if (match(user, name) == 0){
+ if(perm && strcmp(perm, "allow") == 0)
+ allowed = ALLOWED;
+ else
+ allowed = NOT_ALLOWED;
+ break;
+ }
+ }
+ fclose(fd);
+ return allowed;
+}
+#undef ALLOWED
+#undef NOT_ALLOWED
+
+
+int do_login(int code, char *passwd)
+{
+ FILE *fd;
+ login_attempts = 0; /* this time successful */
+ if (setegid((gid_t)pw->pw_gid) < 0) {
+ reply(550, "Can't set gid.");
+ return -1;
+ }
+ initgroups(pw->pw_name, pw->pw_gid);
+
+ /* open wtmp before chroot */
+ ftpd_logwtmp(ttyline, pw->pw_name, remotehost);
+ logged_in = 1;
+
+ dochroot = checkuser(_PATH_FTPCHROOT, pw->pw_name);
+ if (guest) {
+ /*
+ * We MUST do a chdir() after the chroot. Otherwise
+ * the old current directory will be accessible as "."
+ * outside the new root!
+ */
+ if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
+ reply(550, "Can't set guest privileges.");
+ return -1;
+ }
+ } else if (dochroot) {
+ if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
+ reply(550, "Can't change root.");
+ return -1;
+ }
+ } else if (chdir(pw->pw_dir) < 0) {
+ if (chdir("/") < 0) {
+ reply(530, "User %s: can't change directory to %s.",
+ pw->pw_name, pw->pw_dir);
+ return -1;
+ } else
+ lreply(code, "No directory! Logging in with home=/");
+ }
+ if (seteuid((uid_t)pw->pw_uid) < 0) {
+ reply(550, "Can't set uid.");
+ return -1;
+ }
+
+ if(use_builtin_ls == -1) {
+ struct stat st;
+ /* if /bin/ls exist and is a regular file, use it, otherwise
+ use built-in ls */
+ if(stat("/bin/ls", &st) == 0 &&
+ S_ISREG(st.st_mode))
+ use_builtin_ls = 0;
+ else
+ use_builtin_ls = 1;
+ }
+
+ /*
+ * Display a login message, if it exists.
+ * N.B. reply(code,) must follow the message.
+ */
+ show_file(_PATH_FTPLOGINMESG, code);
+ if(show_file(_PATH_ISSUE_NET, code) != 0)
+ show_file(_PATH_ISSUE, code);
+ if (guest) {
+ reply(code, "Guest login ok, access restrictions apply.");
+#ifdef HAVE_SETPROCTITLE
+ snprintf (proctitle, sizeof(proctitle),
+ "%s: anonymous/%s",
+ remotehost,
+ passwd);
+ setproctitle(proctitle);
+#endif /* HAVE_SETPROCTITLE */
+ if (logging) {
+ char data_addr[256];
+
+ if (inet_ntop (his_addr->sa_family,
+ socket_get_address(his_addr),
+ data_addr, sizeof(data_addr)) == NULL)
+ strlcpy (data_addr, "unknown address",
+ sizeof(data_addr));
+
+ syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s(%s), %s",
+ remotehost,
+ data_addr,
+ passwd);
+ }
+ } else {
+ reply(code, "User %s logged in.", pw->pw_name);
+#ifdef HAVE_SETPROCTITLE
+ snprintf(proctitle, sizeof(proctitle), "%s: %s", remotehost, pw->pw_name);
+ setproctitle(proctitle);
+#endif /* HAVE_SETPROCTITLE */
+ if (logging) {
+ char data_addr[256];
+
+ if (inet_ntop (his_addr->sa_family,
+ socket_get_address(his_addr),
+ data_addr, sizeof(data_addr)) == NULL)
+ strlcpy (data_addr, "unknown address",
+ sizeof(data_addr));
+
+ syslog(LOG_INFO, "FTP LOGIN FROM %s(%s) as %s",
+ remotehost,
+ data_addr,
+ pw->pw_name);
+ }
+ }
+ umask(defumask);
+ return 0;
+}
+
+/*
+ * Terminate login as previous user, if any, resetting state;
+ * used when USER command is given or login fails.
+ */
+static void
+end_login(void)
+{
+
+ seteuid((uid_t)0);
+ if (logged_in)
+ ftpd_logwtmp(ttyline, "", "");
+ pw = NULL;
+ logged_in = 0;
+ guest = 0;
+ dochroot = 0;
+}
+
+void
+pass(char *passwd)
+{
+ int rval;
+
+ /* some clients insists on sending a password */
+ if (logged_in && askpasswd == 0){
+ reply(230, "Dumpucko!");
+ return;
+ }
+
+ if (logged_in || askpasswd == 0) {
+ reply(503, "Login with USER first.");
+ return;
+ }
+ askpasswd = 0;
+ rval = 1;
+ if (!guest) { /* "ftp" is only account allowed no password */
+ if (pw == NULL)
+ rval = 1; /* failure below */
+#ifdef OTP
+ else if (otp_verify_user (&otp_ctx, passwd) == 0) {
+ rval = 0;
+ }
+#endif
+ else if((auth_level & AUTH_OTP) == 0) {
+#ifdef KRB4
+ char realm[REALM_SZ];
+ if((rval = krb_get_lrealm(realm, 1)) == KSUCCESS)
+ rval = krb_verify_user(pw->pw_name,
+ "", realm,
+ passwd,
+ KRB_VERIFY_SECURE, NULL);
+ if (rval == KSUCCESS ) {
+ chown (tkt_string(), pw->pw_uid, pw->pw_gid);
+ if(k_hasafs())
+ krb_afslog(0, 0);
+ } else
+#endif
+ rval = unix_verify_user(pw->pw_name, passwd);
+ } else {
+ char *s;
+
+#ifdef OTP
+ if ((s = otp_error(&otp_ctx)) != NULL)
+ lreply(530, "OTP: %s", s);
+#endif
+ }
+ memset (passwd, 0, strlen(passwd));
+
+ /*
+ * If rval == 1, the user failed the authentication
+ * check above. If rval == 0, either Kerberos or
+ * local authentication succeeded.
+ */
+ if (rval) {
+ char data_addr[256];
+
+ if (inet_ntop (his_addr->sa_family,
+ socket_get_address(his_addr),
+ data_addr, sizeof(data_addr)) == NULL)
+ strlcpy (data_addr, "unknown address",
+ sizeof(data_addr));
+
+ reply(530, "Login incorrect.");
+ if (logging)
+ syslog(LOG_NOTICE,
+ "FTP LOGIN FAILED FROM %s(%s), %s",
+ remotehost,
+ data_addr,
+ curname);
+ pw = NULL;
+ if (login_attempts++ >= 5) {
+ syslog(LOG_NOTICE,
+ "repeated login failures from %s(%s)",
+ remotehost,
+ data_addr);
+ exit(0);
+ }
+ return;
+ }
+ }
+ if(!do_login(230, passwd))
+ return;
+
+ /* Forget all about it... */
+ end_login();
+}
+
+void
+retrieve(const char *cmd, char *name)
+{
+ FILE *fin = NULL, *dout;
+ struct stat st;
+ int (*closefunc) (FILE *);
+ char line[BUFSIZ];
+
+
+ if (cmd == 0) {
+ fin = fopen(name, "r");
+ closefunc = fclose;
+ st.st_size = 0;
+ if(fin == NULL){
+ int save_errno = errno;
+ struct cmds {
+ const char *ext;
+ const char *cmd;
+ const char *rev_cmd;
+ } cmds[] = {
+ {".tar", "/bin/gtar cPf - %s", NULL},
+ {".tar.gz", "/bin/gtar zcPf - %s", NULL},
+ {".tar.Z", "/bin/gtar ZcPf - %s", NULL},
+ {".gz", "/bin/gzip -c -- %s", "/bin/gzip -c -d -- %s"},
+ {".Z", "/bin/compress -c -- %s", "/bin/uncompress -c -- %s"},
+ {NULL, NULL}
+ };
+ struct cmds *p;
+ for(p = cmds; p->ext; p++){
+ char *tail = name + strlen(name) - strlen(p->ext);
+ char c = *tail;
+
+ if(strcmp(tail, p->ext) == 0 &&
+ (*tail = 0) == 0 &&
+ access(name, R_OK) == 0){
+ snprintf (line, sizeof(line), p->cmd, name);
+ *tail = c;
+ break;
+ }
+ *tail = c;
+ if (p->rev_cmd != NULL) {
+ char *ext;
+
+ asprintf(&ext, "%s%s", name, p->ext);
+ if (ext != NULL) {
+ if (access(ext, R_OK) == 0) {
+ snprintf (line, sizeof(line),
+ p->rev_cmd, ext);
+ free(ext);
+ break;
+ }
+ free(ext);
+ }
+ }
+
+ }
+ if(p->ext){
+ fin = ftpd_popen(line, "r", 0, 0);
+ closefunc = ftpd_pclose;
+ st.st_size = -1;
+ cmd = line;
+ } else
+ errno = save_errno;
+ }
+ } else {
+ snprintf(line, sizeof(line), cmd, name);
+ name = line;
+ fin = ftpd_popen(line, "r", 1, 0);
+ closefunc = ftpd_pclose;
+ st.st_size = -1;
+ }
+ if (fin == NULL) {
+ if (errno != 0) {
+ perror_reply(550, name);
+ if (cmd == 0) {
+ LOGCMD("get", name);
+ }
+ }
+ return;
+ }
+ byte_count = -1;
+ if (cmd == 0){
+ if(fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode)) {
+ reply(550, "%s: not a plain file.", name);
+ goto done;
+ }
+ }
+ if (restart_point) {
+ if (type == TYPE_A) {
+ off_t i, n;
+ int c;
+
+ n = restart_point;
+ i = 0;
+ while (i++ < n) {
+ if ((c=getc(fin)) == EOF) {
+ perror_reply(550, name);
+ goto done;
+ }
+ if (c == '\n')
+ i++;
+ }
+ } else if (lseek(fileno(fin), restart_point, SEEK_SET) < 0) {
+ perror_reply(550, name);
+ goto done;
+ }
+ }
+ dout = dataconn(name, st.st_size, "w");
+ if (dout == NULL)
+ goto done;
+ set_buffer_size(fileno(dout), 0);
+ send_data(fin, dout);
+ fclose(dout);
+ data = -1;
+ pdata = -1;
+done:
+ if (cmd == 0)
+ LOGBYTES("get", name, byte_count);
+ (*closefunc)(fin);
+}
+
+/* filename sanity check */
+
+int
+filename_check(char *filename)
+{
+ static const char good_chars[] = "+-=_,.";
+ char *p;
+
+ p = strrchr(filename, '/');
+ if(p)
+ filename = p + 1;
+
+ p = filename;
+
+ if(isalnum(*p)){
+ p++;
+ while(*p && (isalnum(*p) || strchr(good_chars, *p)))
+ p++;
+ if(*p == '\0')
+ return 0;
+ }
+ lreply(553, "\"%s\" is an illegal filename.", filename);
+ lreply(553, "The filename must start with an alphanumeric "
+ "character and must only");
+ reply(553, "consist of alphanumeric characters or any of the following: %s",
+ good_chars);
+ return 1;
+}
+
+void
+do_store(char *name, char *mode, int unique)
+{
+ FILE *fout, *din;
+ struct stat st;
+ int (*closefunc) (FILE *);
+
+ if(guest && filename_check(name))
+ return;
+ if (unique && stat(name, &st) == 0 &&
+ (name = gunique(name)) == NULL) {
+ LOGCMD(*mode == 'w' ? "put" : "append", name);
+ return;
+ }
+
+ if (restart_point)
+ mode = "r+";
+ fout = fopen(name, mode);
+ closefunc = fclose;
+ if (fout == NULL) {
+ perror_reply(553, name);
+ LOGCMD(*mode == 'w' ? "put" : "append", name);
+ return;
+ }
+ byte_count = -1;
+ if (restart_point) {
+ if (type == TYPE_A) {
+ off_t i, n;
+ int c;
+
+ n = restart_point;
+ i = 0;
+ while (i++ < n) {
+ if ((c=getc(fout)) == EOF) {
+ perror_reply(550, name);
+ goto done;
+ }
+ if (c == '\n')
+ i++;
+ }
+ /*
+ * We must do this seek to "current" position
+ * because we are changing from reading to
+ * writing.
+ */
+ if (fseek(fout, 0L, SEEK_CUR) < 0) {
+ perror_reply(550, name);
+ goto done;
+ }
+ } else if (lseek(fileno(fout), restart_point, SEEK_SET) < 0) {
+ perror_reply(550, name);
+ goto done;
+ }
+ }
+ din = dataconn(name, (off_t)-1, "r");
+ if (din == NULL)
+ goto done;
+ set_buffer_size(fileno(din), 1);
+ if (receive_data(din, fout) == 0) {
+ if (unique)
+ reply(226, "Transfer complete (unique file name:%s).",
+ name);
+ else
+ reply(226, "Transfer complete.");
+ }
+ fclose(din);
+ data = -1;
+ pdata = -1;
+done:
+ LOGBYTES(*mode == 'w' ? "put" : "append", name, byte_count);
+ (*closefunc)(fout);
+}
+
+static FILE *
+getdatasock(const char *mode)
+{
+ int s, t, tries;
+
+ if (data >= 0)
+ return (fdopen(data, mode));
+ seteuid(0);
+ s = socket(ctrl_addr->sa_family, SOCK_STREAM, 0);
+ if (s < 0)
+ goto bad;
+ socket_set_reuseaddr (s, 1);
+ /* anchor socket to avoid multi-homing problems */
+ socket_set_address_and_port (data_source,
+ socket_get_address (ctrl_addr),
+ socket_get_port (data_source));
+
+ for (tries = 1; ; tries++) {
+ if (bind(s, data_source,
+ socket_sockaddr_size (data_source)) >= 0)
+ break;
+ if (errno != EADDRINUSE || tries > 10)
+ goto bad;
+ sleep(tries);
+ }
+ seteuid(pw->pw_uid);
+#ifdef IPTOS_THROUGHPUT
+ socket_set_tos (s, IPTOS_THROUGHPUT);
+#endif
+ return (fdopen(s, mode));
+bad:
+ /* Return the real value of errno (close may change it) */
+ t = errno;
+ seteuid((uid_t)pw->pw_uid);
+ close(s);
+ errno = t;
+ return (NULL);
+}
+
+static FILE *
+dataconn(const char *name, off_t size, const char *mode)
+{
+ char sizebuf[32];
+ FILE *file;
+ int retry = 0;
+
+ file_size = size;
+ byte_count = 0;
+ if (size >= 0)
+ snprintf(sizebuf, sizeof(sizebuf), " (%ld bytes)", (long)size);
+ else
+ *sizebuf = '\0';
+ if (pdata >= 0) {
+ struct sockaddr_storage from_ss;
+ struct sockaddr *from = (struct sockaddr *)&from_ss;
+ int s;
+ int fromlen = sizeof(from_ss);
+
+ s = accept(pdata, from, &fromlen);
+ if (s < 0) {
+ reply(425, "Can't open data connection.");
+ close(pdata);
+ pdata = -1;
+ return (NULL);
+ }
+ close(pdata);
+ pdata = s;
+#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
+ {
+ int tos = IPTOS_THROUGHPUT;
+
+ setsockopt(s, IPPROTO_IP, IP_TOS, (void *)&tos,
+ sizeof(tos));
+ }
+#endif
+ reply(150, "Opening %s mode data connection for '%s'%s.",
+ type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+ return (fdopen(pdata, mode));
+ }
+ if (data >= 0) {
+ reply(125, "Using existing data connection for '%s'%s.",
+ name, sizebuf);
+ usedefault = 1;
+ return (fdopen(data, mode));
+ }
+ if (usedefault)
+ data_dest = his_addr;
+ usedefault = 1;
+ file = getdatasock(mode);
+ if (file == NULL) {
+ char data_addr[256];
+
+ if (inet_ntop (data_source->sa_family,
+ socket_get_address(data_source),
+ data_addr, sizeof(data_addr)) == NULL)
+ strlcpy (data_addr, "unknown address",
+ sizeof(data_addr));
+
+ reply(425, "Can't create data socket (%s,%d): %s.",
+ data_addr,
+ socket_get_port (data_source),
+ strerror(errno));
+ return (NULL);
+ }
+ data = fileno(file);
+ while (connect(data, data_dest,
+ socket_sockaddr_size(data_dest)) < 0) {
+ if (errno == EADDRINUSE && retry < swaitmax) {
+ sleep(swaitint);
+ retry += swaitint;
+ continue;
+ }
+ perror_reply(425, "Can't build data connection");
+ fclose(file);
+ data = -1;
+ return (NULL);
+ }
+ reply(150, "Opening %s mode data connection for '%s'%s.",
+ type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+ return (file);
+}
+
+/*
+ * Tranfer the contents of "instr" to "outstr" peer using the appropriate
+ * encapsulation of the data subject * to Mode, Structure, and Type.
+ *
+ * NB: Form isn't handled.
+ */
+static void
+send_data(FILE *instr, FILE *outstr)
+{
+ int c, cnt, filefd, netfd;
+ static char *buf;
+ static size_t bufsize;
+
+ transflag++;
+ if (setjmp(urgcatch)) {
+ transflag = 0;
+ return;
+ }
+ switch (type) {
+
+ case TYPE_A:
+ while ((c = getc(instr)) != EOF) {
+ byte_count++;
+ if(c == '\n')
+ sec_putc('\r', outstr);
+ sec_putc(c, outstr);
+ }
+ sec_fflush(outstr);
+ transflag = 0;
+ if (ferror(instr))
+ goto file_err;
+ if (ferror(outstr))
+ goto data_err;
+ reply(226, "Transfer complete.");
+ return;
+
+ case TYPE_I:
+ case TYPE_L:
+#if defined(HAVE_MMAP) && !defined(NO_MMAP)
+#ifndef MAP_FAILED
+#define MAP_FAILED (-1)
+#endif
+ {
+ struct stat st;
+ char *chunk;
+ int in = fileno(instr);
+ if(fstat(in, &st) == 0 && S_ISREG(st.st_mode)
+ && st.st_size > 0) {
+ /*
+ * mmap zero bytes has potential of loosing, don't do it.
+ */
+ chunk = mmap(0, st.st_size, PROT_READ,
+ MAP_SHARED, in, 0);
+ if((void *)chunk != (void *)MAP_FAILED) {
+ cnt = st.st_size - restart_point;
+ sec_write(fileno(outstr), chunk + restart_point, cnt);
+ if (munmap(chunk, st.st_size) < 0)
+ warn ("munmap");
+ sec_fflush(outstr);
+ byte_count = cnt;
+ transflag = 0;
+ }
+ }
+ }
+#endif
+ if(transflag) {
+ struct stat st;
+
+ netfd = fileno(outstr);
+ filefd = fileno(instr);
+ buf = alloc_buffer (buf, &bufsize,
+ fstat(filefd, &st) >= 0 ? &st : NULL);
+ if (buf == NULL) {
+ transflag = 0;
+ perror_reply(451, "Local resource failure: malloc");
+ return;
+ }
+ while ((cnt = read(filefd, buf, bufsize)) > 0 &&
+ sec_write(netfd, buf, cnt) == cnt)
+ byte_count += cnt;
+ sec_fflush(outstr); /* to end an encrypted stream */
+ transflag = 0;
+ if (cnt != 0) {
+ if (cnt < 0)
+ goto file_err;
+ goto data_err;
+ }
+ }
+ reply(226, "Transfer complete.");
+ return;
+ default:
+ transflag = 0;
+ reply(550, "Unimplemented TYPE %d in send_data", type);
+ return;
+ }
+
+data_err:
+ transflag = 0;
+ perror_reply(426, "Data connection");
+ return;
+
+file_err:
+ transflag = 0;
+ perror_reply(551, "Error on input file");
+}
+
+/*
+ * Transfer data from peer to "outstr" using the appropriate encapulation of
+ * the data subject to Mode, Structure, and Type.
+ *
+ * N.B.: Form isn't handled.
+ */
+static int
+receive_data(FILE *instr, FILE *outstr)
+{
+ int cnt, bare_lfs = 0;
+ static char *buf;
+ static size_t bufsize;
+ struct stat st;
+
+ transflag++;
+ if (setjmp(urgcatch)) {
+ transflag = 0;
+ return (-1);
+ }
+
+ buf = alloc_buffer (buf, &bufsize,
+ fstat(fileno(outstr), &st) >= 0 ? &st : NULL);
+ if (buf == NULL) {
+ transflag = 0;
+ perror_reply(451, "Local resource failure: malloc");
+ return -1;
+ }
+
+ switch (type) {
+
+ case TYPE_I:
+ case TYPE_L:
+ while ((cnt = sec_read(fileno(instr), buf, bufsize)) > 0) {
+ if (write(fileno(outstr), buf, cnt) != cnt)
+ goto file_err;
+ byte_count += cnt;
+ }
+ if (cnt < 0)
+ goto data_err;
+ transflag = 0;
+ return (0);
+
+ case TYPE_E:
+ reply(553, "TYPE E not implemented.");
+ transflag = 0;
+ return (-1);
+
+ case TYPE_A:
+ {
+ char *p, *q;
+ int cr_flag = 0;
+ while ((cnt = sec_read(fileno(instr),
+ buf + cr_flag,
+ bufsize - cr_flag)) > 0){
+ byte_count += cnt;
+ cnt += cr_flag;
+ cr_flag = 0;
+ for(p = buf, q = buf; p < buf + cnt;) {
+ if(*p == '\n')
+ bare_lfs++;
+ if(*p == '\r') {
+ if(p == buf + cnt - 1){
+ cr_flag = 1;
+ p++;
+ continue;
+ }else if(p[1] == '\n'){
+ *q++ = '\n';
+ p += 2;
+ continue;
+ }
+ }
+ *q++ = *p++;
+ }
+ fwrite(buf, q - buf, 1, outstr);
+ if(cr_flag)
+ buf[0] = '\r';
+ }
+ if(cr_flag)
+ putc('\r', outstr);
+ fflush(outstr);
+ if (ferror(instr))
+ goto data_err;
+ if (ferror(outstr))
+ goto file_err;
+ transflag = 0;
+ if (bare_lfs) {
+ lreply(226, "WARNING! %d bare linefeeds received in ASCII mode\r\n"
+ " File may not have transferred correctly.\r\n",
+ bare_lfs);
+ }
+ return (0);
+ }
+ default:
+ reply(550, "Unimplemented TYPE %d in receive_data", type);
+ transflag = 0;
+ return (-1);
+ }
+
+data_err:
+ transflag = 0;
+ perror_reply(426, "Data Connection");
+ return (-1);
+
+file_err:
+ transflag = 0;
+ perror_reply(452, "Error writing file");
+ return (-1);
+}
+
+void
+statfilecmd(char *filename)
+{
+ FILE *fin;
+ int c;
+ char line[LINE_MAX];
+
+ snprintf(line, sizeof(line), "/bin/ls -la -- %s", filename);
+ fin = ftpd_popen(line, "r", 1, 0);
+ lreply(211, "status of %s:", filename);
+ while ((c = getc(fin)) != EOF) {
+ if (c == '\n') {
+ if (ferror(stdout)){
+ perror_reply(421, "control connection");
+ ftpd_pclose(fin);
+ dologout(1);
+ /* NOTREACHED */
+ }
+ if (ferror(fin)) {
+ perror_reply(551, filename);
+ ftpd_pclose(fin);
+ return;
+ }
+ putc('\r', stdout);
+ }
+ putc(c, stdout);
+ }
+ ftpd_pclose(fin);
+ reply(211, "End of Status");
+}
+
+void
+statcmd(void)
+{
+#if 0
+ struct sockaddr_in *sin;
+ u_char *a, *p;
+
+ lreply(211, "%s FTP server (%s) status:", hostname, version);
+ printf(" %s\r\n", version);
+ printf(" Connected to %s", remotehost);
+ if (!isdigit(remotehost[0]))
+ printf(" (%s)", inet_ntoa(his_addr.sin_addr));
+ printf("\r\n");
+ if (logged_in) {
+ if (guest)
+ printf(" Logged in anonymously\r\n");
+ else
+ printf(" Logged in as %s\r\n", pw->pw_name);
+ } else if (askpasswd)
+ printf(" Waiting for password\r\n");
+ else
+ printf(" Waiting for user name\r\n");
+ printf(" TYPE: %s", typenames[type]);
+ if (type == TYPE_A || type == TYPE_E)
+ printf(", FORM: %s", formnames[form]);
+ if (type == TYPE_L)
+#if NBBY == 8
+ printf(" %d", NBBY);
+#else
+ printf(" %d", bytesize); /* need definition! */
+#endif
+ printf("; STRUcture: %s; transfer MODE: %s\r\n",
+ strunames[stru], modenames[mode]);
+ if (data != -1)
+ printf(" Data connection open\r\n");
+ else if (pdata != -1) {
+ printf(" in Passive mode");
+ sin = &pasv_addr;
+ goto printaddr;
+ } else if (usedefault == 0) {
+ printf(" PORT");
+ sin = &data_dest;
+printaddr:
+ a = (u_char *) &sin->sin_addr;
+ p = (u_char *) &sin->sin_port;
+#define UC(b) (((int) b) & 0xff)
+ printf(" (%d,%d,%d,%d,%d,%d)\r\n", UC(a[0]),
+ UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
+#undef UC
+ } else
+ printf(" No data connection\r\n");
+#endif
+ reply(211, "End of status");
+}
+
+void
+fatal(char *s)
+{
+
+ reply(451, "Error in server: %s\n", s);
+ reply(221, "Closing connection due to server error.");
+ dologout(0);
+ /* NOTREACHED */
+}
+
+static void
+int_reply(int, char *, const char *, va_list)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 3, 0)))
+#endif
+;
+
+static void
+int_reply(int n, char *c, const char *fmt, va_list ap)
+{
+ char buf[10240];
+ char *p;
+ p=buf;
+ if(n){
+ snprintf(p, sizeof(buf), "%d%s", n, c);
+ p+=strlen(p);
+ }
+ vsnprintf(p, sizeof(buf) - strlen(p), fmt, ap);
+ p+=strlen(p);
+ snprintf(p, sizeof(buf) - strlen(p), "\r\n");
+ p+=strlen(p);
+ sec_fprintf(stdout, "%s", buf);
+ fflush(stdout);
+ if (debug)
+ syslog(LOG_DEBUG, "<--- %s- ", buf);
+}
+
+void
+reply(int n, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ int_reply(n, " ", fmt, ap);
+ delete_ftp_command();
+ va_end(ap);
+}
+
+void
+lreply(int n, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ int_reply(n, "-", fmt, ap);
+ va_end(ap);
+}
+
+void
+nreply(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ int_reply(0, NULL, fmt, ap);
+ va_end(ap);
+}
+
+static void
+ack(char *s)
+{
+
+ reply(250, "%s command successful.", s);
+}
+
+void
+nack(char *s)
+{
+
+ reply(502, "%s command not implemented.", s);
+}
+
+/* ARGSUSED */
+void
+yyerror(char *s)
+{
+ char *cp;
+
+ if ((cp = strchr(cbuf,'\n')))
+ *cp = '\0';
+ reply(500, "'%s': command not understood.", cbuf);
+}
+
+void
+do_delete(char *name)
+{
+ struct stat st;
+
+ LOGCMD("delete", name);
+ if (stat(name, &st) < 0) {
+ perror_reply(550, name);
+ return;
+ }
+ if ((st.st_mode&S_IFMT) == S_IFDIR) {
+ if (rmdir(name) < 0) {
+ perror_reply(550, name);
+ return;
+ }
+ goto done;
+ }
+ if (unlink(name) < 0) {
+ perror_reply(550, name);
+ return;
+ }
+done:
+ ack("DELE");
+}
+
+void
+cwd(char *path)
+{
+
+ if (chdir(path) < 0)
+ perror_reply(550, path);
+ else
+ ack("CWD");
+}
+
+void
+makedir(char *name)
+{
+
+ LOGCMD("mkdir", name);
+ if(guest && filename_check(name))
+ return;
+ if (mkdir(name, 0777) < 0)
+ perror_reply(550, name);
+ else{
+ if(guest)
+ chmod(name, 0700); /* guest has umask 777 */
+ reply(257, "MKD command successful.");
+ }
+}
+
+void
+removedir(char *name)
+{
+
+ LOGCMD("rmdir", name);
+ if (rmdir(name) < 0)
+ perror_reply(550, name);
+ else
+ ack("RMD");
+}
+
+void
+pwd(void)
+{
+ char path[MaxPathLen];
+ char *ret;
+
+ /* SunOS has a broken getcwd that does popen(pwd) (!!!), this
+ * failes miserably when running chroot
+ */
+ ret = getcwd(path, sizeof(path));
+ if (ret == NULL)
+ reply(550, "%s.", strerror(errno));
+ else
+ reply(257, "\"%s\" is current directory.", path);
+}
+
+char *
+renamefrom(char *name)
+{
+ struct stat st;
+
+ if (stat(name, &st) < 0) {
+ perror_reply(550, name);
+ return NULL;
+ }
+ reply(350, "File exists, ready for destination name");
+ return (name);
+}
+
+void
+renamecmd(char *from, char *to)
+{
+
+ LOGCMD2("rename", from, to);
+ if(guest && filename_check(to))
+ return;
+ if (rename(from, to) < 0)
+ perror_reply(550, "rename");
+ else
+ ack("RNTO");
+}
+
+static void
+dolog(struct sockaddr *sa, int len)
+{
+ getnameinfo_verified (sa, len, remotehost, sizeof(remotehost),
+ NULL, 0, 0);
+#ifdef HAVE_SETPROCTITLE
+ snprintf(proctitle, sizeof(proctitle), "%s: connected", remotehost);
+ setproctitle(proctitle);
+#endif /* HAVE_SETPROCTITLE */
+
+ if (logging) {
+ char data_addr[256];
+
+ if (inet_ntop (his_addr->sa_family,
+ socket_get_address(his_addr),
+ data_addr, sizeof(data_addr)) == NULL)
+ strlcpy (data_addr, "unknown address",
+ sizeof(data_addr));
+
+
+ syslog(LOG_INFO, "connection from %s(%s)",
+ remotehost,
+ data_addr);
+ }
+}
+
+/*
+ * Record logout in wtmp file
+ * and exit with supplied status.
+ */
+void
+dologout(int status)
+{
+ transflag = 0;
+ if (logged_in) {
+ seteuid((uid_t)0);
+ ftpd_logwtmp(ttyline, "", "");
+#ifdef KRB4
+ cond_kdestroy();
+#endif
+ }
+ /* beware of flushing buffers after a SIGPIPE */
+#ifdef XXX
+ exit(status);
+#else
+ _exit(status);
+#endif
+}
+
+void abor(void)
+{
+}
+
+static void
+myoob(int signo)
+{
+#if 0
+ char *cp;
+#endif
+
+ /* only process if transfer occurring */
+ if (!transflag)
+ return;
+
+ /* This is all XXX */
+ oobflag = 1;
+ /* if the command resulted in a new command,
+ parse that as well */
+ do{
+ yyparse();
+ } while(ftp_command);
+ oobflag = 0;
+
+#if 0
+ cp = tmpline;
+ if (ftpd_getline(cp, 7) == NULL) {
+ reply(221, "You could at least say goodbye.");
+ dologout(0);
+ }
+ upper(cp);
+ if (strcmp(cp, "ABOR\r\n") == 0) {
+ tmpline[0] = '\0';
+ reply(426, "Transfer aborted. Data connection closed.");
+ reply(226, "Abort successful");
+ longjmp(urgcatch, 1);
+ }
+ if (strcmp(cp, "STAT\r\n") == 0) {
+ if (file_size != (off_t) -1)
+ reply(213, "Status: %ld of %ld bytes transferred",
+ (long)byte_count,
+ (long)file_size);
+ else
+ reply(213, "Status: %ld bytes transferred"
+ (long)byte_count);
+ }
+#endif
+}
+
+/*
+ * Note: a response of 425 is not mentioned as a possible response to
+ * the PASV command in RFC959. However, it has been blessed as
+ * a legitimate response by Jon Postel in a telephone conversation
+ * with Rick Adams on 25 Jan 89.
+ */
+void
+pasv(void)
+{
+ int len;
+ char *p, *a;
+ struct sockaddr_in *sin;
+
+ if (ctrl_addr->sa_family != AF_INET) {
+ reply(425,
+ "You cannot do PASV with something that's not IPv4");
+ return;
+ }
+
+ pdata = socket(ctrl_addr->sa_family, SOCK_STREAM, 0);
+ if (pdata < 0) {
+ perror_reply(425, "Can't open passive connection");
+ return;
+ }
+ pasv_addr->sa_family = ctrl_addr->sa_family;
+ socket_set_address_and_port (pasv_addr,
+ socket_get_address (ctrl_addr),
+ 0);
+ seteuid(0);
+ if (bind(pdata, pasv_addr, socket_sockaddr_size (pasv_addr)) < 0) {
+ seteuid(pw->pw_uid);
+ goto pasv_error;
+ }
+ seteuid(pw->pw_uid);
+ len = sizeof(pasv_addr_ss);
+ if (getsockname(pdata, pasv_addr, &len) < 0)
+ goto pasv_error;
+ if (listen(pdata, 1) < 0)
+ goto pasv_error;
+ sin = (struct sockaddr_in *)pasv_addr;
+ a = (char *) &sin->sin_addr;
+ p = (char *) &sin->sin_port;
+
+#define UC(b) (((int) b) & 0xff)
+
+ reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]),
+ UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
+ return;
+
+pasv_error:
+ close(pdata);
+ pdata = -1;
+ perror_reply(425, "Can't open passive connection");
+ return;
+}
+
+void
+epsv(char *proto)
+{
+ int len;
+
+ pdata = socket(ctrl_addr->sa_family, SOCK_STREAM, 0);
+ if (pdata < 0) {
+ perror_reply(425, "Can't open passive connection");
+ return;
+ }
+ pasv_addr->sa_family = ctrl_addr->sa_family;
+ socket_set_address_and_port (pasv_addr,
+ socket_get_address (ctrl_addr),
+ 0);
+ seteuid(0);
+ if (bind(pdata, pasv_addr, socket_sockaddr_size (pasv_addr)) < 0) {
+ seteuid(pw->pw_uid);
+ goto pasv_error;
+ }
+ seteuid(pw->pw_uid);
+ len = sizeof(pasv_addr_ss);
+ if (getsockname(pdata, pasv_addr, &len) < 0)
+ goto pasv_error;
+ if (listen(pdata, 1) < 0)
+ goto pasv_error;
+
+ reply(229, "Entering Extended Passive Mode (|||%d|)",
+ ntohs(socket_get_port (pasv_addr)));
+ return;
+
+pasv_error:
+ close(pdata);
+ pdata = -1;
+ perror_reply(425, "Can't open passive connection");
+ return;
+}
+
+void
+eprt(char *str)
+{
+ char *end;
+ char sep;
+ int af;
+ int ret;
+ int port;
+
+ usedefault = 0;
+ if (pdata >= 0) {
+ close(pdata);
+ pdata = -1;
+ }
+
+ sep = *str++;
+ if (sep == '\0') {
+ reply(500, "Bad syntax in EPRT");
+ return;
+ }
+ af = strtol (str, &end, 0);
+ if (af == 0 || *end != sep) {
+ reply(500, "Bad syntax in EPRT");
+ return;
+ }
+ str = end + 1;
+ switch (af) {
+#ifdef HAVE_IPV6
+ case 2 :
+ data_dest->sa_family = AF_INET6;
+ break;
+#endif
+ case 1 :
+ data_dest->sa_family = AF_INET;
+ break;
+ default :
+ reply(522, "Network protocol %d not supported, use (1"
+#ifdef HAVE_IPV6
+ ",2"
+#endif
+ ")", af);
+ return;
+ }
+ end = strchr (str, sep);
+ if (end == NULL) {
+ reply(500, "Bad syntax in EPRT");
+ return;
+ }
+ *end = '\0';
+ ret = inet_pton (data_dest->sa_family, str,
+ socket_get_address (data_dest));
+
+ if (ret != 1) {
+ reply(500, "Bad address syntax in EPRT");
+ return;
+ }
+ str = end + 1;
+ port = strtol (str, &end, 0);
+ if (port == 0 || *end != sep) {
+ reply(500, "Bad port syntax in EPRT");
+ return;
+ }
+ socket_set_port (data_dest, htons(port));
+ reply(200, "EPRT command successful.");
+}
+
+/*
+ * Generate unique name for file with basename "local".
+ * The file named "local" is already known to exist.
+ * Generates failure reply on error.
+ */
+static char *
+gunique(char *local)
+{
+ static char new[MaxPathLen];
+ struct stat st;
+ int count;
+ char *cp;
+
+ cp = strrchr(local, '/');
+ if (cp)
+ *cp = '\0';
+ if (stat(cp ? local : ".", &st) < 0) {
+ perror_reply(553, cp ? local : ".");
+ return NULL;
+ }
+ if (cp)
+ *cp = '/';
+ for (count = 1; count < 100; count++) {
+ snprintf (new, sizeof(new), "%s.%d", local, count);
+ if (stat(new, &st) < 0)
+ return (new);
+ }
+ reply(452, "Unique file name cannot be created.");
+ return (NULL);
+}
+
+/*
+ * Format and send reply containing system error number.
+ */
+void
+perror_reply(int code, const char *string)
+{
+ reply(code, "%s: %s.", string, strerror(errno));
+}
+
+static char *onefile[] = {
+ "",
+ 0
+};
+
+void
+list_file(char *file)
+{
+ if(use_builtin_ls) {
+ FILE *dout;
+ dout = dataconn(file, -1, "w");
+ if (dout == NULL)
+ return;
+ set_buffer_size(fileno(dout), 0);
+ builtin_ls(dout, file);
+ reply(226, "Transfer complete.");
+ fclose(dout);
+ data = -1;
+ pdata = -1;
+ } else {
+#ifdef HAVE_LS_A
+ const char *cmd = "/bin/ls -lA -- %s";
+#else
+ const char *cmd = "/bin/ls -la -- %s";
+#endif
+ retrieve(cmd, file);
+ }
+}
+
+void
+send_file_list(char *whichf)
+{
+ struct stat st;
+ DIR *dirp = NULL;
+ struct dirent *dir;
+ FILE *dout = NULL;
+ char **dirlist, *dirname;
+ int simple = 0;
+ int freeglob = 0;
+ glob_t gl;
+ char buf[MaxPathLen];
+
+ if (strpbrk(whichf, "~{[*?") != NULL) {
+ int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+
+ memset(&gl, 0, sizeof(gl));
+ freeglob = 1;
+ if (glob(whichf, flags, 0, &gl)) {
+ reply(550, "not found");
+ goto out;
+ } else if (gl.gl_pathc == 0) {
+ errno = ENOENT;
+ perror_reply(550, whichf);
+ goto out;
+ }
+ dirlist = gl.gl_pathv;
+ } else {
+ onefile[0] = whichf;
+ dirlist = onefile;
+ simple = 1;
+ }
+
+ if (setjmp(urgcatch)) {
+ transflag = 0;
+ goto out;
+ }
+ while ((dirname = *dirlist++)) {
+ if (stat(dirname, &st) < 0) {
+ /*
+ * If user typed "ls -l", etc, and the client
+ * used NLST, do what the user meant.
+ */
+ if (dirname[0] == '-' && *dirlist == NULL &&
+ transflag == 0) {
+ retrieve("/bin/ls -- %s", dirname);
+ goto out;
+ }
+ perror_reply(550, whichf);
+ if (dout != NULL) {
+ fclose(dout);
+ transflag = 0;
+ data = -1;
+ pdata = -1;
+ }
+ goto out;
+ }
+
+ if (S_ISREG(st.st_mode)) {
+ if (dout == NULL) {
+ dout = dataconn("file list", (off_t)-1, "w");
+ if (dout == NULL)
+ goto out;
+ transflag++;
+ }
+ snprintf(buf, sizeof(buf), "%s%s\n", dirname,
+ type == TYPE_A ? "\r" : "");
+ sec_write(fileno(dout), buf, strlen(buf));
+ byte_count += strlen(dirname) + 1;
+ continue;
+ } else if (!S_ISDIR(st.st_mode))
+ continue;
+
+ if ((dirp = opendir(dirname)) == NULL)
+ continue;
+
+ while ((dir = readdir(dirp)) != NULL) {
+ char nbuf[MaxPathLen];
+
+ if (!strcmp(dir->d_name, "."))
+ continue;
+ if (!strcmp(dir->d_name, ".."))
+ continue;
+
+ snprintf(nbuf, sizeof(nbuf), "%s/%s", dirname, dir->d_name);
+
+ /*
+ * We have to do a stat to insure it's
+ * not a directory or special file.
+ */
+ if (simple || (stat(nbuf, &st) == 0 &&
+ S_ISREG(st.st_mode))) {
+ if (dout == NULL) {
+ dout = dataconn("file list", (off_t)-1, "w");
+ if (dout == NULL)
+ goto out;
+ transflag++;
+ }
+ if(strncmp(nbuf, "./", 2) == 0)
+ snprintf(buf, sizeof(buf), "%s%s\n", nbuf +2,
+ type == TYPE_A ? "\r" : "");
+ else
+ snprintf(buf, sizeof(buf), "%s%s\n", nbuf,
+ type == TYPE_A ? "\r" : "");
+ sec_write(fileno(dout), buf, strlen(buf));
+ byte_count += strlen(nbuf) + 1;
+ }
+ }
+ closedir(dirp);
+ }
+ if (dout == NULL)
+ reply(550, "No files found.");
+ else if (ferror(dout) != 0)
+ perror_reply(550, "Data connection");
+ else
+ reply(226, "Transfer complete.");
+
+ transflag = 0;
+ if (dout != NULL){
+ sec_write(fileno(dout), buf, 0); /* XXX flush */
+
+ fclose(dout);
+ }
+ data = -1;
+ pdata = -1;
+out:
+ if (freeglob) {
+ freeglob = 0;
+ globfree(&gl);
+ }
+}
+
+
+int
+find(char *pattern)
+{
+ char line[1024];
+ FILE *f;
+
+ snprintf(line, sizeof(line),
+ "/bin/locate -d %s -- %s",
+ ftp_rooted("/etc/locatedb"),
+ pattern);
+ f = ftpd_popen(line, "r", 1, 1);
+ if(f == NULL){
+ perror_reply(550, "/bin/locate");
+ return 1;
+ }
+ lreply(200, "Output from find.");
+ while(fgets(line, sizeof(line), f)){
+ if(line[strlen(line)-1] == '\n')
+ line[strlen(line)-1] = 0;
+ nreply("%s", line);
+ }
+ reply(200, "Done");
+ ftpd_pclose(f);
+ return 0;
+}
+
diff --git a/crypto/heimdal/appl/ftp/ftpd/ftpd_locl.h b/crypto/heimdal/appl/ftp/ftpd/ftpd_locl.h
new file mode 100644
index 000000000000..5cb49046b52a
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/ftpd_locl.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: ftpd_locl.h,v 1.9 1999/12/02 16:58:30 joda Exp $ */
+
+#ifndef __ftpd_locl_h__
+#define __ftpd_locl_h__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * FTP server.
+ */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#include <arpa/ftp.h>
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_TELNET_H
+#include <arpa/telnet.h>
+#endif
+
+#include <ctype.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include <errno.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <glob.h>
+#include <limits.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+#include <fnmatch.h>
+
+#ifdef HAVE_BSD_BSD_H
+#include <bsd/bsd.h>
+#endif
+
+#include <err.h>
+
+#include "pathnames.h"
+#include "extern.h"
+#include "common.h"
+
+#include "security.h"
+
+#include "roken.h"
+
+#ifdef KRB4
+#include <krb.h>
+#include <kafs.h>
+#endif
+
+#ifdef OTP
+#include <otp.h>
+#endif
+
+#ifdef SOCKS
+#include <socks.h>
+extern int LIBPREFIX(fclose) (FILE *);
+#endif
+
+/* SunOS doesn't have any declaration of fclose */
+
+int fclose(FILE *stream);
+
+int yyparse();
+
+#ifndef LOG_FTP
+#define LOG_FTP LOG_DAEMON
+#endif
+
+#endif /* __ftpd_locl_h__ */
diff --git a/crypto/heimdal/appl/ftp/ftpd/ftpusers.5 b/crypto/heimdal/appl/ftp/ftpd/ftpusers.5
new file mode 100644
index 000000000000..dfd66f94003b
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/ftpusers.5
@@ -0,0 +1,38 @@
+.\" $Id: ftpusers.5,v 1.2 1997/05/07 20:11:11 joda Exp $
+.\"
+.Dd May 7, 1997
+.Dt FTPUSERS 5
+.Os KTH-KRB
+.Sh NAME
+.Pa /etc/ftpusers
+.Nd
+FTP access list file.
+.Sh DESCRIPTION
+.Pa /etc/ftpusers
+contains a list of users that should be allowed or denied FTP
+access. Each line contains a user, optionally followed by
+.Dq allow
+(anything but
+.Dq allow
+is ignored). The semi-user
+.Dq *
+matches any user. Users that has an explicit
+.Dq allow ,
+or that does not match any line, are allowed access. Anyone else is
+denied access.
+
+Note that this is compatible with the old format, where this file
+contained a list of users that should be denied access.
+.Sh EXAMPLES
+This will deny anyone but
+.Dq foo
+and
+.Dq bar
+to use FTP:
+.Bd -literal
+foo allow
+bar allow
+*
+.Ed
+.Sh SEE ALSO
+.Xr ftpd 8
diff --git a/crypto/heimdal/appl/ftp/ftpd/gss_userok.c b/crypto/heimdal/appl/ftp/ftpd/gss_userok.c
new file mode 100644
index 000000000000..28e35960cc9d
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/gss_userok.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ftpd_locl.h"
+#include <gssapi.h>
+#include <krb5.h>
+
+RCSID("$Id: gss_userok.c,v 1.2 1999/12/02 16:58:31 joda Exp $");
+
+/* XXX a bit too much of krb5 dependency here...
+ What is the correct way to do this?
+ */
+
+extern krb5_context gssapi_krb5_context;
+
+/* XXX sync with gssapi.c */
+struct gss_data {
+ gss_ctx_id_t context_hdl;
+ char *client_name;
+};
+
+int gss_userok(void*, char*); /* to keep gcc happy */
+
+int
+gss_userok(void *app_data, char *username)
+{
+ struct gss_data *data = app_data;
+ if(gssapi_krb5_context) {
+ krb5_principal client;
+ krb5_error_code ret;
+ ret = krb5_parse_name(gssapi_krb5_context, data->client_name, &client);
+ if(ret)
+ return 1;
+ ret = krb5_kuserok(gssapi_krb5_context, client, username);
+ krb5_free_principal(gssapi_krb5_context, client);
+ return !ret;
+ }
+ return 1;
+}
diff --git a/crypto/heimdal/appl/ftp/ftpd/kauth.c b/crypto/heimdal/appl/ftp/ftpd/kauth.c
new file mode 100644
index 000000000000..dad4de540152
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/kauth.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "ftpd_locl.h"
+
+RCSID("$Id: kauth.c,v 1.25 1999/12/02 16:58:31 joda Exp $");
+
+static KTEXT_ST cip;
+static unsigned int lifetime;
+static time_t local_time;
+
+static krb_principal pr;
+
+static int do_destroy_tickets = 1;
+
+static int
+save_tkt(const char *user,
+ const char *instance,
+ const char *realm,
+ const void *arg,
+ key_proc_t key_proc,
+ KTEXT *cipp)
+{
+ local_time = time(0);
+ memmove(&cip, *cipp, sizeof(cip));
+ return -1;
+}
+
+static int
+store_ticket(KTEXT cip)
+{
+ char *ptr;
+ des_cblock session;
+ krb_principal sp;
+ unsigned char kvno;
+ KTEXT_ST tkt;
+ int left = cip->length;
+ int len;
+ int kerror;
+
+ ptr = (char *) cip->dat;
+
+ /* extract session key */
+ memmove(session, ptr, 8);
+ ptr += 8;
+ left -= 8;
+
+ len = strnlen(ptr, left);
+ if (len == left)
+ return(INTK_BADPW);
+
+ /* extract server's name */
+ strlcpy(sp.name, ptr, sizeof(sp.name));
+ ptr += len + 1;
+ left -= len + 1;
+
+ len = strnlen(ptr, left);
+ if (len == left)
+ return(INTK_BADPW);
+
+ /* extract server's instance */
+ strlcpy(sp.instance, ptr, sizeof(sp.instance));
+ ptr += len + 1;
+ left -= len + 1;
+
+ len = strnlen(ptr, left);
+ if (len == left)
+ return(INTK_BADPW);
+
+ /* extract server's realm */
+ strlcpy(sp.realm, ptr, sizeof(sp.realm));
+ ptr += len + 1;
+ left -= len + 1;
+
+ if(left < 3)
+ return INTK_BADPW;
+ /* extract ticket lifetime, server key version, ticket length */
+ /* be sure to avoid sign extension on lifetime! */
+ lifetime = (unsigned char) ptr[0];
+ kvno = (unsigned char) ptr[1];
+ tkt.length = (unsigned char) ptr[2];
+ ptr += 3;
+ left -= 3;
+
+ if (tkt.length > left)
+ return(INTK_BADPW);
+
+ /* extract ticket itself */
+ memmove(tkt.dat, ptr, tkt.length);
+ ptr += tkt.length;
+ left -= tkt.length;
+
+ /* Here is where the time should be verified against the KDC.
+ * Unfortunately everything is sent in host byte order (receiver
+ * makes wrong) , and at this stage there is no way for us to know
+ * which byteorder the KDC has. So we simply ignore the time,
+ * there are no security risks with this, the only thing that can
+ * happen is that we might receive a replayed ticket, which could
+ * at most be useless.
+ */
+
+#if 0
+ /* check KDC time stamp */
+ {
+ time_t kdc_time;
+
+ memmove(&kdc_time, ptr, sizeof(kdc_time));
+ if (swap_bytes) swap_u_long(kdc_time);
+
+ ptr += 4;
+
+ if (abs((int)(local_time - kdc_time)) > CLOCK_SKEW) {
+ return(RD_AP_TIME); /* XXX should probably be better
+ code */
+ }
+ }
+#endif
+
+ /* initialize ticket cache */
+
+ if (tf_create(TKT_FILE) != KSUCCESS)
+ return(INTK_ERR);
+
+ if (tf_put_pname(pr.name) != KSUCCESS ||
+ tf_put_pinst(pr.instance) != KSUCCESS) {
+ tf_close();
+ return(INTK_ERR);
+ }
+
+
+ kerror = tf_save_cred(sp.name, sp.instance, sp.realm, session,
+ lifetime, kvno, &tkt, local_time);
+ tf_close();
+
+ return(kerror);
+}
+
+void
+kauth(char *principal, char *ticket)
+{
+ char *p;
+ int ret;
+
+ if(get_command_prot() != prot_private) {
+ reply(500, "Request denied (bad protection level)");
+ return;
+ }
+ ret = krb_parse_name(principal, &pr);
+ if(ret){
+ reply(500, "Bad principal: %s.", krb_get_err_text(ret));
+ return;
+ }
+ if(pr.realm[0] == 0)
+ krb_get_lrealm(pr.realm, 1);
+
+ if(ticket){
+ cip.length = base64_decode(ticket, &cip.dat);
+ if(cip.length == -1){
+ reply(500, "Failed to decode data.");
+ return;
+ }
+ ret = store_ticket(&cip);
+ if(ret){
+ reply(500, "Kerberos error: %s.", krb_get_err_text(ret));
+ memset(&cip, 0, sizeof(cip));
+ return;
+ }
+ do_destroy_tickets = 1;
+
+ if(k_hasafs())
+ krb_afslog(0, 0);
+ reply(200, "Tickets will be destroyed on exit.");
+ return;
+ }
+
+ ret = krb_get_in_tkt (pr.name,
+ pr.instance,
+ pr.realm,
+ KRB_TICKET_GRANTING_TICKET,
+ pr.realm,
+ DEFAULT_TKT_LIFE,
+ NULL, save_tkt, NULL);
+ if(ret != INTK_BADPW){
+ reply(500, "Kerberos error: %s.", krb_get_err_text(ret));
+ return;
+ }
+ if(base64_encode(cip.dat, cip.length, &p) < 0) {
+ reply(500, "Out of memory while base64-encoding.");
+ return;
+ }
+ reply(300, "P=%s T=%s", krb_unparse_name(&pr), p);
+ free(p);
+ memset(&cip, 0, sizeof(cip));
+}
+
+
+static char *
+short_date(int32_t dp)
+{
+ char *cp;
+ time_t t = (time_t)dp;
+
+ if (t == (time_t)(-1L)) return "*** Never *** ";
+ cp = ctime(&t) + 4;
+ cp[15] = '\0';
+ return (cp);
+}
+
+void
+klist(void)
+{
+ int err;
+
+ char *file = tkt_string();
+
+ krb_principal pr;
+
+ char buf1[128], buf2[128];
+ int header = 1;
+ CREDENTIALS c;
+
+
+
+ err = tf_init(file, R_TKT_FIL);
+ if(err != KSUCCESS){
+ reply(500, "%s", krb_get_err_text(err));
+ return;
+ }
+ tf_close();
+
+ /*
+ * We must find the realm of the ticket file here before calling
+ * tf_init because since the realm of the ticket file is not
+ * really stored in the principal section of the file, the
+ * routine we use must itself call tf_init and tf_close.
+ */
+ err = krb_get_tf_realm(file, pr.realm);
+ if(err != KSUCCESS){
+ reply(500, "%s", krb_get_err_text(err));
+ return;
+ }
+
+ err = tf_init(file, R_TKT_FIL);
+ if(err != KSUCCESS){
+ reply(500, "%s", krb_get_err_text(err));
+ return;
+ }
+
+ err = tf_get_pname(pr.name);
+ if(err != KSUCCESS){
+ reply(500, "%s", krb_get_err_text(err));
+ return;
+ }
+ err = tf_get_pinst(pr.instance);
+ if(err != KSUCCESS){
+ reply(500, "%s", krb_get_err_text(err));
+ return;
+ }
+
+ /*
+ * You may think that this is the obvious place to get the
+ * realm of the ticket file, but it can't be done here as the
+ * routine to do this must open the ticket file. This is why
+ * it was done before tf_init.
+ */
+
+ lreply(200, "Ticket file: %s", tkt_string());
+
+ lreply(200, "Principal: %s", krb_unparse_name(&pr));
+ while ((err = tf_get_cred(&c)) == KSUCCESS) {
+ if (header) {
+ lreply(200, "%-15s %-15s %s",
+ " Issued", " Expires", " Principal (kvno)");
+ header = 0;
+ }
+ strlcpy(buf1, short_date(c.issue_date), sizeof(buf1));
+ c.issue_date = krb_life_to_time(c.issue_date, c.lifetime);
+ if (time(0) < (unsigned long) c.issue_date)
+ strlcpy(buf2, short_date(c.issue_date), sizeof(buf2));
+ else
+ strlcpy(buf2, ">>> Expired <<< ", sizeof(buf2));
+ lreply(200, "%s %s %s (%d)", buf1, buf2,
+ krb_unparse_name_long(c.service, c.instance, c.realm), c.kvno);
+ }
+ if (header && err == EOF) {
+ lreply(200, "No tickets in file.");
+ }
+ reply(200, " ");
+}
+
+/*
+ * Only destroy if we created the tickets
+ */
+
+void
+cond_kdestroy(void)
+{
+ if (do_destroy_tickets)
+ dest_tkt();
+ afsunlog();
+}
+
+void
+kdestroy(void)
+{
+ dest_tkt();
+ afsunlog();
+ reply(200, "Tickets destroyed");
+}
+
+void
+krbtkfile(const char *tkfile)
+{
+ do_destroy_tickets = 0;
+ krb_set_tkt_string(tkfile);
+ reply(200, "Using ticket file %s", tkfile);
+}
+
+void
+afslog(const char *cell)
+{
+ if(k_hasafs()) {
+ krb_afslog(cell, 0);
+ reply(200, "afslog done");
+ } else {
+ reply(200, "no AFS present");
+ }
+}
+
+void
+afsunlog(void)
+{
+ if(k_hasafs())
+ k_unlog();
+}
diff --git a/crypto/heimdal/appl/ftp/ftpd/logwtmp.c b/crypto/heimdal/appl/ftp/ftpd/logwtmp.c
new file mode 100644
index 000000000000..019cc2d17e02
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/logwtmp.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: logwtmp.c,v 1.14 1999/12/02 16:58:31 joda Exp $");
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+#include "extern.h"
+
+#ifndef WTMP_FILE
+#ifdef _PATH_WTMP
+#define WTMP_FILE _PATH_WTMP
+#else
+#define WTMP_FILE "/var/adm/wtmp"
+#endif
+#endif
+
+void
+ftpd_logwtmp(char *line, char *name, char *host)
+{
+ static int init = 0;
+ static int fd;
+#ifdef WTMPX_FILE
+ static int fdx;
+#endif
+ struct utmp ut;
+#ifdef WTMPX_FILE
+ struct utmpx utx;
+#endif
+
+ memset(&ut, 0, sizeof(struct utmp));
+#ifdef HAVE_STRUCT_UTMP_UT_TYPE
+ if(name[0])
+ ut.ut_type = USER_PROCESS;
+ else
+ ut.ut_type = DEAD_PROCESS;
+#endif
+ strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+#ifdef HAVE_STRUCT_UTMP_UT_PID
+ ut.ut_pid = getpid();
+#endif
+#ifdef HAVE_STRUCT_UTMP_UT_HOST
+ strncpy(ut.ut_host, host, sizeof(ut.ut_host));
+#endif
+ ut.ut_time = time(NULL);
+
+#ifdef WTMPX_FILE
+ strncpy(utx.ut_line, line, sizeof(utx.ut_line));
+ strncpy(utx.ut_user, name, sizeof(utx.ut_user));
+ strncpy(utx.ut_host, host, sizeof(utx.ut_host));
+#ifdef HAVE_STRUCT_UTMPX_UT_SYSLEN
+ utx.ut_syslen = strlen(host) + 1;
+ if (utx.ut_syslen > sizeof(utx.ut_host))
+ utx.ut_syslen = sizeof(utx.ut_host);
+#endif
+ {
+ struct timeval tv;
+
+ gettimeofday (&tv, 0);
+ utx.ut_tv.tv_sec = tv.tv_sec;
+ utx.ut_tv.tv_usec = tv.tv_usec;
+ }
+
+ if(name[0])
+ utx.ut_type = USER_PROCESS;
+ else
+ utx.ut_type = DEAD_PROCESS;
+#endif
+
+ if(!init){
+ fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0);
+#ifdef WTMPX_FILE
+ fdx = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0);
+#endif
+ init = 1;
+ }
+ if(fd >= 0) {
+ write(fd, &ut, sizeof(struct utmp)); /* XXX */
+#ifdef WTMPX_FILE
+ write(fdx, &utx, sizeof(struct utmpx));
+#endif
+ }
+}
diff --git a/crypto/heimdal/appl/ftp/ftpd/ls.c b/crypto/heimdal/appl/ftp/ftpd/ls.c
new file mode 100644
index 000000000000..2c8548711fa9
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/ls.c
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "ftpd_locl.h"
+
+RCSID("$Id: ls.c,v 1.14 2000/01/05 13:48:58 joda Exp $");
+
+struct fileinfo {
+ struct stat st;
+ int inode;
+ int bsize;
+ char mode[11];
+ int n_link;
+ char *user;
+ char *group;
+ char *size;
+ char *major;
+ char *minor;
+ char *date;
+ char *filename;
+ char *link;
+};
+
+static void
+free_fileinfo(struct fileinfo *f)
+{
+ free(f->user);
+ free(f->group);
+ free(f->size);
+ free(f->major);
+ free(f->minor);
+ free(f->date);
+ free(f->filename);
+ free(f->link);
+}
+
+#define LS_DIRS 1
+#define LS_IGNORE_DOT 2
+#define LS_SORT_MODE 12
+#define SORT_MODE(f) ((f) & LS_SORT_MODE)
+#define LS_SORT_NAME 4
+#define LS_SORT_MTIME 8
+#define LS_SORT_SIZE 12
+#define LS_SORT_REVERSE 16
+
+#define LS_SIZE 32
+#define LS_INODE 64
+
+#ifndef S_ISTXT
+#define S_ISTXT S_ISVTX
+#endif
+
+#ifndef S_ISSOCK
+#define S_ISSOCK(mode) (((mode) & _S_IFMT) == S_IFSOCK)
+#endif
+
+#ifndef S_ISLNK
+#define S_ISLNK(mode) (((mode) & _S_IFMT) == S_IFLNK)
+#endif
+
+static void
+make_fileinfo(const char *filename, struct fileinfo *file, int flags)
+{
+ char buf[128];
+ struct stat *st = &file->st;
+
+ file->inode = st->st_ino;
+#ifdef S_BLKSIZE
+ file->bsize = st->st_blocks * S_BLKSIZE / 1024;
+#else
+ file->bsize = st->st_blocks * 512 / 1024;
+#endif
+
+ if(S_ISDIR(st->st_mode))
+ file->mode[0] = 'd';
+ else if(S_ISCHR(st->st_mode))
+ file->mode[0] = 'c';
+ else if(S_ISBLK(st->st_mode))
+ file->mode[0] = 'b';
+ else if(S_ISREG(st->st_mode))
+ file->mode[0] = '-';
+ else if(S_ISFIFO(st->st_mode))
+ file->mode[0] = 'p';
+ else if(S_ISLNK(st->st_mode))
+ file->mode[0] = 'l';
+ else if(S_ISSOCK(st->st_mode))
+ file->mode[0] = 's';
+#ifdef S_ISWHT
+ else if(S_ISWHT(st->st_mode))
+ file->mode[0] = 'w';
+#endif
+ else
+ file->mode[0] = '?';
+ {
+ char *x[] = { "---", "--x", "-w-", "-wx",
+ "r--", "r-x", "rw-", "rwx" };
+ strcpy(file->mode + 1, x[(st->st_mode & S_IRWXU) >> 6]);
+ strcpy(file->mode + 4, x[(st->st_mode & S_IRWXG) >> 3]);
+ strcpy(file->mode + 7, x[(st->st_mode & S_IRWXO) >> 0]);
+ if((st->st_mode & S_ISUID)) {
+ if((st->st_mode & S_IXUSR))
+ file->mode[3] = 's';
+ else
+ file->mode[3] = 'S';
+ }
+ if((st->st_mode & S_ISGID)) {
+ if((st->st_mode & S_IXGRP))
+ file->mode[6] = 's';
+ else
+ file->mode[6] = 'S';
+ }
+ if((st->st_mode & S_ISTXT)) {
+ if((st->st_mode & S_IXOTH))
+ file->mode[9] = 't';
+ else
+ file->mode[9] = 'T';
+ }
+ }
+ file->n_link = st->st_nlink;
+ {
+ struct passwd *pwd;
+ pwd = getpwuid(st->st_uid);
+ if(pwd == NULL)
+ asprintf(&file->user, "%u", (unsigned)st->st_uid);
+ else
+ file->user = strdup(pwd->pw_name);
+ }
+ {
+ struct group *grp;
+ grp = getgrgid(st->st_gid);
+ if(grp == NULL)
+ asprintf(&file->group, "%u", (unsigned)st->st_gid);
+ else
+ file->group = strdup(grp->gr_name);
+ }
+
+ if(S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) {
+#if defined(major) && defined(minor)
+ asprintf(&file->major, "%u", (unsigned)major(st->st_rdev));
+ asprintf(&file->minor, "%u", (unsigned)minor(st->st_rdev));
+#else
+ /* Don't want to use the DDI/DKI crap. */
+ asprintf(&file->major, "%u", (unsigned)st->st_rdev);
+ asprintf(&file->minor, "%u", 0);
+#endif
+ } else
+ asprintf(&file->size, "%lu", (unsigned long)st->st_size);
+
+ {
+ time_t t = time(NULL);
+ struct tm *tm = localtime(&st->st_mtime);
+ if((t - st->st_mtime > 6*30*24*60*60) ||
+ (st->st_mtime - t > 6*30*24*60*60))
+ strftime(buf, sizeof(buf), "%b %e %Y", tm);
+ else
+ strftime(buf, sizeof(buf), "%b %e %H:%M", tm);
+ file->date = strdup(buf);
+ }
+ {
+ const char *p = strrchr(filename, '/');
+ if(p)
+ p++;
+ else
+ p = filename;
+ file->filename = strdup(p);
+ }
+ if(S_ISLNK(st->st_mode)) {
+ int n;
+ n = readlink((char *)filename, buf, sizeof(buf));
+ if(n >= 0) {
+ buf[n] = '\0';
+ file->link = strdup(buf);
+ } else
+ warn("%s: readlink", filename);
+ }
+}
+
+static void
+print_file(FILE *out,
+ int flags,
+ struct fileinfo *f,
+ int max_inode,
+ int max_bsize,
+ int max_n_link,
+ int max_user,
+ int max_group,
+ int max_size,
+ int max_major,
+ int max_minor,
+ int max_date)
+{
+ if(f->filename == NULL)
+ return;
+
+ if(flags & LS_INODE) {
+ sec_fprintf2(out, "%*d", max_inode, f->inode);
+ sec_fprintf2(out, " ");
+ }
+ if(flags & LS_SIZE) {
+ sec_fprintf2(out, "%*d", max_bsize, f->bsize);
+ sec_fprintf2(out, " ");
+ }
+ sec_fprintf2(out, "%s", f->mode);
+ sec_fprintf2(out, " ");
+ sec_fprintf2(out, "%*d", max_n_link, f->n_link);
+ sec_fprintf2(out, " ");
+ sec_fprintf2(out, "%-*s", max_user, f->user);
+ sec_fprintf2(out, " ");
+ sec_fprintf2(out, "%-*s", max_group, f->group);
+ sec_fprintf2(out, " ");
+ if(f->major != NULL && f->minor != NULL)
+ sec_fprintf2(out, "%*s, %*s", max_major, f->major, max_minor, f->minor);
+ else
+ sec_fprintf2(out, "%*s", max_size, f->size);
+ sec_fprintf2(out, " ");
+ sec_fprintf2(out, "%*s", max_date, f->date);
+ sec_fprintf2(out, " ");
+ sec_fprintf2(out, "%s", f->filename);
+ if(f->link)
+ sec_fprintf2(out, " -> %s", f->link);
+ sec_fprintf2(out, "\r\n");
+}
+
+static int
+compare_filename(struct fileinfo *a, struct fileinfo *b)
+{
+ if(a->filename == NULL)
+ return 1;
+ if(b->filename == NULL)
+ return -1;
+ return strcmp(a->filename, b->filename);
+}
+
+static int
+compare_mtime(struct fileinfo *a, struct fileinfo *b)
+{
+ if(a->filename == NULL)
+ return 1;
+ if(b->filename == NULL)
+ return -1;
+ return a->st.st_mtime - b->st.st_mtime;
+}
+
+static int
+compare_size(struct fileinfo *a, struct fileinfo *b)
+{
+ if(a->filename == NULL)
+ return 1;
+ if(b->filename == NULL)
+ return -1;
+ return a->st.st_size - b->st.st_size;
+}
+
+static void
+list_dir(FILE *out, const char *directory, int flags);
+
+static int
+log10(int num)
+{
+ int i = 1;
+ while(num > 10) {
+ i++;
+ num /= 10;
+ }
+ return i;
+}
+
+/*
+ * Operate as lstat but fake up entries for AFS mount points so we don't
+ * have to fetch them.
+ */
+
+static int
+lstat_file (const char *file, struct stat *sb)
+{
+#ifdef KRB4
+ if (k_hasafs()
+ && strcmp(file, ".")
+ && strcmp(file, ".."))
+ {
+ struct ViceIoctl a_params;
+ char *last;
+ char *path_bkp;
+ static ino_t ino_counter = 0, ino_last = 0;
+ int ret;
+ const int maxsize = 2048;
+
+ path_bkp = strdup (file);
+ if (path_bkp == NULL)
+ return -1;
+
+ a_params.out = malloc (maxsize);
+ if (a_params.out == NULL) {
+ free (path_bkp);
+ return -1;
+ }
+
+ /* If path contains more than the filename alone - split it */
+
+ last = strrchr (path_bkp, '/');
+ if (last != NULL) {
+ *last = '\0';
+ a_params.in = last + 1;
+ } else
+ a_params.in = (char *)file;
+
+ a_params.in_size = strlen (a_params.in) + 1;
+ a_params.out_size = maxsize;
+
+ ret = k_pioctl (last ? path_bkp : "." ,
+ VIOC_AFS_STAT_MT_PT, &a_params, 0);
+ free (a_params.out);
+ if (ret < 0) {
+ free (path_bkp);
+
+ if (errno != EINVAL)
+ return ret;
+ else
+ /* if we get EINVAL this is probably not a mountpoint */
+ return lstat (file, sb);
+ }
+
+ /*
+ * wow this was a mountpoint, lets cook the struct stat
+ * use . as a prototype
+ */
+
+ ret = lstat (path_bkp, sb);
+ free (path_bkp);
+ if (ret < 0)
+ return ret;
+
+ if (ino_last == sb->st_ino)
+ ino_counter++;
+ else {
+ ino_last = sb->st_ino;
+ ino_counter = 0;
+ }
+ sb->st_ino += ino_counter;
+ sb->st_nlink = 3;
+
+ return 0;
+ }
+#endif /* KRB4 */
+ return lstat (file, sb);
+}
+
+static void
+list_files(FILE *out, const char **files, int n_files, int flags)
+{
+ struct fileinfo *fi;
+ int i;
+
+ fi = calloc(n_files, sizeof(*fi));
+ if (fi == NULL) {
+ sec_fprintf2(out, "ouf of memory\r\n");
+ return;
+ }
+ for(i = 0; i < n_files; i++) {
+ if(lstat_file(files[i], &fi[i].st) < 0) {
+ sec_fprintf2(out, "%s: %s\r\n", files[i], strerror(errno));
+ fi[i].filename = NULL;
+ } else {
+ if((flags & LS_DIRS) == 0 && S_ISDIR(fi[i].st.st_mode)) {
+ if(n_files > 1)
+ sec_fprintf2(out, "%s:\r\n", files[i]);
+ list_dir(out, files[i], flags);
+ } else {
+ make_fileinfo(files[i], &fi[i], flags);
+ }
+ }
+ }
+ switch(SORT_MODE(flags)) {
+ case LS_SORT_NAME:
+ qsort(fi, n_files, sizeof(*fi),
+ (int (*)(const void*, const void*))compare_filename);
+ break;
+ case LS_SORT_MTIME:
+ qsort(fi, n_files, sizeof(*fi),
+ (int (*)(const void*, const void*))compare_mtime);
+ break;
+ case LS_SORT_SIZE:
+ qsort(fi, n_files, sizeof(*fi),
+ (int (*)(const void*, const void*))compare_size);
+ break;
+ }
+ {
+ int max_inode = 0;
+ int max_bsize = 0;
+ int max_n_link = 0;
+ int max_user = 0;
+ int max_group = 0;
+ int max_size = 0;
+ int max_major = 0;
+ int max_minor = 0;
+ int max_date = 0;
+ for(i = 0; i < n_files; i++) {
+ if(fi[i].filename == NULL)
+ continue;
+ if(fi[i].inode > max_inode)
+ max_inode = fi[i].inode;
+ if(fi[i].bsize > max_bsize)
+ max_bsize = fi[i].bsize;
+ if(fi[i].n_link > max_n_link)
+ max_n_link = fi[i].n_link;
+ if(strlen(fi[i].user) > max_user)
+ max_user = strlen(fi[i].user);
+ if(strlen(fi[i].group) > max_group)
+ max_group = strlen(fi[i].group);
+ if(fi[i].major != NULL && strlen(fi[i].major) > max_major)
+ max_major = strlen(fi[i].major);
+ if(fi[i].minor != NULL && strlen(fi[i].minor) > max_minor)
+ max_minor = strlen(fi[i].minor);
+ if(fi[i].size != NULL && strlen(fi[i].size) > max_size)
+ max_size = strlen(fi[i].size);
+ if(strlen(fi[i].date) > max_date)
+ max_date = strlen(fi[i].date);
+ }
+ if(max_size < max_major + max_minor + 2)
+ max_size = max_major + max_minor + 2;
+ else if(max_size - max_minor - 2 > max_major)
+ max_major = max_size - max_minor - 2;
+ max_inode = log10(max_inode);
+ max_bsize = log10(max_bsize);
+ max_n_link = log10(max_n_link);
+
+ if(flags & LS_SORT_REVERSE)
+ for(i = n_files - 1; i >= 0; i--)
+ print_file(out,
+ flags,
+ &fi[i],
+ max_inode,
+ max_bsize,
+ max_n_link,
+ max_user,
+ max_group,
+ max_size,
+ max_major,
+ max_minor,
+ max_date);
+ else
+ for(i = 0; i < n_files; i++)
+ print_file(out,
+ flags,
+ &fi[i],
+ max_inode,
+ max_bsize,
+ max_n_link,
+ max_user,
+ max_group,
+ max_size,
+ max_major,
+ max_minor,
+ max_date);
+ for(i = 0; i < n_files; i++)
+ free_fileinfo(&fi[i]);
+ free(fi);
+ }
+}
+
+static void
+free_files (char **files, int n)
+{
+ int i;
+
+ for (i = 0; i < n; ++i)
+ free (files[i]);
+ free (files);
+}
+
+static void
+list_dir(FILE *out, const char *directory, int flags)
+{
+ DIR *d = opendir(directory);
+ struct dirent *ent;
+ char **files = NULL;
+ int n_files = 0;
+
+ if(d == NULL) {
+ sec_fprintf2(out, "%s: %s\r\n", directory, strerror(errno));
+ return;
+ }
+ while((ent = readdir(d)) != NULL) {
+ void *tmp;
+
+ if(ent->d_name[0] == '.') {
+ if (flags & LS_IGNORE_DOT)
+ continue;
+ if (ent->d_name[1] == 0) /* Ignore . */
+ continue;
+ if (ent->d_name[1] == '.' && ent->d_name[2] == 0) /* Ignore .. */
+ continue;
+ }
+ tmp = realloc(files, (n_files + 1) * sizeof(*files));
+ if (tmp == NULL) {
+ sec_fprintf2(out, "%s: out of memory\r\n", directory);
+ free_files (files, n_files);
+ closedir (d);
+ return;
+ }
+ files = tmp;
+ asprintf(&files[n_files], "%s/%s", directory, ent->d_name);
+ if (files[n_files] == NULL) {
+ sec_fprintf2(out, "%s: out of memory\r\n", directory);
+ free_files (files, n_files);
+ closedir (d);
+ return;
+ }
+ ++n_files;
+ }
+ closedir(d);
+ list_files(out, (const char**)files, n_files, flags | LS_DIRS);
+}
+
+void
+builtin_ls(FILE *out, const char *file)
+{
+ int flags = LS_SORT_NAME;
+
+ if(*file == '-') {
+ const char *p;
+ for(p = file + 1; *p; p++) {
+ switch(*p) {
+ case 'a':
+ case 'A':
+ flags &= ~LS_IGNORE_DOT;
+ break;
+ case 'C':
+ break;
+ case 'd':
+ flags |= LS_DIRS;
+ break;
+ case 'f':
+ flags = (flags & ~LS_SORT_MODE);
+ break;
+ case 'i':
+ flags |= flags | LS_INODE;
+ break;
+ case 'l':
+ break;
+ case 't':
+ flags = (flags & ~LS_SORT_MODE) | LS_SORT_MTIME;
+ break;
+ case 's':
+ flags |= LS_SIZE;
+ break;
+ case 'S':
+ flags = (flags & ~LS_SORT_MODE) | LS_SORT_SIZE;
+ break;
+ case 'r':
+ flags |= LS_SORT_REVERSE;
+ break;
+ }
+ }
+ file = ".";
+ }
+ list_files(out, &file, 1, flags);
+ sec_fflush(out);
+}
diff --git a/crypto/heimdal/appl/ftp/ftpd/pathnames.h b/crypto/heimdal/appl/ftp/ftpd/pathnames.h
new file mode 100644
index 000000000000..ff2041bb6c79
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/pathnames.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/4/93
+ */
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#ifndef _PATH_DEVNULL
+#define _PATH_DEVNULL "/dev/null"
+#endif
+
+#ifndef _PATH_NOLOGIN
+#define _PATH_NOLOGIN "/etc/nologin"
+#endif
+
+#ifndef _PATH_BSHELL
+#define _PATH_BSHELL "/bin/sh"
+#endif
+
+#define _PATH_FTPUSERS "/etc/ftpusers"
+#define _PATH_FTPCHROOT "/etc/ftpchroot"
+#define _PATH_FTPWELCOME "/etc/ftpwelcome"
+#define _PATH_FTPLOGINMESG "/etc/motd"
+
+#define _PATH_ISSUE "/etc/issue"
+#define _PATH_ISSUE_NET "/etc/issue.net"
diff --git a/crypto/heimdal/appl/ftp/ftpd/popen.c b/crypto/heimdal/appl/ftp/ftpd/popen.c
new file mode 100644
index 000000000000..5f36813a195b
--- /dev/null
+++ b/crypto/heimdal/appl/ftp/ftpd/popen.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 1988, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software written by Ken Arnold and
+ * published in UNIX Review, Vol. 6, No. 8.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: popen.c,v 1.19 1999/09/16 20:38:45 assar Exp $");
+#endif
+
+#include <sys/types.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <glob.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "extern.h"
+
+#include <roken.h>
+
+/*
+ * Special version of popen which avoids call to shell. This ensures
+ * no one may create a pipe to a hidden program as a side effect of a
+ * list or dir command.
+ */
+static int *pids;
+static int fds;
+
+extern int dochroot;
+
+/* return path prepended with ~ftp if that file exists, otherwise
+ * return path unchanged
+ */
+
+const char *
+ftp_rooted(const char *path)
+{
+ static char home[MaxPathLen] = "";
+ static char newpath[MaxPathLen];
+ struct passwd *pwd;
+
+ if(!home[0])
+ if((pwd = k_getpwnam("ftp")))
+ strlcpy(home, pwd->pw_dir, sizeof(home));
+ snprintf(newpath, sizeof(newpath), "%s/%s", home, path);
+ if(access(newpath, X_OK))
+ strlcpy(newpath, path, sizeof(newpath));
+ return newpath;
+}
+
+
+FILE *
+ftpd_popen(char *program, char *type, int do_stderr, int no_glob)
+{
+ char *cp;
+ FILE *iop;
+ int argc, gargc, pdes[2], pid;
+ char **pop, *argv[100], *gargv[1000];
+ char *foo;
+
+ if (strcmp(type, "r") && strcmp(type, "w"))
+ return (NULL);
+
+ if (!pids) {
+
+ /* This function is ugly and should be rewritten, in
+ * modern unices there is no such thing as a maximum
+ * filedescriptor.
+ */
+
+ fds = getdtablesize();
+ pids = (int*)calloc(fds, sizeof(int));
+ if(!pids)
+ return NULL;
+ }
+ if (pipe(pdes) < 0)
+ return (NULL);
+
+ /* break up string into pieces */
+ foo = NULL;
+ for (argc = 0, cp = program;; cp = NULL) {
+ if (!(argv[argc++] = strtok_r(cp, " \t\n", &foo)))
+ break;
+ }
+
+ gargv[0] = (char*)ftp_rooted(argv[0]);
+ /* glob each piece */
+ for (gargc = argc = 1; argv[argc]; argc++) {
+ glob_t gl;
+ int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+
+ memset(&gl, 0, sizeof(gl));
+ if (no_glob || glob(argv[argc], flags, NULL, &gl))
+ gargv[gargc++] = strdup(argv[argc]);
+ else
+ for (pop = gl.gl_pathv; *pop; pop++)
+ gargv[gargc++] = strdup(*pop);
+ globfree(&gl);
+ }
+ gargv[gargc] = NULL;
+
+ iop = NULL;
+ switch(pid = fork()) {
+ case -1: /* error */
+ close(pdes[0]);
+ close(pdes[1]);
+ goto pfree;
+ /* NOTREACHED */
+ case 0: /* child */
+ if (*type == 'r') {
+ if (pdes[1] != STDOUT_FILENO) {
+ dup2(pdes[1], STDOUT_FILENO);
+ close(pdes[1]);
+ }
+ if(do_stderr)
+ dup2(STDOUT_FILENO, STDERR_FILENO);
+ close(pdes[0]);
+ } else {
+ if (pdes[0] != STDIN_FILENO) {
+ dup2(pdes[0], STDIN_FILENO);
+ close(pdes[0]);
+ }
+ close(pdes[1]);
+ }
+ execv(gargv[0], gargv);
+ gargv[0] = argv[0];
+ execv(gargv[0], gargv);
+ _exit(1);
+ }
+ /* parent; assume fdopen can't fail... */
+ if (*type == 'r') {
+ iop = fdopen(pdes[0], type);
+ close(pdes[1]);
+ } else {
+ iop = fdopen(pdes[1], type);
+ close(pdes[0]);
+ }
+ pids[fileno(iop)] = pid;
+
+pfree:
+ for (argc = 1; gargv[argc] != NULL; argc++)
+ free(gargv[argc]);
+
+
+ return (iop);
+}
+
+int
+ftpd_pclose(FILE *iop)
+{
+ int fdes, status;
+ pid_t pid;
+ sigset_t sigset, osigset;
+
+ /*
+ * pclose returns -1 if stream is not associated with a
+ * `popened' command, or, if already `pclosed'.
+ */
+ if (pids == 0 || pids[fdes = fileno(iop)] == 0)
+ return (-1);
+ fclose(iop);
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGINT);
+ sigaddset(&sigset, SIGQUIT);
+ sigaddset(&sigset, SIGHUP);
+ sigprocmask(SIG_BLOCK, &sigset, &osigset);
+ while ((pid = waitpid(pids[fdes], &status, 0)) < 0 && errno == EINTR)
+ continue;
+ sigprocmask(SIG_SETMASK, &osigset, NULL);
+ pids[fdes] = 0;
+ if (pid < 0)
+ return (pid);
+ if (WIFEXITED(status))
+ return (WEXITSTATUS(status));
+ return (1);
+}
diff --git a/crypto/heimdal/appl/kauth/ChangeLog b/crypto/heimdal/appl/kauth/ChangeLog
new file mode 100644
index 000000000000..ac0491fb1766
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/ChangeLog
@@ -0,0 +1,39 @@
+1999-12-06 Assar Westerlund <assar@sics.se>
+
+ * rkinit.c (doit_host): NAT work-around
+ * kauthd.c (doit): type correctness
+
+1999-12-05 Assar Westerlund <assar@sics.se>
+
+ * kauthd.c: use getnameinfo instead of inaddr2str and inet_ntoa
+
+1999-08-31 Johan Danielsson <joda@pdc.kth.se>
+
+ * kauth.c: cleanup usage string; handle `kauth -h' gracefully
+ (print usage); add `-a' flag to get the ticket address (useful for
+ firewall configurations)
+
+Thu Apr 15 15:05:33 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * kauth.c: add `-v'
+
+Thu Mar 18 11:17:14 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: include Makefile.am.common
+
+Sun Nov 22 10:30:47 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (WFLAGS): set
+
+Tue May 26 17:41:47 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kauth.c: use krb_enable_debug
+
+Fri May 1 07:15:18 1998 Assar Westerlund <assar@sics.se>
+
+ * rkinit.c: unifdef -DHAVE_H_ERRNO
+
+Thu Mar 19 16:07:18 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kauth.c: Check for negative return value from krb_afslog().
+
diff --git a/crypto/heimdal/appl/kauth/Makefile.am b/crypto/heimdal/appl/kauth/Makefile.am
new file mode 100644
index 000000000000..a5bf0fdacac6
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/Makefile.am
@@ -0,0 +1,42 @@
+# $Id: Makefile.am,v 1.7 1999/04/09 18:22:45 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+bin_PROGRAMS = kauth
+bin_SCRIPTS = ksrvtgt
+libexec_PROGRAMS = kauthd
+
+EXTRA_DIST = zrefresh ksrvtgt.in
+
+kauth_SOURCES = \
+ kauth.c \
+ kauth.h \
+ rkinit.c \
+ marshall.c \
+ encdata.c
+
+kauthd_SOURCES = \
+ kauthd.c \
+ kauth.h \
+ marshall.c \
+ encdata.c
+
+ksrvtgt: ksrvtgt.in
+ sed -e "s!%bindir%!$(bindir)!" $(srcdir)/ksrvtgt.in > $@
+ chmod +x $@
+
+install-exec-local:
+ if test -f $(bindir)/zrefresh -o -r $(bindir)/zrefresh; then \
+ true; \
+ else \
+ $(INSTALL_PROGRAM) $(srcdir)/zrefresh $(bindir)/`echo zrefresh | sed '$(transform)'`; \
+ fi
+
+LDADD = \
+ $(LIB_kafs) \
+ $(LIB_krb5) \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(LIB_roken)
diff --git a/crypto/heimdal/appl/kauth/Makefile.in b/crypto/heimdal/appl/kauth/Makefile.in
new file mode 100644
index 000000000000..f9c005f68f34
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/Makefile.in
@@ -0,0 +1,739 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.7 1999/04/09 18:22:45 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+bin_PROGRAMS = kauth
+bin_SCRIPTS = ksrvtgt
+libexec_PROGRAMS = kauthd
+
+EXTRA_DIST = zrefresh ksrvtgt.in
+
+kauth_SOURCES = kauth.c kauth.h rkinit.c marshall.c encdata.c
+
+
+kauthd_SOURCES = kauthd.c kauth.h marshall.c encdata.c
+
+
+LDADD = $(LIB_kafs) $(LIB_krb5) $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(LIB_roken)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = kauth$(EXEEXT)
+libexec_PROGRAMS = kauthd$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+kauth_OBJECTS = kauth.$(OBJEXT) rkinit.$(OBJEXT) marshall.$(OBJEXT) \
+encdata.$(OBJEXT)
+kauth_LDADD = $(LDADD)
+@KRB4_TRUE@@KRB5_FALSE@kauth_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_TRUE@kauth_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_FALSE@kauth_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_TRUE@@KRB5_TRUE@kauth_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+kauth_LDFLAGS =
+kauthd_OBJECTS = kauthd.$(OBJEXT) marshall.$(OBJEXT) encdata.$(OBJEXT)
+kauthd_LDADD = $(LDADD)
+@KRB4_TRUE@@KRB5_FALSE@kauthd_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_TRUE@kauthd_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_FALSE@kauthd_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_TRUE@@KRB5_TRUE@kauthd_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+kauthd_LDFLAGS =
+SCRIPTS = $(bin_SCRIPTS)
+
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(kauth_SOURCES) $(kauthd_SOURCES)
+OBJECTS = $(kauth_OBJECTS) $(kauthd_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/kauth/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-libexecPROGRAMS:
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+
+distclean-libexecPROGRAMS:
+
+maintainer-clean-libexecPROGRAMS:
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+kauth$(EXEEXT): $(kauth_OBJECTS) $(kauth_DEPENDENCIES)
+ @rm -f kauth$(EXEEXT)
+ $(LINK) $(kauth_LDFLAGS) $(kauth_OBJECTS) $(kauth_LDADD) $(LIBS)
+
+kauthd$(EXEEXT): $(kauthd_OBJECTS) $(kauthd_DEPENDENCIES)
+ @rm -f kauthd$(EXEEXT)
+ $(LINK) $(kauthd_LDFLAGS) $(kauthd_OBJECTS) $(kauthd_LDADD) $(LIBS)
+
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ else if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ else :; fi; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_SCRIPTS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/kauth
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS install-libexecPROGRAMS \
+ install-binSCRIPTS install-exec-local
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS uninstall-libexecPROGRAMS \
+ uninstall-binSCRIPTS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(libexecdir) \
+ $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-libexecPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-libexecPROGRAMS clean-compile \
+ clean-libtool clean-tags clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-libexecPROGRAMS \
+ distclean-compile distclean-libtool distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-libexecPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-libexecPROGRAMS distclean-libexecPROGRAMS \
+clean-libexecPROGRAMS maintainer-clean-libexecPROGRAMS \
+uninstall-libexecPROGRAMS install-libexecPROGRAMS mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool uninstall-binSCRIPTS install-binSCRIPTS tags \
+mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \
+distdir info-am info dvi-am dvi check-local check check-am \
+installcheck-am installcheck install-exec-local install-exec-am \
+install-exec install-data-local install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+ksrvtgt: ksrvtgt.in
+ sed -e "s!%bindir%!$(bindir)!" $(srcdir)/ksrvtgt.in > $@
+ chmod +x $@
+
+install-exec-local:
+ if test -f $(bindir)/zrefresh -o -r $(bindir)/zrefresh; then \
+ true; \
+ else \
+ $(INSTALL_PROGRAM) $(srcdir)/zrefresh $(bindir)/`echo zrefresh | sed '$(transform)'`; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/kauth/encdata.c b/crypto/heimdal/appl/kauth/encdata.c
new file mode 100644
index 000000000000..886f5490bad8
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/encdata.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kauth.h"
+
+RCSID("$Id: encdata.c,v 1.10 1999/12/02 16:58:31 joda Exp $");
+
+int
+write_encrypted (int fd, void *buf, size_t len, des_key_schedule schedule,
+ des_cblock *session, struct sockaddr_in *me,
+ struct sockaddr_in *him)
+{
+ void *outbuf;
+ int32_t outlen, l;
+ int i;
+ unsigned char tmp[4];
+
+ outbuf = malloc(len + 30);
+ if (outbuf == NULL)
+ return -1;
+ outlen = krb_mk_priv (buf, outbuf, len, schedule, session, me, him);
+ if (outlen < 0) {
+ free(outbuf);
+ return -1;
+ }
+ l = outlen;
+ for(i = 3; i >= 0; i--, l = l >> 8)
+ tmp[i] = l & 0xff;
+ if (krb_net_write (fd, tmp, 4) != 4 ||
+ krb_net_write (fd, outbuf, outlen) != outlen) {
+ free(outbuf);
+ return -1;
+ }
+
+ free(outbuf);
+ return 0;
+}
+
+
+int
+read_encrypted (int fd, void *buf, size_t len, void **ret,
+ des_key_schedule schedule, des_cblock *session,
+ struct sockaddr_in *him, struct sockaddr_in *me)
+{
+ int status;
+ int32_t l;
+ MSG_DAT msg;
+ unsigned char tmp[4];
+
+ l = krb_net_read (fd, tmp, 4);
+ if (l != 4)
+ return l;
+ l = (tmp[0] << 24) | (tmp[1] << 16) | (tmp[2] << 8) | tmp[3];
+ if (l > len)
+ return -1;
+ if (krb_net_read (fd, buf, l) != l)
+ return -1;
+ status = krb_rd_priv (buf, l, schedule, session, him, me, &msg);
+ if (status != RD_AP_OK) {
+ fprintf (stderr, "read_encrypted: %s\n",
+ krb_get_err_text(status));
+ return -1;
+ }
+ *ret = msg.app_data;
+ return msg.app_length;
+}
diff --git a/crypto/heimdal/appl/kauth/kauth.c b/crypto/heimdal/appl/kauth/kauth.c
new file mode 100644
index 000000000000..13448a040dda
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/kauth.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*
+ * Little program that reads an srvtab or password and
+ * creates a suitable ticketfile and associated AFS tokens.
+ *
+ * If an optional command is given the command is executed in a
+ * new PAG and when the command exits the tickets are destroyed.
+ */
+
+#include "kauth.h"
+
+RCSID("$Id: kauth.c,v 1.97 1999/12/02 16:58:31 joda Exp $");
+
+krb_principal princ;
+static char srvtab[MaxPathLen];
+static int lifetime = DEFAULT_TKT_LIFE;
+static char remote_tktfile[MaxPathLen];
+static char remoteuser[100];
+static char *cell = 0;
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "Usage:\n"
+ " %s [name]\n"
+ "or\n"
+ " %s [-ad] [-n name] [-r remoteuser] [-t remote ticketfile]\n"
+ " [-l lifetime (in minutes) ] [-f srvtab ] [-c AFS cell name ]\n"
+ " [-h hosts... [--]] [command ... ]\n\n",
+ __progname, __progname);
+ fprintf(stderr,
+ "A fully qualified name can be given: user[.instance][@realm]\n"
+ "Realm is converted to uppercase!\n");
+ exit(1);
+}
+
+#define EX_NOEXEC 126
+#define EX_NOTFOUND 127
+
+static int
+doexec(int argc, char **argv)
+{
+ int ret = simple_execvp(argv[0], argv);
+ if(ret == -2)
+ warn ("fork");
+ if(ret == -3)
+ warn("waitpid");
+ if(ret < 0)
+ return EX_NOEXEC;
+ if(ret == EX_NOEXEC || ret == EX_NOTFOUND)
+ warnx("Can't exec program ``%s''", argv[0]);
+
+ return ret;
+}
+
+static RETSIGTYPE
+renew(int sig)
+{
+ int code;
+
+ signal(SIGALRM, renew);
+
+ code = krb_get_svc_in_tkt(princ.name, princ.instance, princ.realm,
+ KRB_TICKET_GRANTING_TICKET,
+ princ.realm, lifetime, srvtab);
+ if (code)
+ warnx ("%s", krb_get_err_text(code));
+ else if (k_hasafs())
+ {
+ if ((code = krb_afslog(cell, NULL)) != 0 && code != KDC_PR_UNKNOWN) {
+ warnx ("%s", krb_get_err_text(code));
+ }
+ }
+
+ alarm(krb_life_to_time(0, lifetime)/2 - 60);
+ SIGRETURN(0);
+}
+
+static int
+zrefresh(void)
+{
+ switch (fork()) {
+ case -1:
+ err (1, "Warning: Failed to fork zrefresh");
+ return -1;
+ case 0:
+ /* Child */
+ execlp("zrefresh", "zrefresh", 0);
+ execl(BINDIR "/zrefresh", "zrefresh", 0);
+ exit(1);
+ default:
+ /* Parent */
+ break;
+ }
+ return 0;
+}
+
+static int
+key_to_key(const char *user,
+ char *instance,
+ const char *realm,
+ const void *arg,
+ des_cblock *key)
+{
+ memcpy(key, arg, sizeof(des_cblock));
+ return 0;
+}
+
+static int
+get_ticket_address(krb_principal *princ, des_cblock *key)
+{
+ int code;
+ unsigned char flags;
+ krb_principal service;
+ u_int32_t addr;
+ struct in_addr addr2;
+ des_cblock session;
+ int life;
+ u_int32_t time_sec;
+ des_key_schedule schedule;
+ CREDENTIALS c;
+
+ code = get_ad_tkt(princ->name, princ->instance, princ->realm, 0);
+ if(code) {
+ warnx("get_ad_tkt: %s\n", krb_get_err_text(code));
+ return code;
+ }
+ code = krb_get_cred(princ->name, princ->instance, princ->realm, &c);
+ if(code) {
+ warnx("krb_get_cred: %s\n", krb_get_err_text(code));
+ return code;
+ }
+
+ des_set_key(key, schedule);
+ code = decomp_ticket(&c.ticket_st,
+ &flags,
+ princ->name,
+ princ->instance,
+ princ->realm,
+ &addr,
+ session,
+ &life,
+ &time_sec,
+ service.name,
+ service.instance,
+ key,
+ schedule);
+ if(code) {
+ warnx("decomp_ticket: %s\n", krb_get_err_text(code));
+ return code;
+ }
+ memset(&session, 0, sizeof(session));
+ memset(schedule, 0, sizeof(schedule));
+ addr2.s_addr = addr;
+ fprintf(stdout, "ticket address = %s\n", inet_ntoa(addr2));
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int code, more_args;
+ int ret;
+ int c;
+ char *file;
+ int pflag = 0;
+ int aflag = 0;
+ int version_flag = 0;
+ char passwd[100];
+ des_cblock key;
+ char **host;
+ int nhost;
+ char tf[MaxPathLen];
+
+ set_progname (argv[0]);
+
+ if ((file = getenv("KRBTKFILE")) == 0)
+ file = TKT_FILE;
+
+ memset(&princ, 0, sizeof(princ));
+ memset(srvtab, 0, sizeof(srvtab));
+ *remoteuser = '\0';
+ nhost = 0;
+ host = NULL;
+
+ /* Look for kerberos name */
+ if (argc > 1 &&
+ argv[1][0] != '-' &&
+ krb_parse_name(argv[1], &princ) == 0)
+ {
+ argc--; argv++;
+ strupr(princ.realm);
+ }
+
+ while ((c = getopt(argc, argv, "ar:t:f:hdl:n:c:v")) != -1)
+ switch (c) {
+ case 'a':
+ aflag++;
+ break;
+ case 'd':
+ krb_enable_debug();
+ _kafs_debug = 1;
+ aflag++;
+ break;
+ case 'f':
+ strlcpy(srvtab, optarg, sizeof(srvtab));
+ break;
+ case 't':
+ strlcpy(remote_tktfile, optarg, sizeof(remote_tktfile));
+ break;
+ case 'r':
+ strlcpy(remoteuser, optarg, sizeof(remoteuser));
+ break;
+ case 'l':
+ lifetime = atoi(optarg);
+ if (lifetime == -1)
+ lifetime = 255;
+ else if (lifetime < 5)
+ lifetime = 1;
+ else
+ lifetime = krb_time_to_life(0, lifetime*60);
+ if (lifetime > 255)
+ lifetime = 255;
+ break;
+ case 'n':
+ if ((code = krb_parse_name(optarg, &princ)) != 0) {
+ warnx ("%s", krb_get_err_text(code));
+ usage();
+ }
+ strupr(princ.realm);
+ pflag = 1;
+ break;
+ case 'c':
+ cell = optarg;
+ break;
+ case 'h':
+ host = argv + optind;
+ for(nhost = 0; optind < argc && *argv[optind] != '-'; ++optind)
+ ++nhost;
+ if(nhost == 0)
+ usage();
+ break;
+ case 'v':
+ version_flag++;
+ print_version(NULL);
+ break;
+ case '?':
+ default:
+ usage();
+ break;
+ }
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+ if (princ.name[0] == '\0' && krb_get_default_principal (princ.name,
+ princ.instance,
+ princ.realm) < 0)
+ errx (1, "Could not get default principal");
+
+ /* With root tickets assume remote user is root */
+ if (*remoteuser == '\0') {
+ if (strcmp(princ.instance, "root") == 0)
+ strlcpy(remoteuser, princ.instance, sizeof(remoteuser));
+ else
+ strlcpy(remoteuser, princ.name, sizeof(remoteuser));
+ }
+
+ more_args = argc - optind;
+
+ if (princ.realm[0] == '\0')
+ if (krb_get_lrealm(princ.realm, 1) != KSUCCESS)
+ strlcpy(princ.realm, KRB_REALM, REALM_SZ);
+
+ if (more_args) {
+ int f;
+
+ do{
+ snprintf(tf, sizeof(tf), "%s%u_%u", TKT_ROOT, (unsigned)getuid(),
+ (unsigned)(getpid()*time(0)));
+ f = open(tf, O_CREAT|O_EXCL|O_RDWR);
+ }while(f < 0);
+ close(f);
+ unlink(tf);
+ setenv("KRBTKFILE", tf, 1);
+ krb_set_tkt_string (tf);
+ }
+
+ if (srvtab[0])
+ {
+ signal(SIGALRM, renew);
+
+ code = read_service_key (princ.name, princ.instance, princ.realm, 0,
+ srvtab, (char *)&key);
+ if (code == KSUCCESS)
+ code = krb_get_in_tkt(princ.name, princ.instance, princ.realm,
+ KRB_TICKET_GRANTING_TICKET,
+ princ.realm, lifetime,
+ key_to_key, NULL, key);
+ alarm(krb_life_to_time(0, lifetime)/2 - 60);
+ }
+ else {
+ char prompt[128];
+
+ snprintf(prompt, sizeof(prompt), "%s's Password: ", krb_unparse_name(&princ));
+ if (des_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){
+ memset(passwd, 0, sizeof(passwd));
+ exit(1);
+ }
+ code = krb_get_pw_in_tkt2(princ.name, princ.instance, princ.realm,
+ KRB_TICKET_GRANTING_TICKET, princ.realm,
+ lifetime, passwd, &key);
+
+ memset(passwd, 0, sizeof(passwd));
+ }
+ if (code) {
+ memset (key, 0, sizeof(key));
+ errx (1, "%s", krb_get_err_text(code));
+ }
+
+ if(aflag)
+ get_ticket_address(&princ, &key);
+
+ if (k_hasafs()) {
+ if (more_args)
+ k_setpag();
+ if ((code = krb_afslog(cell, NULL)) != 0 && code != KDC_PR_UNKNOWN) {
+ if(code > 0)
+ warnx ("%s", krb_get_err_text(code));
+ else
+ warnx ("failed to store AFS token");
+ }
+ }
+
+ for(ret = 0; nhost-- > 0; host++)
+ ret += rkinit(&princ, lifetime, remoteuser, remote_tktfile, &key, *host);
+
+ if (ret)
+ return ret;
+
+ if (more_args) {
+ ret = doexec(more_args, &argv[optind]);
+ dest_tkt();
+ if (k_hasafs())
+ k_unlog();
+ }
+ else
+ zrefresh();
+
+ return ret;
+}
diff --git a/crypto/heimdal/appl/kauth/kauth.h b/crypto/heimdal/appl/kauth/kauth.h
new file mode 100644
index 000000000000..32243c7d4333
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/kauth.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: kauth.h,v 1.21 1999/12/02 16:58:31 joda Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <signal.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef SOCKS
+#include <socks.h>
+/* This doesn't belong here. */
+struct tm *localtime(const time_t *);
+struct hostent *gethostbyname(const char *);
+#endif
+
+#include <err.h>
+
+#include <krb.h>
+#include <kafs.h>
+
+#include <roken.h>
+
+#define KAUTH_PORT 2120
+
+#define KAUTH_VERSION "RKINIT.0"
+
+int rkinit (krb_principal*, int, char*, char*, des_cblock*, char*);
+
+int write_encrypted (int, void*, size_t, des_key_schedule,
+ des_cblock*, struct sockaddr_in*, struct sockaddr_in*);
+
+int read_encrypted (int, void*, size_t, void **, des_key_schedule,
+ des_cblock*, struct sockaddr_in*, struct sockaddr_in*);
+
+int pack_args (char *, size_t, krb_principal*, int, const char*, const char*);
+
+int unpack_args (const char*, krb_principal*, int*, char*, char*);
diff --git a/crypto/heimdal/appl/kauth/kauthd.c b/crypto/heimdal/appl/kauth/kauthd.c
new file mode 100644
index 000000000000..520730a3171d
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/kauthd.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kauth.h"
+
+RCSID("$Id: kauthd.c,v 1.27 1999/12/06 16:46:05 assar Exp $");
+
+krb_principal princ;
+static char locuser[SNAME_SZ];
+static int lifetime;
+static char tktfile[MaxPathLen];
+
+struct remote_args {
+ int sock;
+ des_key_schedule *schedule;
+ des_cblock *session;
+ struct sockaddr_in *me, *her;
+};
+
+static int
+decrypt_remote_tkt (const char *user,
+ const char *inst,
+ const char *realm,
+ const void *varg,
+ key_proc_t key_proc,
+ KTEXT *cipp)
+{
+ char buf[BUFSIZ];
+ void *ptr;
+ int len;
+ KTEXT cip = *cipp;
+ struct remote_args *args = (struct remote_args *)varg;
+
+ write_encrypted (args->sock, cip->dat, cip->length,
+ *args->schedule, args->session, args->me,
+ args->her);
+ len = read_encrypted (args->sock, buf, sizeof(buf), &ptr, *args->schedule,
+ args->session, args->her, args->me);
+ memcpy(cip->dat, ptr, cip->length);
+
+ return 0;
+}
+
+static int
+doit(int sock)
+{
+ int status;
+ KTEXT_ST ticket;
+ AUTH_DAT auth;
+ char instance[INST_SZ];
+ des_key_schedule schedule;
+ struct sockaddr_in thisaddr, thataddr;
+ int addrlen;
+ int len;
+ char buf[BUFSIZ];
+ void *data;
+ struct passwd *passwd;
+ char version[KRB_SENDAUTH_VLEN + 1];
+ char remotehost[MaxHostNameLen];
+
+ addrlen = sizeof(thisaddr);
+ if (getsockname (sock, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
+ addrlen != sizeof(thisaddr)) {
+ return 1;
+ }
+ addrlen = sizeof(thataddr);
+ if (getpeername (sock, (struct sockaddr *)&thataddr, &addrlen) < 0 ||
+ addrlen != sizeof(thataddr)) {
+ return 1;
+ }
+
+ getnameinfo_verified ((struct sockaddr *)&thataddr, sizeof(thataddr),
+ remotehost, sizeof(remotehost),
+ NULL, 0, 0);
+
+ k_getsockinst (sock, instance, sizeof(instance));
+ status = krb_recvauth (KOPT_DO_MUTUAL, sock, &ticket, "rcmd", instance,
+ &thataddr, &thisaddr, &auth, "", schedule,
+ version);
+ if (status != KSUCCESS ||
+ strncmp(version, KAUTH_VERSION, KRB_SENDAUTH_VLEN) != 0) {
+ return 1;
+ }
+ len = read_encrypted (sock, buf, sizeof(buf), &data, schedule,
+ &auth.session, &thataddr, &thisaddr);
+ if (len < 0) {
+ write_encrypted (sock, "read_enc failed",
+ sizeof("read_enc failed") - 1, schedule,
+ &auth.session, &thisaddr, &thataddr);
+ return 1;
+ }
+ if (unpack_args(data, &princ, &lifetime, locuser,
+ tktfile)) {
+ write_encrypted (sock, "unpack_args failed",
+ sizeof("unpack_args failed") - 1, schedule,
+ &auth.session, &thisaddr, &thataddr);
+ return 1;
+ }
+
+ if( kuserok(&auth, locuser) != 0) {
+ snprintf(buf, sizeof(buf), "%s cannot get tickets for %s",
+ locuser, krb_unparse_name(&princ));
+ syslog (LOG_ERR, buf);
+ write_encrypted (sock, buf, strlen(buf), schedule,
+ &auth.session, &thisaddr, &thataddr);
+ return 1;
+ }
+ passwd = k_getpwnam (locuser);
+ if (passwd == NULL) {
+ snprintf (buf, sizeof(buf), "No user '%s'", locuser);
+ syslog (LOG_ERR, buf);
+ write_encrypted (sock, buf, strlen(buf), schedule,
+ &auth.session, &thisaddr, &thataddr);
+ return 1;
+ }
+ if (setgid (passwd->pw_gid) ||
+ initgroups(passwd->pw_name, passwd->pw_gid) ||
+ setuid(passwd->pw_uid)) {
+ snprintf (buf, sizeof(buf), "Could not change user");
+ syslog (LOG_ERR, buf);
+ write_encrypted (sock, buf, strlen(buf), schedule,
+ &auth.session, &thisaddr, &thataddr);
+ return 1;
+ }
+ write_encrypted (sock, "ok", sizeof("ok") - 1, schedule,
+ &auth.session, &thisaddr, &thataddr);
+
+ if (*tktfile == 0)
+ snprintf(tktfile, sizeof(tktfile), "%s%u", TKT_ROOT, (unsigned)getuid());
+ krb_set_tkt_string (tktfile);
+
+ {
+ struct remote_args arg;
+
+ arg.sock = sock;
+ arg.schedule = &schedule;
+ arg.session = &auth.session;
+ arg.me = &thisaddr;
+ arg.her = &thataddr;
+
+ status = krb_get_in_tkt (princ.name, princ.instance, princ.realm,
+ KRB_TICKET_GRANTING_TICKET,
+ princ.realm,
+ lifetime, NULL, decrypt_remote_tkt, &arg);
+ }
+ if (status == KSUCCESS) {
+ char remoteaddr[INET6_ADDRSTRLEN];
+
+ getnameinfo ((struct sockaddr *)&thataddr, sizeof(thataddr),
+ remoteaddr, sizeof(remoteaddr),
+ NULL, 0, NI_NUMERICHOST);
+
+ syslog (LOG_INFO, "from %s(%s): %s -> %s",
+ remotehost, remoteaddr,
+ locuser,
+ krb_unparse_name (&princ));
+ write_encrypted (sock, "ok", sizeof("ok") - 1, schedule,
+ &auth.session, &thisaddr, &thataddr);
+ return 0;
+ } else {
+ snprintf (buf, sizeof(buf), "TGT failed: %s", krb_get_err_text(status));
+ syslog (LOG_NOTICE, buf);
+ write_encrypted (sock, buf, strlen(buf), schedule,
+ &auth.session, &thisaddr, &thataddr);
+ return 1;
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ openlog ("kauthd", LOG_ODELAY, LOG_AUTH);
+
+ if(argc > 1 && strcmp(argv[1], "-i") == 0)
+ mini_inetd (k_getportbyname("kauth", "tcp", htons(KAUTH_PORT)));
+ return doit(STDIN_FILENO);
+}
diff --git a/crypto/heimdal/appl/kauth/ksrvtgt.in b/crypto/heimdal/appl/kauth/ksrvtgt.in
new file mode 100755
index 000000000000..c2f33bb22fb0
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/ksrvtgt.in
@@ -0,0 +1,14 @@
+#! /bin/sh
+# $Id: ksrvtgt.in,v 1.3 1997/09/13 03:39:03 joda Exp $
+
+usage="Usage: `basename $0` name instance [[realm] srvtab]"
+
+if [ $# -lt 2 -o $# -gt 4 ]; then
+ echo "$usage"
+ exit 1
+fi
+
+srvtab="${4-${3-/etc/srvtab}}"
+realm="${4+@$3}"
+
+%bindir%/kauth -n "$1.$2$realm" -l 5 -f "$srvtab"
diff --git a/crypto/heimdal/appl/kauth/marshall.c b/crypto/heimdal/appl/kauth/marshall.c
new file mode 100644
index 000000000000..e37b8c969c81
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/marshall.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kauth.h"
+
+RCSID("$Id: marshall.c,v 1.10 1999/12/02 16:58:31 joda Exp $");
+
+int
+pack_args (char *buf,
+ size_t sz,
+ krb_principal *pr,
+ int lifetime,
+ const char *locuser,
+ const char *tktfile)
+{
+ char *p = buf;
+ int len;
+
+ p = buf;
+
+ len = strlen(pr->name);
+ if (len >= sz)
+ return -1;
+ memcpy (p, pr->name, len + 1);
+ p += len + 1;
+ sz -= len + 1;
+
+ len = strlen(pr->instance);
+ if (len >= sz)
+ return -1;
+ memcpy (p, pr->instance, len + 1);
+ p += len + 1;
+ sz -= len + 1;
+
+ len = strlen(pr->realm);
+ if (len >= sz)
+ return -1;
+ memcpy(p, pr->realm, len + 1);
+ p += len + 1;
+ sz -= len + 1;
+
+ if (sz < 1)
+ return -1;
+ *p++ = (unsigned char)lifetime;
+
+ len = strlen(locuser);
+ if (len >= sz)
+ return -1;
+ memcpy (p, locuser, len + 1);
+ p += len + 1;
+ sz -= len + 1;
+
+ len = strlen(tktfile);
+ if (len >= sz)
+ return -1;
+ memcpy (p, tktfile, len + 1);
+ p += len + 1;
+ sz -= len + 1;
+
+ return p - buf;
+}
+
+int
+unpack_args (const char *buf, krb_principal *pr, int *lifetime,
+ char *locuser, char *tktfile)
+{
+ int len;
+
+ len = strlen(buf);
+ if (len >= SNAME_SZ)
+ return -1;
+ strlcpy (pr->name, buf, ANAME_SZ);
+ buf += len + 1;
+ len = strlen (buf);
+ if (len >= INST_SZ)
+ return -1;
+ strlcpy (pr->instance, buf, INST_SZ);
+ buf += len + 1;
+ len = strlen (buf);
+ if (len >= REALM_SZ)
+ return -1;
+ strlcpy (pr->realm, buf, REALM_SZ);
+ buf += len + 1;
+ *lifetime = (unsigned char)*buf++;
+ len = strlen(buf);
+ if (len >= SNAME_SZ)
+ return -1;
+ strlcpy (locuser, buf, SNAME_SZ);
+ buf += len + 1;
+ len = strlen(buf);
+ if (len >= MaxPathLen)
+ return -1;
+ strlcpy (tktfile, buf, MaxPathLen);
+ buf += len + 1;
+ return 0;
+}
diff --git a/crypto/heimdal/appl/kauth/rkinit.c b/crypto/heimdal/appl/kauth/rkinit.c
new file mode 100644
index 000000000000..d4b07c6c842d
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/rkinit.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kauth.h"
+
+RCSID("$Id: rkinit.c,v 1.23 1999/12/06 17:07:20 assar Exp $");
+
+static struct in_addr *
+getalladdrs (char *hostname, unsigned *count)
+{
+ struct hostent *hostent;
+ struct in_addr **h;
+ struct in_addr *addr;
+ unsigned naddr;
+ unsigned maxaddr;
+
+ hostent = gethostbyname (hostname);
+ if (hostent == NULL) {
+ warnx ("gethostbyname '%s' failed: %s\n",
+ hostname,
+ hstrerror(h_errno));
+ return NULL;
+ }
+ maxaddr = 1;
+ naddr = 0;
+ addr = malloc(sizeof(*addr) * maxaddr);
+ if (addr == NULL) {
+ warnx ("out of memory");
+ return NULL;
+ }
+ for (h = (struct in_addr **)(hostent->h_addr_list);
+ *h != NULL;
+ h++) {
+ if (naddr >= maxaddr) {
+ maxaddr *= 2;
+ addr = realloc (addr, sizeof(*addr) * maxaddr);
+ if (addr == NULL) {
+ warnx ("out of memory");
+ return NULL;
+ }
+ }
+ addr[naddr++] = **h;
+ }
+ addr = realloc (addr, sizeof(*addr) * naddr);
+ if (addr == NULL) {
+ warnx ("out of memory");
+ return NULL;
+ }
+ *count = naddr;
+ return addr;
+}
+
+static int
+doit_host (krb_principal *princ, int lifetime, char *locuser,
+ char *tktfile, des_cblock *key, int s, char *hostname)
+{
+ char buf[BUFSIZ];
+ int inlen;
+ KTEXT_ST text;
+ CREDENTIALS cred;
+ MSG_DAT msg;
+ int status;
+ des_key_schedule schedule;
+ struct sockaddr_in thisaddr, thataddr;
+ int addrlen;
+ void *ret;
+
+ addrlen = sizeof(thisaddr);
+ if (getsockname (s, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
+ addrlen != sizeof(thisaddr)) {
+ warn ("getsockname(%s)", hostname);
+ return 1;
+ }
+ addrlen = sizeof(thataddr);
+ if (getpeername (s, (struct sockaddr *)&thataddr, &addrlen) < 0 ||
+ addrlen != sizeof(thataddr)) {
+ warn ("getpeername(%s)", hostname);
+ return 1;
+ }
+
+ if (krb_get_config_bool("nat_in_use")) {
+ struct in_addr natAddr;
+
+ if (krb_get_our_ip_for_realm(krb_realmofhost(hostname),
+ &natAddr) == KSUCCESS
+ || krb_get_our_ip_for_realm (NULL, &natAddr) == KSUCCESS)
+ thisaddr.sin_addr = natAddr;
+ }
+
+ status = krb_sendauth (KOPT_DO_MUTUAL, s, &text, "rcmd",
+ hostname, krb_realmofhost (hostname),
+ getpid(), &msg, &cred, schedule,
+ &thisaddr, &thataddr, KAUTH_VERSION);
+ if (status != KSUCCESS) {
+ warnx ("%s: %s\n", hostname, krb_get_err_text(status));
+ return 1;
+ }
+ inlen = pack_args (buf, sizeof(buf),
+ princ, lifetime, locuser, tktfile);
+ if (inlen < 0) {
+ warn ("cannot marshall arguments to %s", hostname);
+ return 1;
+ }
+
+ if (write_encrypted(s, buf, inlen, schedule, &cred.session,
+ &thisaddr, &thataddr) < 0) {
+ warn ("write to %s", hostname);
+ return 1;
+ }
+
+ inlen = read_encrypted (s, buf, sizeof(buf), &ret, schedule,
+ &cred.session, &thataddr, &thisaddr);
+ if (inlen < 0) {
+ warn ("read from %s failed", hostname);
+ return 1;
+ }
+
+ if (strncmp(ret, "ok", inlen) != 0) {
+ warnx ("error from %s: %.*s\n",
+ hostname, inlen, (char *)ret);
+ return 1;
+ }
+
+ inlen = read_encrypted (s, buf, sizeof(buf), &ret, schedule,
+ &cred.session, &thataddr, &thisaddr);
+ if (inlen < 0) {
+ warn ("read from %s", hostname);
+ return 1;
+ }
+
+ {
+ des_key_schedule key_s;
+
+ des_key_sched(key, key_s);
+ des_pcbc_encrypt(ret, ret, inlen, key_s, key, DES_DECRYPT);
+ memset(key_s, 0, sizeof(key_s));
+ }
+ write_encrypted (s, ret, inlen, schedule, &cred.session,
+ &thisaddr, &thataddr);
+
+ inlen = read_encrypted (s, buf, sizeof(buf), &ret, schedule,
+ &cred.session, &thataddr, &thisaddr);
+ if (inlen < 0) {
+ warn ("read from %s", hostname);
+ return 1;
+ }
+
+ if (strncmp(ret, "ok", inlen) != 0) {
+ warnx ("error from %s: %.*s\n",
+ hostname, inlen, (char *)ret);
+ return 1;
+ }
+ return 0;
+}
+
+int
+rkinit (krb_principal *princ, int lifetime, char *locuser,
+ char *tktfile, des_cblock *key, char *hostname)
+{
+ struct in_addr *addr;
+ unsigned naddr;
+ unsigned i;
+ int port;
+ int success;
+
+ addr = getalladdrs (hostname, &naddr);
+ if (addr == NULL)
+ return 1;
+ port = k_getportbyname ("kauth", "tcp", htons(KAUTH_PORT));
+ success = 0;
+ for (i = 0; !success && i < naddr; ++i) {
+ struct sockaddr_in a;
+ int s;
+
+ memset(&a, 0, sizeof(a));
+ a.sin_family = AF_INET;
+ a.sin_port = port;
+ a.sin_addr = addr[i];
+
+ s = socket (AF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ warn("socket");
+ return 1;
+ }
+ if (connect(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
+ warn("connect(%s)", hostname);
+ continue;
+ }
+
+ success = success || !doit_host (princ, lifetime,
+ locuser, tktfile, key,
+ s, hostname);
+ close (s);
+ }
+ return !success;
+}
diff --git a/crypto/heimdal/appl/kauth/zrefresh b/crypto/heimdal/appl/kauth/zrefresh
new file mode 100755
index 000000000000..8347a1b33c0c
--- /dev/null
+++ b/crypto/heimdal/appl/kauth/zrefresh
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# @(#) $Id: zrefresh,v 1.3 1996/06/09 19:21:59 joda Exp $
+#
+# Substitute this script with a real zrefresh if running Zephyr. For
+# instance:
+#
+# if [ -f "$WGFILE" ] ; then
+# zctl load
+# fi
+
+exit 0
diff --git a/crypto/heimdal/appl/kf/Makefile.am b/crypto/heimdal/appl/kf/Makefile.am
new file mode 100644
index 000000000000..44b70698fcf0
--- /dev/null
+++ b/crypto/heimdal/appl/kf/Makefile.am
@@ -0,0 +1,14 @@
+# $Id: Makefile.am,v 1.1 1999/07/22 11:36:26 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+noinst_PROGRAMS = kf kfd
+
+kf_SOURCES = kf.c kf_locl.h
+
+kfd_SOURCES = kfd.c kf_locl.h
+
+LDADD = $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
diff --git a/crypto/heimdal/appl/kf/Makefile.in b/crypto/heimdal/appl/kf/Makefile.in
new file mode 100644
index 000000000000..5c608103937a
--- /dev/null
+++ b/crypto/heimdal/appl/kf/Makefile.in
@@ -0,0 +1,626 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.1 1999/07/22 11:36:26 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+noinst_PROGRAMS = kf kfd
+
+kf_SOURCES = kf.c kf_locl.h
+
+kfd_SOURCES = kfd.c kf_locl.h
+
+LDADD = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+noinst_PROGRAMS = kf$(EXEEXT) kfd$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+kf_OBJECTS = kf.$(OBJEXT)
+kf_LDADD = $(LDADD)
+kf_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+kf_LDFLAGS =
+kfd_OBJECTS = kfd.$(OBJEXT)
+kfd_LDADD = $(LDADD)
+kfd_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+kfd_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(kf_SOURCES) $(kfd_SOURCES)
+OBJECTS = $(kf_OBJECTS) $(kfd_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/kf/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+kf$(EXEEXT): $(kf_OBJECTS) $(kf_DEPENDENCIES)
+ @rm -f kf$(EXEEXT)
+ $(LINK) $(kf_LDFLAGS) $(kf_OBJECTS) $(kf_LDADD) $(LIBS)
+
+kfd$(EXEEXT): $(kfd_OBJECTS) $(kfd_DEPENDENCIES)
+ @rm -f kfd$(EXEEXT)
+ $(LINK) $(kfd_LDFLAGS) $(kfd_OBJECTS) $(kfd_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/kf
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-noinstPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstPROGRAMS distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/kf/kf.c b/crypto/heimdal/appl/kf/kf.c
new file mode 100644
index 000000000000..1e85f94d34c1
--- /dev/null
+++ b/crypto/heimdal/appl/kf/kf.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kf_locl.h"
+RCSID("$Id: kf.c,v 1.13 1999/12/04 18:04:09 assar Exp $");
+
+krb5_context context;
+static int help_flag;
+static int version_flag;
+static char *port_str;
+const char *service = SERVICE;
+const char *remote_name = NULL;
+int forwardable = 0;
+const char *ccache_name = NULL;
+
+static struct getargs args[] = {
+ { "port", 'p', arg_string, &port_str, "port to connect to", "port" },
+ { "login", 'l',arg_string, &remote_name,"remote login name","login"},
+ { "ccache", 'c',arg_string, &ccache_name, "remote cred cache","ccache"},
+ { "forwardable",'F',arg_flag,&forwardable,
+ "Forward forwardable credentials", NULL },
+ { "forwardable",'G',arg_negative_flag,&forwardable,
+ "Don't forward forwardable credentials", NULL },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 0, arg_flag, &version_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int code, struct getargs *args, int num_args)
+{
+ arg_printusage(args, num_args, NULL, "hosts");
+ exit(code);
+}
+
+static int
+client_setup(krb5_context *context, int *argc, char **argv)
+{
+ int optind = 0;
+ int port = 0;
+ int status;
+
+ set_progname (argv[0]);
+
+ status = krb5_init_context (context);
+ if (status)
+ errx(1, "krb5_init_context failed: %u", status);
+
+ forwardable = krb5_config_get_bool (*context, NULL,
+ "libdefaults",
+ "forwardable",
+ NULL);
+
+ if (getarg (args, num_args, *argc, argv, &optind))
+ usage(1, args, num_args);
+
+ if(help_flag)
+ usage (0, args, num_args);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ if(port_str) {
+ struct servent *s = roken_getservbyname(port_str, "tcp");
+ if(s)
+ port = s->s_port;
+ else {
+ char *ptr;
+
+ port = strtol (port_str, &ptr, 10);
+ if (port == 0 && ptr == port_str)
+ errx (1, "Bad port `%s'", port_str);
+ port = htons(port);
+ }
+ }
+
+ if (port == 0)
+ port = krb5_getportbyname (*context, PORT, "tcp", PORT_NUM);
+
+ if(*argc - optind < 1)
+ usage(1, args, num_args);
+ *argc = optind;
+
+ return port;
+}
+
+/*
+ * forward creds to `hostname'/`service' over `sock'
+ * return 0 iff OK
+ */
+
+static int
+proto (int sock, const char *hostname, const char *service)
+{
+ krb5_auth_context auth_context;
+ krb5_error_code status;
+ krb5_principal server;
+ krb5_data data;
+ krb5_data packet;
+ krb5_data data_send;
+ u_int32_t len, net_len;
+
+ krb5_ccache ccache;
+ krb5_creds creds;
+ krb5_kdc_flags flags;
+ krb5_principal principal;
+ char ret_string[10];
+ ssize_t n;
+
+ status = krb5_auth_con_init (context, &auth_context);
+ if (status) {
+ krb5_warn (context, status, "krb5_auth_con_init");
+ return 1;
+ }
+
+ status = krb5_auth_con_setaddrs_from_fd (context,
+ auth_context,
+ &sock);
+ if (status) {
+ krb5_warn (context, status, "krb5_auth_con_setaddr");
+ return 1;
+ }
+
+ status = krb5_sname_to_principal (context,
+ hostname,
+ service,
+ KRB5_NT_SRV_HST,
+ &server);
+ if (status) {
+ krb5_warn (context, status, "krb5_sname_to_principal");
+ return 1;
+ }
+
+ status = krb5_sendauth (context,
+ &auth_context,
+ &sock,
+ VERSION,
+ NULL,
+ server,
+ AP_OPTS_MUTUAL_REQUIRED,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (status) {
+ krb5_warn(context, status, "krb5_sendauth");
+ return 1;
+ }
+
+ if (remote_name == NULL) {
+ remote_name = get_default_username ();
+ if (remote_name == NULL)
+ errx (1, "who are you?");
+ }
+
+ krb5_data_zero(&data_send);
+ data_send.data = (void *)remote_name;
+ data_send.length = strlen(remote_name) + 1;
+ status = krb5_write_message(context, &sock, &data_send);
+ if (status) {
+ krb5_warn (context, status, "krb5_write_message");
+ return 1;
+ }
+
+ if (ccache_name == NULL)
+ ccache_name = "";
+
+ data_send.data = (void *)ccache_name;
+ data_send.length = strlen(ccache_name)+1;
+ status = krb5_write_message(context, &sock, &data_send);
+ if (status) {
+ krb5_warn (context, status, "krb5_write_message");
+ return 1;
+ }
+
+ memset (&creds, 0, sizeof(creds));
+
+ status = krb5_cc_default (context, &ccache);
+ if (status) {
+ krb5_warn (context, status, "krb5_cc_default");
+ return 1;
+ }
+
+ status = krb5_cc_get_principal (context, ccache, &principal);
+ if (status) {
+ krb5_warn (context, status, "krb5_cc_get_principal");
+ return 1;
+ }
+
+ creds.client = principal;
+
+ status = krb5_build_principal (context,
+ &creds.server,
+ strlen(principal->realm),
+ principal->realm,
+ KRB5_TGS_NAME,
+ principal->realm,
+ NULL);
+
+ if (status) {
+ krb5_warn (context, status, "krb5_build_principal");
+ return 1;
+ }
+
+ creds.times.endtime = 0;
+
+ flags.i = 0;
+ flags.b.forwarded = 1;
+ flags.b.forwardable = forwardable;
+
+ status = krb5_get_forwarded_creds (context,
+ auth_context,
+ ccache,
+ flags.i,
+ hostname,
+ &creds,
+ &data);
+ if (status) {
+ krb5_warn (context, status, "krb5_get_forwarded_creds");
+ return 1;
+ }
+
+ status = krb5_mk_priv (context,
+ auth_context,
+ &data,
+ &packet,
+ NULL);
+ if (status) {
+ krb5_warn (context, status, "krb5_mk_priv");
+ return 1;
+ }
+
+ len = packet.length;
+ net_len = htonl(len);
+
+ if (krb5_net_write (context, &sock, &net_len, 4) != 4) {
+ krb5_warn (context, errno, "krb5_net_write");
+ return 1;
+ }
+ if (krb5_net_write (context, &sock, packet.data, len) != len) {
+ krb5_warn (context, errno, "krb5_net_write");
+ return 1;
+ }
+
+ krb5_data_free (&data);
+
+ n = krb5_net_read (context, &sock, &net_len, 4);
+ if (n == 0) {
+ krb5_warnx (context, "EOF in krb5_net_read");
+ return 1;
+ }
+ if (n < 0) {
+ krb5_warn (context, errno, "krb5_net_read");
+ return 1;
+ }
+ len = ntohl(net_len);
+ if (len >= sizeof(ret_string)) {
+ krb5_warnx (context, "too long string back from %s", hostname);
+ return 1;
+ }
+ n = krb5_net_read (context, &sock, ret_string, len);
+ if (n == 0) {
+ krb5_warnx (context, "EOF in krb5_net_read");
+ return 1;
+ }
+ if (n < 0) {
+ krb5_warn (context, errno, "krb5_net_read");
+ return 1;
+ }
+ ret_string[sizeof(ret_string) - 1] = '\0';
+
+ return(strcmp(ret_string,"ok"));
+}
+
+static int
+doit (const char *hostname, int port, const char *service)
+{
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char portstr[NI_MAXSERV];
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(port));
+
+ error = getaddrinfo (hostname, portstr, &hints, &ai);
+ if (error) {
+ errx (1, "getaddrinfo(%s): %s", hostname, gai_strerror(error));
+ }
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ int s;
+
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0)
+ continue;
+ if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
+ warn ("connect(%s)", hostname);
+ close (s);
+ continue;
+ }
+ freeaddrinfo (ai);
+ return proto (s, hostname, service);
+ }
+ warnx ("failed to contact %s", hostname);
+ freeaddrinfo (ai);
+ return 1;
+}
+
+int
+main(int argc, char **argv)
+{
+ int argcc,port,i;
+ int ret=0;
+
+ argcc = argc;
+ port = client_setup(&context, &argcc, argv);
+
+ for (i = argcc;i < argc; i++) {
+ ret = doit (argv[i], port, service);
+ warnx ("%s %s", argv[i], ret ? "failed" : "ok");
+ }
+ return(ret);
+}
diff --git a/crypto/heimdal/appl/kf/kf_locl.h b/crypto/heimdal/appl/kf/kf_locl.h
new file mode 100644
index 000000000000..29f59412d8b5
--- /dev/null
+++ b/crypto/heimdal/appl/kf/kf_locl.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: kf_locl.h,v 1.2 1999/12/02 17:04:55 joda Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <errno.h>
+#include <roken.h>
+#include <getarg.h>
+#include <err.h>
+#include <krb5.h>
+
+#define SERVICE "host"
+
+#define PORT "kf"
+#define PORT_NUM 2110
diff --git a/crypto/heimdal/appl/kf/kfd.c b/crypto/heimdal/appl/kf/kfd.c
new file mode 100644
index 000000000000..9ad434f20a10
--- /dev/null
+++ b/crypto/heimdal/appl/kf/kfd.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kf_locl.h"
+RCSID("$Id: kfd.c,v 1.7 1999/12/02 17:04:55 joda Exp $");
+
+krb5_context context;
+char krb5_tkfile[MAXPATHLEN];
+
+static int help_flag;
+static int version_flag;
+static char *port_str;
+char *service = SERVICE;
+int do_inetd = 0;
+static char *regpag_str=NULL;
+
+static struct getargs args[] = {
+ { "port", 'p', arg_string, &port_str, "port to listen to", "port" },
+ { "inetd",'i',arg_flag, &do_inetd,
+ "Not started from inetd", NULL },
+ { "regpag",'R',arg_string,&regpag_str,"path to regpag binary","regpag"},
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 0, arg_flag, &version_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int code, struct getargs *args, int num_args)
+{
+ arg_printusage(args, num_args, NULL, "");
+ exit(code);
+}
+
+static int
+server_setup(krb5_context *context, int argc, char **argv)
+{
+ int port = 0;
+ int local_argc;
+
+ local_argc = krb5_program_setup(context, argc, argv, args, num_args, usage);
+
+ if(help_flag)
+ (*usage)(0, args, num_args);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ if(port_str){
+ struct servent *s = roken_getservbyname(port_str, "tcp");
+ if(s)
+ port = s->s_port;
+ else {
+ char *ptr;
+
+ port = strtol (port_str, &ptr, 10);
+ if (port == 0 && ptr == port_str)
+ errx (1, "Bad port `%s'", port_str);
+ port = htons(port);
+ }
+ }
+
+ if (port == 0)
+ port = krb5_getportbyname (*context, PORT, "tcp", PORT_NUM);
+
+ if(argv[local_argc] != NULL)
+ usage(1, args, num_args);
+
+ return port;
+}
+
+static void
+syslog_and_die (const char *m, ...)
+{
+ va_list args;
+
+ va_start(args, m);
+ vsyslog (LOG_ERR, m, args);
+ va_end(args);
+ exit (1);
+}
+
+static void
+syslog_and_cont (const char *m, ...)
+{
+ va_list args;
+
+ va_start(args, m);
+ vsyslog (LOG_ERR, m, args);
+ va_end(args);
+ return;
+}
+
+static int
+proto (int sock, const char *service)
+{
+ krb5_auth_context auth_context;
+ krb5_error_code status;
+ krb5_principal server;
+ krb5_ticket *ticket;
+ char *name;
+ char ret_string[10];
+ char hostname[MAXHOSTNAMELEN];
+ krb5_data packet;
+ krb5_data data;
+ krb5_data remotename;
+ krb5_data tk_file;
+
+ u_int32_t len, net_len;
+ krb5_ccache ccache;
+ char ccname[MAXPATHLEN];
+ struct passwd *pwd;
+ ssize_t n;
+
+ status = krb5_auth_con_init (context, &auth_context);
+ if (status)
+ syslog_and_die("krb5_auth_con_init: %s",
+ krb5_get_err_text(context, status));
+
+ status = krb5_auth_con_setaddrs_from_fd (context,
+ auth_context,
+ &sock);
+ if (status)
+ syslog_and_die("krb5_auth_con_setaddr: %s",
+ krb5_get_err_text(context, status));
+
+ if(gethostname (hostname, sizeof(hostname)) < 0)
+ syslog_and_die("gethostname: %s",strerror(errno));
+
+ status = krb5_sname_to_principal (context,
+ hostname,
+ service,
+ KRB5_NT_SRV_HST,
+ &server);
+ if (status)
+ syslog_and_die("krb5_sname_to_principal: %s",
+ krb5_get_err_text(context, status));
+
+ status = krb5_recvauth (context,
+ &auth_context,
+ &sock,
+ VERSION,
+ server,
+ 0,
+ NULL,
+ &ticket);
+ if (status)
+ syslog_and_die("krb5_recvauth: %s",
+ krb5_get_err_text(context, status));
+
+ status = krb5_unparse_name (context,
+ ticket->client,
+ &name);
+ if (status)
+ syslog_and_die("krb5_unparse_name: %s",
+ krb5_get_err_text(context, status));
+
+ status=krb5_read_message (context, &sock, &remotename);
+ if (status) {
+ syslog_and_die("krb5_read_message: %s",
+ krb5_get_err_text(context, status));
+ }
+ status=krb5_read_message (context, &sock, &tk_file);
+ if (status) {
+ syslog_and_die("krb5_read_message: %s",
+ krb5_get_err_text(context, status));
+ }
+
+ krb5_data_zero (&data);
+ krb5_data_zero (&packet);
+
+ n = krb5_net_read (context, &sock, &net_len, 4);
+ if (n < 0)
+ syslog_and_die("krb5_net_read: %s", strerror(errno));
+ if (n == 0)
+ syslog_and_die("EOF in krb5_net_read");
+
+ len = ntohl(net_len);
+ krb5_data_alloc (&packet, len);
+ n = krb5_net_read (context, &sock, packet.data, len);
+ if (n < 0)
+ syslog_and_die("krb5_net_read: %s", strerror(errno));
+ if (n == 0)
+ syslog_and_die("EOF in krb5_net_read");
+
+ status = krb5_rd_priv (context,
+ auth_context,
+ &packet,
+ &data,
+ NULL);
+ if (status) {
+ syslog_and_cont("krb5_rd_priv: %s",
+ krb5_get_err_text(context, status));
+ goto out;
+ }
+
+ pwd = getpwnam ((char *)(remotename.data));
+ if (pwd == NULL) {
+ status=1;
+ syslog_and_cont("getpwnam: %s failed",(char *)(remotename.data));
+ goto out;
+ }
+
+ if(!krb5_kuserok (context,
+ ticket->client,
+ (char *)(remotename.data))) {
+ status=1;
+ syslog_and_cont("krb5_kuserok: permission denied");
+ goto out;
+ }
+
+ if (setgid(pwd->pw_gid) < 0) {
+ syslog_and_cont ("setgid: %s", strerror(errno));
+ goto out;
+ }
+ if (setuid(pwd->pw_uid) < 0) {
+ syslog_and_cont ("setuid: %s", strerror(errno));
+ goto out;
+ }
+
+ if (tk_file.length != 1)
+ snprintf (ccname, sizeof(ccname), "%s", (char *)(tk_file.data));
+ else
+ snprintf (ccname, sizeof(ccname), "FILE:/tmp/krb5cc_%u",pwd->pw_uid);
+
+ status = krb5_cc_resolve (context, ccname, &ccache);
+ if (status) {
+ syslog_and_cont("krb5_cc_resolve: %s",
+ krb5_get_err_text(context, status));
+ goto out;
+ }
+ status = krb5_cc_initialize (context, ccache, ticket->client);
+ if (status) {
+ syslog_and_cont("krb5_cc_initialize: %s",
+ krb5_get_err_text(context, status));
+ goto out;
+ }
+ status = krb5_rd_cred (context, auth_context, ccache, &data);
+ krb5_cc_close (context, ccache);
+ if (status) {
+ syslog_and_cont("krb5_rd_cred: %s",
+ krb5_get_err_text(context, status));
+ goto out;
+
+ }
+ strlcpy(krb5_tkfile,ccname,sizeof(krb5_tkfile));
+ syslog_and_cont("%s forwarded ticket to %s,%s",
+ name,
+ (char *)(remotename.data),ccname);
+out:
+ if (status) {
+ strcpy(ret_string, "no");
+ syslog_and_cont("failed");
+ } else {
+ strcpy(ret_string, "ok");
+ }
+
+ krb5_data_free (&tk_file);
+ krb5_data_free (&remotename);
+ krb5_data_free (&packet);
+ krb5_data_free (&data);
+ free(name);
+
+ len = strlen(ret_string) + 1;
+ net_len = htonl(len);
+ if (krb5_net_write (context, &sock, &net_len, 4) != 4)
+ return 1;
+ if (krb5_net_write (context, &sock, ret_string, len) != len)
+ return 1;
+ return status;
+}
+
+static int
+doit (int port, const char *service)
+{
+ if (do_inetd)
+ mini_inetd(port);
+ return proto (STDIN_FILENO, service);
+}
+
+int
+main(int argc, char **argv)
+{
+ int port;
+ int ret;
+
+ set_progname (argv[0]);
+ roken_openlog (argv[0], LOG_ODELAY | LOG_PID,LOG_AUTH);
+ port = server_setup(&context, argc, argv);
+ ret = doit (port, service);
+ closelog();
+ if (ret == 0 && regpag_str != NULL)
+ ret = execl(regpag_str, "regpag", "-t", krb5_tkfile, "-r", NULL);
+ return ret;
+}
diff --git a/crypto/heimdal/appl/login/ChangeLog b/crypto/heimdal/appl/login/ChangeLog
new file mode 100644
index 000000000000..a751caeef020
--- /dev/null
+++ b/crypto/heimdal/appl/login/ChangeLog
@@ -0,0 +1,162 @@
+1999-11-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * conf.c: remove case for not having cgetent, since it's in roken
+
+1999-11-05 Assar Westerlund <assar@sics.se>
+
+ * login.c (do_login): conditionalize shadow stuff on getspnam
+
+1999-10-30 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (login_DEPENDENCIES): remove, it's not entirely
+ correct and was causing problems with non-GNU make
+
+1999-10-28 Assar Westerlund <assar@sics.se>
+
+ * login.c (start_logout_proceess): don't examine `prog' before
+ setting it.
+
+1999-10-27 Assar Westerlund <assar@sics.se>
+
+ * login.c (do_login): chown and chmod the tty. some clean-up.
+
+1999-10-03 Assar Westerlund <assar@sics.se>
+
+ * login.c (krb5_start_session): correct the ccache to
+ krb524_convert_creds_kdc
+
+1999-09-28 Assar Westerlund <assar@sics.se>
+
+ * login.c (krb5_verify): use krb5_verify_user_lrealm
+
+1999-09-01 Johan Danielsson <joda@pdc.kth.se>
+
+ * login.c: SGI capability mumbo-jumbo
+
+1999-08-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * login.c (start_logout_process): call setproctitle
+
+ * login_locl.h: declare struct spwd
+
+ * login.c: add support for starting extra processes at login and
+ logout; always preserve TERM and TZ
+
+ * conf.c: add configuration file support
+
+1999-08-07 Assar Westerlund <assar@sics.se>
+
+ * shadow.c (check_shadow): check for a NULL sp
+
+1999-08-05 Assar Westerlund <assar@sics.se>
+
+ * login.c (main): move down login incorrect to disallow account
+ guessing
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * utmpx_login.c (utmpx_login): fix for Solaris. From Miroslav
+ Ruda <ruda@ics.muni.cz>
+
+ * login_locl.h: add <shadow.h> and some prototypes
+
+ * login.c: fixes with v4 and shadow support. From Miroslav Ruda
+ <ruda@ics.muni.cz>
+
+ * shadow.c: new file with functions for handling shadow passwords
+
+ * Makefile.am: add shadow
+
+1999-07-22 Assar Westerlund <assar@sics.se>
+
+ * login.c (main): generate a better tty name
+
+1999-05-25 Johan Danielsson <joda@pdc.kth.se>
+
+ * login.c (do_login): set $SHELL
+
+1999-05-18 Assar Westerlund <assar@sics.se>
+
+ * add login-access
+
+1999-05-11 Assar Westerlund <assar@sics.se>
+
+ * login.c: copy the v5 ccache to a file after having done setuid
+
+1999-05-09 Assar Westerlund <assar@sics.se>
+
+ * login.c (krb5_verify): check seteuid for errors
+
+Mon Apr 19 22:30:55 1999 Assar Westerlund <assar@sics.se>
+
+ * login.c: conditionalize the kafs calls on KRB4
+
+ * Makefile.am (LDADD): add kafs
+
+ * login.c: add support for getting afs tokens with v4 and v5
+
+Sun Apr 18 14:12:28 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * login.c: check _PATH_NOLOGIN
+
+ * login_locl.h: _PATH_NOLOGIN
+
+1999-04-11 Assar Westerlund <assar@sics.se>
+
+ * login.c (main): use print_version
+
+Thu Apr 8 15:03:55 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * login.c: remove definition of KRB_VERIFY_USER et.al. (moved to
+ config.h)
+
+ * login_locl.h: include udb.h, sys/resource.h, and sys/category.h
+
+Sat Mar 27 17:58:37 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: osfc2.c
+
+ * login.c: magic for OSF C2, and Crays
+
+ * login_locl.h: do_osfc2_magic proto
+
+ * osfc2.c: bsd_locl -> login_locl
+
+ * osfc2.c: OSF C2 magic
+
+Tue Mar 23 14:17:40 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * login_locl.h: _PATH_UTMP
+
+Sun Mar 21 15:02:31 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * login.c: `-h' is host, not help
+
+Sat Mar 20 00:11:13 1999 Assar Westerlund <assar@sics.se>
+
+ * login_locl.h: krb.h: add
+
+ * login.c: static-size
+ (krb4_verify): add
+
+Thu Mar 18 11:36:10 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: include Makefile.am.common
+
+Thu Mar 11 17:53:36 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * utmpx_login.c: add some consts
+
+ * utmp_login.c: add some consts
+
+ * login.c: staticize
+
+ * login_locl.h: add prototypes, and defaults for
+ _PATH_*
+
+Mon Mar 1 10:49:14 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * utmpx_login.c: HAVE_UT_* -> HAVE_STRUCT_UTMP*_UT_*
+
+ * utmp_login.c: HAVE_UT_* -> HAVE_STRUCT_UTMP*_UT_*
+
diff --git a/crypto/heimdal/appl/login/Makefile.am b/crypto/heimdal/appl/login/Makefile.am
new file mode 100644
index 000000000000..22b4b624a576
--- /dev/null
+++ b/crypto/heimdal/appl/login/Makefile.am
@@ -0,0 +1,34 @@
+# $Id: Makefile.am,v 1.16 1999/10/30 08:51:45 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+bin_PROGRAMS = login
+
+login_SOURCES = \
+ login.c \
+ osfc2.c \
+ read_string.c \
+ utmp_login.c \
+ utmpx_login.c \
+ tty.c \
+ stty_default.c \
+ login_access.c \
+ login_locl.h \
+ login_proto.h \
+ conf.c \
+ shadow.c
+
+LDADD = $(LIB_kafs) \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken) \
+ $(LIB_security)
+
+$(srcdir)/login_protos.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -o login_protos.h $(login_SOURCES) || rm -f login_protos.h
+
+$(login_OBJECTS): $(srcdir)/login_protos.h
diff --git a/crypto/heimdal/appl/login/Makefile.in b/crypto/heimdal/appl/login/Makefile.in
new file mode 100644
index 000000000000..10b75e8c7478
--- /dev/null
+++ b/crypto/heimdal/appl/login/Makefile.in
@@ -0,0 +1,645 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.16 1999/10/30 08:51:45 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+bin_PROGRAMS = login
+
+login_SOURCES = login.c osfc2.c read_string.c utmp_login.c utmpx_login.c tty.c stty_default.c login_access.c login_locl.h login_proto.h conf.c shadow.c
+
+
+LDADD = $(LIB_kafs) $(top_builddir)/lib/krb5/libkrb5.la $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken) $(LIB_security)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = login$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+login_OBJECTS = login.$(OBJEXT) osfc2.$(OBJEXT) read_string.$(OBJEXT) \
+utmp_login.$(OBJEXT) utmpx_login.$(OBJEXT) tty.$(OBJEXT) \
+stty_default.$(OBJEXT) login_access.$(OBJEXT) conf.$(OBJEXT) \
+shadow.$(OBJEXT)
+login_LDADD = $(LDADD)
+@KRB4_TRUE@login_DEPENDENCIES = $(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@login_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+login_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(login_SOURCES)
+OBJECTS = $(login_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/login/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+login$(EXEEXT): $(login_OBJECTS) $(login_DEPENDENCIES)
+ @rm -f login$(EXEEXT)
+ $(LINK) $(login_LDFLAGS) $(login_OBJECTS) $(login_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/login
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-compile distclean-libtool \
+ distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+$(srcdir)/login_protos.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -o login_protos.h $(login_SOURCES) || rm -f login_protos.h
+
+$(login_OBJECTS): $(srcdir)/login_protos.h
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/login/conf.c b/crypto/heimdal/appl/login/conf.c
new file mode 100644
index 000000000000..6a4b2a8322fc
--- /dev/null
+++ b/crypto/heimdal/appl/login/conf.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "login_locl.h"
+
+RCSID("$Id: conf.c,v 1.2 1999/11/09 18:05:49 joda Exp $");
+
+static char *confbuf;
+
+static int
+login_conf_init(void)
+{
+ char *files[] = { _PATH_LOGIN_CONF, NULL };
+ return cgetent(&confbuf, files, "default");
+}
+
+char *
+login_conf_get_string(const char *str)
+{
+ char *value;
+ if(login_conf_init() != 0)
+ return NULL;
+ if(cgetstr(confbuf, str, &value) < 0)
+ return NULL;
+ return value;
+}
diff --git a/crypto/heimdal/appl/login/login.c b/crypto/heimdal/appl/login/login.c
new file mode 100644
index 000000000000..a149449a57a9
--- /dev/null
+++ b/crypto/heimdal/appl/login/login.c
@@ -0,0 +1,730 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "login_locl.h"
+#ifdef HAVE_CAPABILITY_H
+#include <capability.h>
+#endif
+#ifdef HAVE_SYS_CAPABILITY_H
+#include <sys/capability.h>
+#endif
+
+RCSID("$Id: login.c,v 1.33 1999/12/02 17:04:55 joda Exp $");
+
+/*
+ * the environment we will send to execle and the shell.
+ */
+
+static char **env;
+static int num_env;
+
+static void
+extend_env(char *str)
+{
+ env = realloc(env, (num_env + 1) * sizeof(*env));
+ if(env == NULL)
+ errx(1, "Out of memory!");
+ env[num_env++] = str;
+}
+
+static void
+add_env(const char *var, const char *value)
+{
+ int i;
+ char *str;
+ asprintf(&str, "%s=%s", var, value);
+ if(str == NULL)
+ errx(1, "Out of memory!");
+ for(i = 0; i < num_env; i++)
+ if(strncmp(env[i], var, strlen(var)) == 0 &&
+ env[i][strlen(var)] == '='){
+ free(env[i]);
+ env[i] = str;
+ return;
+ }
+
+ extend_env(str);
+}
+
+static void
+copy_env(void)
+{
+ char **p;
+ for(p = environ; *p; p++)
+ extend_env(*p);
+}
+
+static int
+start_login_process(void)
+{
+ char *prog, *argv0;
+ prog = login_conf_get_string("login_program");
+ if(prog == NULL)
+ return 0;
+ argv0 = strrchr(prog, '/');
+
+ if(argv0)
+ argv0++;
+ else
+ argv0 = prog;
+
+ return simple_execle(prog, argv0, NULL, env);
+}
+
+static int
+start_logout_process(void)
+{
+ char *prog, *argv0;
+ pid_t pid;
+
+ prog = login_conf_get_string("logout_program");
+ if(prog == NULL)
+ return 0;
+ argv0 = strrchr(prog, '/');
+
+ if(argv0)
+ argv0++;
+ else
+ argv0 = prog;
+
+ pid = fork();
+ if(pid == 0)
+ return 0;
+ if(pid == -1)
+ err(1, "fork");
+ /* wait for the real login process to exit */
+#ifdef HAVE_SETPROCTITLE
+ setproctitle("waitpid %d", pid);
+#endif
+ while(1) {
+ int status;
+ int ret;
+ ret = waitpid(pid, &status, 0);
+ if(ret > 0) {
+ if(WIFEXITED(status) || WIFSIGNALED(status)) {
+ execle(prog, argv0, NULL, env);
+ err(1, "exec %s", prog);
+ }
+ } else if(ret < 0)
+ err(1, "waitpid");
+ }
+}
+
+static void
+exec_shell(const char *shell, int fallback)
+{
+ char *sh;
+ const char *p;
+
+ extend_env(NULL);
+ if(start_login_process() < 0)
+ warn("login process");
+ start_logout_process();
+
+ p = strrchr(shell, '/');
+ if(p)
+ p++;
+ else
+ p = shell;
+ asprintf(&sh, "-%s", p);
+ execle(shell, sh, NULL, env);
+ if(fallback){
+ warnx("Can't exec %s, trying %s",
+ shell, _PATH_BSHELL);
+ execle(_PATH_BSHELL, "-sh", NULL, env);
+ err(1, "%s", _PATH_BSHELL);
+ }
+ err(1, "%s", shell);
+}
+
+static enum { AUTH_KRB4, AUTH_KRB5 } auth;
+
+#ifdef KRB5
+static krb5_context context;
+static krb5_ccache id, id2;
+
+static int
+krb5_verify(struct passwd *pwd, const char *password)
+{
+ krb5_error_code ret;
+ krb5_principal princ;
+
+ ret = krb5_init_context(&context);
+ if(ret)
+ return 1;
+
+ ret = krb5_parse_name(context, pwd->pw_name, &princ);
+ if(ret){
+ krb5_free_context(context);
+ return 1;
+ }
+ ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &id);
+ if(ret){
+ krb5_free_principal(context, princ);
+ krb5_free_context(context);
+ return 1;
+ }
+ ret = krb5_verify_user_lrealm(context,
+ princ,
+ id,
+ password,
+ 1,
+ NULL);
+ krb5_free_principal(context, princ);
+ if (ret)
+ krb5_free_context (context);
+ return ret;
+}
+
+static int
+krb5_start_session (const struct passwd *pwd)
+{
+ krb5_error_code ret;
+ char residual[64];
+
+ /* copy credentials to file cache */
+ snprintf(residual, sizeof(residual), "FILE:/tmp/krb5cc_%u",
+ (unsigned)pwd->pw_uid);
+ krb5_cc_resolve(context, residual, &id2);
+ ret = krb5_cc_copy_cache(context, id, id2);
+ if (ret == 0)
+ add_env("KRB5CCNAME", residual);
+ else {
+ krb5_cc_destroy (context, id2);
+ return ret;
+ }
+#ifdef KRB4
+ if (krb5_config_get_bool(context, NULL,
+ "libdefaults",
+ "krb4_get_tickets",
+ NULL)) {
+ CREDENTIALS c;
+ krb5_creds mcred, cred;
+ krb5_realm realm;
+ char krb4tkfile[MAXPATHLEN];
+
+ krb5_get_default_realm(context, &realm);
+ krb5_make_principal(context, &mcred.server, realm,
+ "krbtgt",
+ realm,
+ NULL);
+ free (realm);
+ ret = krb5_cc_retrieve_cred(context, id2, 0, &mcred, &cred);
+ if(ret == 0) {
+ ret = krb524_convert_creds_kdc(context, id2, &cred, &c);
+ if(ret == 0) {
+ snprintf(krb4tkfile,sizeof(krb4tkfile),"%s%d",TKT_ROOT,
+ getuid());
+ krb_set_tkt_string(krb4tkfile);
+ tf_setup(&c, c.pname, c.pinst);
+ }
+ memset(&c, 0, sizeof(c));
+ krb5_free_creds_contents(context, &cred);
+ }
+ krb5_free_principal(context, mcred.server);
+ }
+#endif
+ krb5_cc_close(context, id2);
+ krb5_cc_destroy(context, id);
+ return 0;
+}
+
+static void
+krb5_finish (void)
+{
+ krb5_free_context(context);
+}
+
+#ifdef KRB4
+
+static int pag_set = 0;
+
+static void
+krb5_get_afs_tokens (const struct passwd *pwd)
+{
+ char cell[64];
+ char *pw_dir;
+ krb5_error_code ret;
+
+ if (!k_hasafs ())
+ return;
+
+ ret = krb5_init_context(&context);
+ if(ret)
+ return;
+ ret = krb5_cc_default(context, &id2);
+
+ if (ret == 0) {
+ pw_dir = pwd->pw_dir;
+
+ if (!pag_set) {
+ k_setpag();
+ pag_set = 1;
+ }
+
+ if(k_afs_cell_of_file(pw_dir, cell, sizeof(cell)) == 0)
+ krb5_afslog_uid_home (context, id2,
+ cell, NULL, pwd->pw_uid, pwd->pw_dir);
+ krb5_afslog_uid_home (context, id2, NULL, NULL,
+ pwd->pw_uid, pwd->pw_dir);
+ krb5_cc_close (context, id2);
+ }
+ krb5_free_context (context);
+}
+
+#endif /* KRB4 */
+
+#endif /* KRB5 */
+
+#ifdef KRB4
+
+static int
+krb4_verify(struct passwd *pwd, const char *password)
+{
+ char lrealm[REALM_SZ];
+ int ret;
+ char ticket_file[MaxPathLen];
+
+ ret = krb_get_lrealm (lrealm, 1);
+ if (ret)
+ return 1;
+
+ snprintf (ticket_file, sizeof(ticket_file),
+ "%s%u_%u",
+ TKT_ROOT, (unsigned)pwd->pw_uid, (unsigned)getpid());
+
+ krb_set_tkt_string (ticket_file);
+
+ ret = krb_verify_user (pwd->pw_name, "", lrealm, (char *)password,
+ KRB_VERIFY_SECURE_FAIL, NULL);
+ if (ret)
+ return 1;
+
+ if (chown (ticket_file, pwd->pw_uid, pwd->pw_gid) < 0) {
+ dest_tkt();
+ return 1;
+ }
+
+ add_env ("KRBTKFILE", ticket_file);
+ return 0;
+}
+
+static void
+krb4_get_afs_tokens (const struct passwd *pwd)
+{
+ char cell[64];
+ char *pw_dir;
+
+ if (!k_hasafs ())
+ return;
+
+ pw_dir = pwd->pw_dir;
+
+ if (!pag_set) {
+ k_setpag();
+ pag_set = 1;
+ }
+
+ if(k_afs_cell_of_file(pw_dir, cell, sizeof(cell)) == 0)
+ krb_afslog_uid_home (cell, NULL, pwd->pw_uid, pwd->pw_dir);
+
+ krb_afslog_uid_home (NULL, NULL, pwd->pw_uid, pwd->pw_dir);
+}
+
+#endif /* KRB4 */
+
+static int f_flag;
+static int p_flag;
+static int r_flag;
+static int version_flag;
+static int help_flag;
+static char *remote_host;
+
+struct getargs args[] = {
+#if 0
+ { NULL, 'a' },
+ { NULL, 'd' },
+#endif
+ { NULL, 'f', arg_flag, &f_flag, "pre-authenticated" },
+ { NULL, 'h', arg_string, &remote_host, "remote host", "hostname" },
+ { NULL, 'p', arg_flag, &p_flag, "don't purge environment" },
+#if 0
+ { NULL, 'r', arg_flag, &r_flag, "rlogin protocol" },
+#endif
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag,&help_flag, }
+};
+
+int nargs = sizeof(args) / sizeof(args[0]);
+
+static void
+update_utmp(const char *username, const char *hostname,
+ char *tty, char *ttyn)
+{
+ /*
+ * Update the utmp files, both BSD and SYSV style.
+ */
+ if (utmpx_login(tty, username, hostname) != 0 && !f_flag) {
+ printf("No utmpx entry. You must exec \"login\" from the "
+ "lowest level shell.\n");
+ exit(1);
+ }
+ utmp_login(ttyn, username, hostname);
+}
+
+static void
+checknologin(void)
+{
+ FILE *f;
+ char buf[1024];
+
+ f = fopen(_PATH_NOLOGIN, "r");
+ if(f == NULL)
+ return;
+ while(fgets(buf, sizeof(buf), f))
+ fputs(buf, stdout);
+ fclose(f);
+ exit(0);
+}
+
+/*
+ * Actually log in the user. `pwd' contains all the relevant
+ * information about the user. `ttyn' is the complete name of the tty
+ * and `tty' the short name.
+ */
+
+static void
+do_login(const struct passwd *pwd, char *tty, char *ttyn)
+{
+#ifdef HAVE_GETSPNAM
+ struct spwd *sp;
+#endif
+ int rootlogin = (pwd->pw_uid == 0);
+ gid_t tty_gid;
+ struct group *gr;
+ const char *home_dir;
+
+ if(!rootlogin)
+ checknologin();
+
+#ifdef HAVE_GETSPNAM
+ sp = getspnam(pwd->pw_name);
+#endif
+
+ update_utmp(pwd->pw_name, remote_host ? remote_host : "",
+ tty, ttyn);
+
+ gr = getgrnam ("tty");
+ if (gr != NULL)
+ tty_gid = gr->gr_gid;
+ else
+ tty_gid = pwd->pw_gid;
+
+ if (chown (ttyn, pwd->pw_uid, pwd->pw_gid) < 0) {
+ warn("chown %s", ttyn);
+ if (rootlogin == 0)
+ exit (1);
+ }
+
+ if (chmod (ttyn, S_IRUSR | S_IWUSR | S_IWGRP) < 0) {
+ warn("chmod %s", ttyn);
+ if (rootlogin == 0)
+ exit (1);
+ }
+
+#ifdef HAVE_SETLOGIN
+ if(setlogin(pwd->pw_name)){
+ warn("setlogin(%s)", pwd->pw_name);
+ if(rootlogin == 0)
+ exit(1);
+ }
+#endif
+#ifdef HAVE_INITGROUPS
+ if(initgroups(pwd->pw_name, pwd->pw_gid)){
+ warn("initgroups(%s, %u)", pwd->pw_name, (unsigned)pwd->pw_gid);
+ if(rootlogin == 0)
+ exit(1);
+ }
+#endif
+ if(setgid(pwd->pw_gid)){
+ warn("setgid(%u)", (unsigned)pwd->pw_gid);
+ if(rootlogin == 0)
+ exit(1);
+ }
+ if(setuid(pwd->pw_uid)){
+ warn("setuid(%u)", (unsigned)pwd->pw_uid);
+ if(rootlogin == 0)
+ exit(1);
+ }
+ /* all kinds of different magic */
+
+#ifdef HAVE_GETSPNAM
+ check_shadow(pwd, sp);
+#endif
+
+ if(do_osfc2_magic(pwd->pw_uid))
+ exit(1);
+#if defined(HAVE_GETUDBNAM) && defined(HAVE_SETLIM)
+ {
+ struct udb *udb;
+ long t;
+ const long maxcpu = 46116860184; /* some random constant */
+ udb = getudbnam(pwd->pw_name);
+ if(udb == UDB_NULL)
+ errx(1, "Failed to get UDB entry.");
+ t = udb->ue_pcpulim[UDBRC_INTER];
+ if(t == 0 || t > maxcpu)
+ t = CPUUNLIM;
+ else
+ t *= 100 * CLOCKS_PER_SEC;
+
+ if(limit(C_PROC, 0, L_CPU, t) < 0)
+ warn("limit C_PROC");
+
+ t = udb->ue_jcpulim[UDBRC_INTER];
+ if(t == 0 || t > maxcpu)
+ t = CPUUNLIM;
+ else
+ t *= 100 * CLOCKS_PER_SEC;
+
+ if(limit(C_JOBPROCS, 0, L_CPU, t) < 0)
+ warn("limit C_JOBPROCS");
+
+ nice(udb->ue_nice[UDBRC_INTER]);
+ }
+#endif
+#if defined(HAVE_SGI_GETCAPABILITYBYNAME) && defined(HAVE_CAP_SET_PROC)
+ /* XXX SGI capability hack IRIX 6.x (x >= 0?) has something
+ called capabilities, that allow you to give away
+ permissions (such as chown) to specific processes. From 6.5
+ this is default on, and the default capability set seems to
+ not always be the empty set. The problem is that the
+ runtime linker refuses to do just about anything if the
+ process has *any* capabilities set, so we have to remove
+ them here (unless otherwise instructed by /etc/capability).
+ In IRIX < 6.5, these functions was called sgi_cap_setproc,
+ etc, but we ignore this fact (it works anyway). */
+ {
+ struct user_cap *ucap = sgi_getcapabilitybyname(pwd->pw_name);
+ cap_t cap;
+ if(ucap == NULL)
+ cap = cap_from_text("all=");
+ else
+ cap = cap_from_text(ucap->ca_default);
+ if(cap == NULL)
+ err(1, "cap_from_text");
+ if(cap_set_proc(cap) < 0)
+ err(1, "cap_set_proc");
+ cap_free(cap);
+ free(ucap);
+ }
+#endif
+ home_dir = pwd->pw_dir;
+ if (chdir(home_dir) < 0) {
+ fprintf(stderr, "No home directory \"%s\"!\n", pwd->pw_dir);
+ if (chdir("/"))
+ exit(0);
+ home_dir = "/";
+ fprintf(stderr, "Logging in with home = \"/\".\n");
+ }
+#ifdef KRB5
+ if (auth == AUTH_KRB5) {
+ krb5_start_session (pwd);
+ krb5_finish ();
+ }
+#ifdef KRB4
+ krb5_get_afs_tokens (pwd);
+#endif /* KRB4 */
+#endif /* KRB5 */
+
+#ifdef KRB4
+ krb4_get_afs_tokens (pwd);
+#endif /* KRB4 */
+
+ add_env("HOME", home_dir);
+ add_env("USER", pwd->pw_name);
+ add_env("LOGNAME", pwd->pw_name);
+ add_env("SHELL", pwd->pw_shell);
+ exec_shell(pwd->pw_shell, rootlogin);
+}
+
+static int
+check_password(struct passwd *pwd, const char *password)
+{
+ if(pwd->pw_passwd == NULL)
+ return 1;
+ if(pwd->pw_passwd[0] == '\0'){
+#ifdef ALLOW_NULL_PASSWORD
+ return password[0] != '\0';
+#else
+ return 1;
+#endif
+ }
+ if(strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) == 0)
+ return 0;
+#ifdef KRB5
+ if(krb5_verify(pwd, password) == 0) {
+ auth = AUTH_KRB5;
+ return 0;
+ }
+#endif
+#ifdef KRB4
+ if (krb4_verify (pwd, password) == 0) {
+ auth = AUTH_KRB4;
+ return 0;
+ }
+#endif
+ return 1;
+}
+
+static void
+usage(int status)
+{
+ arg_printusage(args, nargs, NULL, "[username]");
+ exit(status);
+}
+
+int
+main(int argc, char **argv)
+{
+ int max_tries = 5;
+ int try;
+
+ char username[32];
+ int optind = 0;
+
+ int ask = 1;
+
+ set_progname(argv[0]);
+
+ openlog("login", LOG_ODELAY, LOG_AUTH);
+
+ if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
+ &optind))
+ usage (1);
+ argc -= optind;
+ argv += optind;
+
+ if(help_flag)
+ usage(0);
+ if (version_flag) {
+ print_version (NULL);
+ return 0;
+ }
+
+ if (geteuid() != 0)
+ errx(1, "only root may use login, use su");
+
+ /* Default tty settings. */
+ stty_default();
+
+ if(p_flag)
+ copy_env();
+ else {
+ /* this set of variables is always preserved by BSD login */
+ if(getenv("TERM"))
+ add_env("TERM", getenv("TERM"));
+ if(getenv("TZ"))
+ add_env("TZ", getenv("TZ"));
+ }
+
+ if(*argv){
+ if(strchr(*argv, '=') == NULL && strcmp(*argv, "-") != 0){
+ strlcpy (username, *argv, sizeof(username));
+ ask = 0;
+ }
+ }
+ /* XXX should we care about environment on the command line? */
+ for(try = 0; try < max_tries; try++){
+ struct passwd *pwd;
+ char password[128];
+ int ret;
+ char ttname[32];
+ char *tty, *ttyn;
+
+ if(ask){
+ f_flag = r_flag = 0;
+ ret = read_string("login: ", username, sizeof(username), 1);
+ if(ret == -3)
+ exit(0);
+ if(ret == -2)
+ continue;
+ }
+ pwd = k_getpwnam(username);
+#ifdef ALLOW_NULL_PASSWORD
+ if (pwd != NULL && (pwd->pw_passwd[0] == '\0')) {
+ strcpy(password,"");
+ }
+ else
+#endif
+ if(f_flag == 0) {
+ ret = read_string("Password: ", password, sizeof(password), 0);
+ if(ret == -3 || ret == -2)
+ continue;
+ }
+
+ if(pwd == NULL){
+ fprintf(stderr, "Login incorrect.\n");
+ ask = 1;
+ continue;
+ }
+
+ if(f_flag == 0 && check_password(pwd, password)){
+ fprintf(stderr, "Login incorrect.\n");
+ ask = 1;
+ continue;
+ }
+ ttyn = ttyname(STDIN_FILENO);
+ if(ttyn == NULL){
+ snprintf(ttname, sizeof(ttname), "%s??", _PATH_TTY);
+ ttyn = ttname;
+ }
+ if (strncmp (ttyn, _PATH_DEV, strlen(_PATH_DEV)) == 0)
+ tty = ttyn + strlen(_PATH_DEV);
+ else
+ tty = ttyn;
+
+ if (login_access (pwd, remote_host ? remote_host : tty) == 0) {
+ fprintf(stderr, "Permission denied\n");
+ if (remote_host)
+ syslog(LOG_NOTICE, "%s LOGIN REFUSED FROM %s",
+ pwd->pw_name, remote_host);
+ else
+ syslog(LOG_NOTICE, "%s LOGIN REFUSED ON %s",
+ pwd->pw_name, tty);
+ exit (1);
+ }
+ do_login(pwd, tty, ttyn);
+ }
+ exit(1);
+}
diff --git a/crypto/heimdal/appl/login/login_access.c b/crypto/heimdal/appl/login/login_access.c
new file mode 100644
index 000000000000..86d691ef79b4
--- /dev/null
+++ b/crypto/heimdal/appl/login/login_access.c
@@ -0,0 +1,261 @@
+ /*
+ * This module implements a simple but effective form of login access
+ * control based on login names and on host (or domain) names, internet
+ * addresses (or network numbers), or on terminal line names in case of
+ * non-networked logins. Diagnostics are reported through syslog(3).
+ *
+ * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ */
+
+#include "login_locl.h"
+
+RCSID("$Id: login_access.c,v 1.1 1999/05/17 22:40:05 assar Exp $");
+
+ /* Delimiters for fields and for lists of users, ttys or hosts. */
+
+static char fs[] = ":"; /* field separator */
+static char sep[] = ", \t"; /* list-element separator */
+
+ /* Constants to be used in assignments only, not in comparisons... */
+
+#define YES 1
+#define NO 0
+
+ /*
+ * A structure to bundle up all login-related information to keep the
+ * functional interfaces as generic as possible.
+ */
+struct login_info {
+ struct passwd *user;
+ char *from;
+};
+
+static int list_match(char *list, struct login_info *item,
+ int (*match_fn)(char *, struct login_info *));
+static int user_match(char *tok, struct login_info *item);
+static int from_match(char *tok, struct login_info *item);
+static int string_match(char *tok, char *string);
+
+/* login_access - match username/group and host/tty with access control file */
+
+int login_access(struct passwd *user, char *from)
+{
+ struct login_info item;
+ FILE *fp;
+ char line[BUFSIZ];
+ char *perm; /* becomes permission field */
+ char *users; /* becomes list of login names */
+ char *froms; /* becomes list of terminals or hosts */
+ int match = NO;
+ int end;
+ int lineno = 0; /* for diagnostics */
+ char *foo;
+
+ /*
+ * Bundle up the arguments to avoid unnecessary clumsiness lateron.
+ */
+ item.user = user;
+ item.from = from;
+
+ /*
+ * Process the table one line at a time and stop at the first match.
+ * Blank lines and lines that begin with a '#' character are ignored.
+ * Non-comment lines are broken at the ':' character. All fields are
+ * mandatory. The first field should be a "+" or "-" character. A
+ * non-existing table means no access control.
+ */
+
+ if ((fp = fopen(_PATH_LOGACCESS, "r")) != 0) {
+ while (!match && fgets(line, sizeof(line), fp)) {
+ lineno++;
+ if (line[end = strlen(line) - 1] != '\n') {
+ syslog(LOG_ERR, "%s: line %d: missing newline or line too long",
+ _PATH_LOGACCESS, lineno);
+ continue;
+ }
+ if (line[0] == '#')
+ continue; /* comment line */
+ while (end > 0 && isspace((unsigned char)line[end - 1]))
+ end--;
+ line[end] = 0; /* strip trailing whitespace */
+ if (line[0] == 0) /* skip blank lines */
+ continue;
+ foo = NULL;
+ if (!(perm = strtok_r(line, fs, &foo))
+ || !(users = strtok_r(NULL, fs, &foo))
+ || !(froms = strtok_r(NULL, fs, &foo))
+ || strtok_r(NULL, fs, &foo)) {
+ syslog(LOG_ERR, "%s: line %d: bad field count",
+ _PATH_LOGACCESS,
+ lineno);
+ continue;
+ }
+ if (perm[0] != '+' && perm[0] != '-') {
+ syslog(LOG_ERR, "%s: line %d: bad first field",
+ _PATH_LOGACCESS,
+ lineno);
+ continue;
+ }
+ match = (list_match(froms, &item, from_match)
+ && list_match(users, &item, user_match));
+ }
+ fclose(fp);
+ } else if (errno != ENOENT) {
+ syslog(LOG_ERR, "cannot open %s: %m", _PATH_LOGACCESS);
+ }
+ return (match == 0 || (line[0] == '+'));
+}
+
+/* list_match - match an item against a list of tokens with exceptions */
+
+static int
+list_match(char *list,
+ struct login_info *item,
+ int (*match_fn)(char *, struct login_info *))
+{
+ char *tok;
+ int match = NO;
+ char *foo = NULL;
+
+ /*
+ * Process tokens one at a time. We have exhausted all possible matches
+ * when we reach an "EXCEPT" token or the end of the list. If we do find
+ * a match, look for an "EXCEPT" list and recurse to determine whether
+ * the match is affected by any exceptions.
+ */
+
+ for (tok = strtok_r(list, sep, &foo);
+ tok != NULL;
+ tok = strtok_r(NULL, sep, &foo)) {
+ if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
+ break;
+ if ((match = (*match_fn) (tok, item)) != 0) /* YES */
+ break;
+ }
+ /* Process exceptions to matches. */
+
+ if (match != NO) {
+ while ((tok = strtok_r(NULL, sep, &foo)) && strcasecmp(tok, "EXCEPT"))
+ /* VOID */ ;
+ if (tok == 0 || list_match(NULL, item, match_fn) == NO)
+ return (match);
+ }
+ return (NO);
+}
+
+/* myhostname - figure out local machine name */
+
+static char *myhostname(void)
+{
+ static char name[MAXHOSTNAMELEN + 1] = "";
+
+ if (name[0] == 0) {
+ gethostname(name, sizeof(name));
+ name[MAXHOSTNAMELEN] = 0;
+ }
+ return (name);
+}
+
+/* netgroup_match - match group against machine or user */
+
+static int netgroup_match(char *group, char *machine, char *user)
+{
+#ifdef HAVE_YP_GET_DEFAULT_DOMAIN
+ static char *mydomain = 0;
+
+ if (mydomain == 0)
+ yp_get_default_domain(&mydomain);
+ return (innetgr(group, machine, user, mydomain));
+#else
+ syslog(LOG_ERR, "NIS netgroup support not configured");
+ return 0;
+#endif
+}
+
+/* user_match - match a username against one token */
+
+static int user_match(char *tok, struct login_info *item)
+{
+ char *string = item->user->pw_name;
+ struct login_info fake_item;
+ struct group *group;
+ int i;
+ char *at;
+
+ /*
+ * If a token has the magic value "ALL" the match always succeeds.
+ * Otherwise, return YES if the token fully matches the username, if the
+ * token is a group that contains the username, or if the token is the
+ * name of the user's primary group.
+ */
+
+ if ((at = strchr(tok + 1, '@')) != 0) { /* split user@host pattern */
+ *at = 0;
+ fake_item.from = myhostname();
+ return (user_match(tok, item) && from_match(at + 1, &fake_item));
+ } else if (tok[0] == '@') { /* netgroup */
+ return (netgroup_match(tok + 1, (char *) 0, string));
+ } else if (string_match(tok, string)) { /* ALL or exact match */
+ return (YES);
+ } else if ((group = getgrnam(tok)) != 0) { /* try group membership */
+ if (item->user->pw_gid == group->gr_gid)
+ return (YES);
+ for (i = 0; group->gr_mem[i]; i++)
+ if (strcasecmp(string, group->gr_mem[i]) == 0)
+ return (YES);
+ }
+ return (NO);
+}
+
+/* from_match - match a host or tty against a list of tokens */
+
+static int from_match(char *tok, struct login_info *item)
+{
+ char *string = item->from;
+ int tok_len;
+ int str_len;
+
+ /*
+ * If a token has the magic value "ALL" the match always succeeds. Return
+ * YES if the token fully matches the string. If the token is a domain
+ * name, return YES if it matches the last fields of the string. If the
+ * token has the magic value "LOCAL", return YES if the string does not
+ * contain a "." character. If the token is a network number, return YES
+ * if it matches the head of the string.
+ */
+
+ if (tok[0] == '@') { /* netgroup */
+ return (netgroup_match(tok + 1, string, (char *) 0));
+ } else if (string_match(tok, string)) { /* ALL or exact match */
+ return (YES);
+ } else if (tok[0] == '.') { /* domain: match last fields */
+ if ((str_len = strlen(string)) > (tok_len = strlen(tok))
+ && strcasecmp(tok, string + str_len - tok_len) == 0)
+ return (YES);
+ } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */
+ if (strchr(string, '.') == 0)
+ return (YES);
+ } else if (tok[(tok_len = strlen(tok)) - 1] == '.' /* network */
+ && strncmp(tok, string, tok_len) == 0) {
+ return (YES);
+ }
+ return (NO);
+}
+
+/* string_match - match a string against one token */
+
+static int string_match(char *tok, char *string)
+{
+
+ /*
+ * If the token has the magic value "ALL" the match always succeeds.
+ * Otherwise, return YES if the token fully matches the string.
+ */
+
+ if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
+ return (YES);
+ } else if (strcasecmp(tok, string) == 0) { /* try exact match */
+ return (YES);
+ }
+ return (NO);
+}
diff --git a/crypto/heimdal/appl/login/login_locl.h b/crypto/heimdal/appl/login/login_locl.h
new file mode 100644
index 000000000000..2d2f7fda13f1
--- /dev/null
+++ b/crypto/heimdal/appl/login/login_locl.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: login_locl.h,v 1.17 1999/12/02 17:04:55 joda Exp $ */
+
+#ifndef __LOGIN_LOCL_H__
+#define __LOGIN_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <signal.h>
+#include <termios.h>
+#include <err.h>
+#include <pwd.h>
+#include <roken.h>
+#include <getarg.h>
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+#ifdef HAVE_UDB_H
+#include <udb.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_SYS_CATEGORY_H
+#include <sys/category.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+#ifdef KRB4
+#include <krb.h>
+#endif
+#ifdef KRB5
+#include <krb5.h>
+#endif
+#include <kafs.h>
+
+#ifndef _PATH_BSHELL
+#define _PATH_BSHELL "/bin/sh"
+#endif
+#ifndef _PATH_TTY
+#define _PATH_TTY "/dev/tty"
+#endif
+#ifndef _PATH_DEV
+#define _PATH_DEV "/dev/"
+#endif
+#ifndef _PATH_NOLOGIN
+#define _PATH_NOLOGIN "/etc/nologin"
+#endif
+#ifndef _PATH_WTMP
+#ifdef WTMP_FILE
+#define _PATH_WTMP WTMP_FILE
+#else
+#define _PATH_WTMP "/var/adm/wtmp"
+#endif
+#endif
+#ifndef _PATH_UTMP
+#ifdef UTMP_FILE
+#define _PATH_UTMP UTMP_FILE
+#else
+#define _PATH_UTMP "/var/adm/utmp"
+#endif
+#endif
+
+#ifndef _PATH_LOGACCESS
+#define _PATH_LOGACCESS "/etc/login.access"
+#endif /* _PATH_LOGACCESS */
+
+#ifndef _PATH_LOGIN_CONF
+#define _PATH_LOGIN_CONF "/etc/login.conf"
+#endif /* _PATH_LOGIN_CONF */
+
+struct spwd;
+
+#include "login_protos.h"
+
+#endif /* __LOGIN_LOCL_H__ */
diff --git a/crypto/heimdal/appl/login/login_protos.h b/crypto/heimdal/appl/login/login_protos.h
new file mode 100644
index 000000000000..173acc51cc3c
--- /dev/null
+++ b/crypto/heimdal/appl/login/login_protos.h
@@ -0,0 +1,67 @@
+/* This is a generated file */
+#ifndef __login_protos_h__
+#define __login_protos_h__
+
+#ifdef __STDC__
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+void
+check_shadow __P((
+ const struct passwd *pw,
+ const struct spwd *sp));
+
+char *
+clean_ttyname __P((char *tty));
+
+int
+do_osfc2_magic __P((uid_t uid));
+
+int
+login_access __P((
+ struct passwd *user,
+ char *from));
+
+char *
+login_conf_get_string __P((const char *str));
+
+char *
+make_id __P((char *tty));
+
+void
+prepare_utmp __P((
+ struct utmp *utmp,
+ char *tty,
+ const char *username,
+ const char *hostname));
+
+int
+read_string __P((
+ const char *prompt,
+ char *buf,
+ size_t len,
+ int echo));
+
+void
+stty_default __P((void));
+
+void
+utmp_login __P((
+ char *tty,
+ const char *username,
+ const char *hostname));
+
+int
+utmpx_login __P((
+ char *line,
+ const char *user,
+ const char *host));
+
+#endif /* __login_protos_h__ */
diff --git a/crypto/heimdal/appl/login/osfc2.c b/crypto/heimdal/appl/login/osfc2.c
new file mode 100644
index 000000000000..5d4d0877d505
--- /dev/null
+++ b/crypto/heimdal/appl/login/osfc2.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "login_locl.h"
+RCSID("$Id: osfc2.c,v 1.3 1999/12/02 17:04:56 joda Exp $");
+
+int
+do_osfc2_magic(uid_t uid)
+{
+#ifdef HAVE_OSFC2
+ struct es_passwd *epw;
+ char *argv[2];
+
+ /* fake */
+ argv[0] = (char*)__progname;
+ argv[1] = NULL;
+ set_auth_parameters(1, argv);
+
+ epw = getespwuid(uid);
+ if(epw == NULL) {
+ syslog(LOG_AUTHPRIV|LOG_NOTICE,
+ "getespwuid failed for %d", uid);
+ printf("Sorry.\n");
+ return 1;
+ }
+ /* We don't check for auto-retired, foo-retired,
+ bar-retired, or any other kind of retired accounts
+ here; neither do we check for time-locked accounts, or
+ any other kind of serious C2 mumbo-jumbo. We do,
+ however, call setluid, since failing to do so is not
+ very good (take my word for it). */
+
+ if(!epw->uflg->fg_uid) {
+ syslog(LOG_AUTHPRIV|LOG_NOTICE,
+ "attempted login by %s (has no uid)", epw->ufld->fd_name);
+ printf("Sorry.\n");
+ return 1;
+ }
+ setluid(epw->ufld->fd_uid);
+ if(getluid() != epw->ufld->fd_uid) {
+ syslog(LOG_AUTHPRIV|LOG_NOTICE,
+ "failed to set LUID for %s (%d)",
+ epw->ufld->fd_name, epw->ufld->fd_uid);
+ printf("Sorry.\n");
+ return 1;
+ }
+#endif /* HAVE_OSFC2 */
+ return 0;
+}
diff --git a/crypto/heimdal/appl/login/read_string.c b/crypto/heimdal/appl/login/read_string.c
new file mode 100644
index 000000000000..2c4b66b1f3aa
--- /dev/null
+++ b/crypto/heimdal/appl/login/read_string.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "login_locl.h"
+
+RCSID("$Id: read_string.c,v 1.3 1999/12/02 17:04:56 joda Exp $");
+
+static sig_atomic_t intr_flag;
+
+static void
+intr(int sig)
+{
+ intr_flag++;
+}
+
+int
+read_string(const char *prompt, char *buf, size_t len, int echo)
+{
+ struct sigaction sigs[47];
+ struct sigaction sa;
+ FILE *tty;
+ int ret = 0;
+ int of = 0;
+ int i;
+ int c;
+ char *p;
+
+ struct termios t_new, t_old;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = intr;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ for(i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++)
+ sigaction(i, &sa, &sigs[i]);
+
+ if((tty = fopen("/dev/tty", "r")) == NULL)
+ tty = stdin;
+
+ fprintf(stderr, "%s", prompt);
+ fflush(stderr);
+
+ if(echo == 0){
+ tcgetattr(fileno(tty), &t_old);
+ memcpy(&t_new, &t_old, sizeof(t_new));
+ t_new.c_lflag &= ~ECHO;
+ tcsetattr(fileno(tty), TCSANOW, &t_new);
+ }
+ intr_flag = 0;
+ p = buf;
+ while(intr_flag == 0){
+ c = getc(tty);
+ if(c == EOF){
+ if(!ferror(tty))
+ ret = 1;
+ break;
+ }
+ if(c == '\n')
+ break;
+ if(of == 0)
+ *p++ = c;
+ of = (p == buf + len);
+ }
+ if(of)
+ p--;
+ *p = 0;
+
+ if(echo == 0){
+ printf("\n");
+ tcsetattr(fileno(tty), TCSANOW, &t_old);
+ }
+
+ if(tty != stdin)
+ fclose(tty);
+
+ for(i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++)
+ sigaction(i, &sigs[i], NULL);
+
+ if(ret)
+ return -3;
+ if(intr_flag)
+ return -2;
+ if(of)
+ return -1;
+ return 0;
+}
+
+
+#if 0
+int main()
+{
+ char s[128];
+ int ret;
+ ret = read_string("foo: ", s, sizeof(s), 0);
+ printf("%d ->%s<-\n", ret, s);
+}
+#endif
diff --git a/crypto/heimdal/appl/login/shadow.c b/crypto/heimdal/appl/login/shadow.c
new file mode 100644
index 000000000000..0923831c3496
--- /dev/null
+++ b/crypto/heimdal/appl/login/shadow.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "login_locl.h"
+
+RCSID("$Id: shadow.c,v 1.5 1999/12/02 17:04:56 joda Exp $");
+
+#ifdef HAVE_SHADOW_H
+
+#ifndef _PATH_CHPASS
+#define _PATH_CHPASS "/usr/bin/passwd"
+#endif
+
+static int
+change_passwd(const struct passwd *who)
+{
+ int status;
+ pid_t pid;
+
+ switch (pid = fork()) {
+ case -1:
+ printf("fork /bin/passwd");
+ exit(1);
+ case 0:
+ execlp(_PATH_CHPASS, "passwd", who->pw_name, (char *) 0);
+ exit(1);
+ default:
+ waitpid(pid, &status, 0);
+ return (status);
+ }
+}
+
+void
+check_shadow(const struct passwd *pw, const struct spwd *sp)
+{
+ long today;
+
+ today = time(0)/(24L * 60 * 60);
+
+ if (sp == NULL)
+ return;
+
+ if (sp->sp_expire > 0) {
+ if (today >= sp->sp_expire) {
+ printf("Your account has expired.\n");
+ sleep(1);
+ exit(0);
+ } else if (sp->sp_expire - today < 14) {
+ printf("Your account will expire in %d days.\n",
+ (int)(sp->sp_expire - today));
+ }
+ }
+
+ if (sp->sp_max > 0) {
+ if (today >= (sp->sp_lstchg + sp->sp_max)) {
+ printf("Your password has expired. Choose a new one.\n");
+ change_passwd(pw);
+ } else if (sp->sp_warn > 0
+ && (today > (sp->sp_lstchg + sp->sp_max - sp->sp_warn))) {
+ printf("Your password will expire in %d days.\n",
+ (int)(sp->sp_lstchg + sp->sp_max - today));
+ }
+ }
+}
+#endif /* HAVE_SHADOW_H */
diff --git a/crypto/heimdal/appl/login/stty_default.c b/crypto/heimdal/appl/login/stty_default.c
new file mode 100644
index 000000000000..5e3856629514
--- /dev/null
+++ b/crypto/heimdal/appl/login/stty_default.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "login_locl.h"
+
+RCSID("$Id: stty_default.c,v 1.8 1999/12/02 17:04:56 joda Exp $");
+
+#include <termios.h>
+
+/* HP-UX 9.0 termios doesn't define these */
+#ifndef FLUSHO
+#define FLUSHO 0
+#endif
+
+#ifndef XTABS
+#define XTABS 0
+#endif
+
+#ifndef OXTABS
+#define OXTABS XTABS
+#endif
+
+/* Ultrix... */
+#ifndef ECHOPRT
+#define ECHOPRT 0
+#endif
+
+#ifndef ECHOCTL
+#define ECHOCTL 0
+#endif
+
+#ifndef ECHOKE
+#define ECHOKE 0
+#endif
+
+#ifndef IMAXBEL
+#define IMAXBEL 0
+#endif
+
+#define Ctl(x) ((x) ^ 0100)
+
+void
+stty_default(void)
+{
+ struct termios termios;
+
+ /*
+ * Finalize the terminal settings. Some systems default to 8 bits,
+ * others to 7, so we should leave that alone.
+ */
+ tcgetattr(0, &termios);
+
+ termios.c_iflag |= (BRKINT|IGNPAR|ICRNL|IXON|IMAXBEL);
+ termios.c_iflag &= ~IXANY;
+
+ termios.c_lflag |= (ISIG|IEXTEN|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE);
+ termios.c_lflag &= ~(ECHOPRT|TOSTOP|FLUSHO);
+
+ termios.c_oflag |= (OPOST|ONLCR);
+ termios.c_oflag &= ~OXTABS;
+
+ termios.c_cc[VINTR] = Ctl('C');
+ termios.c_cc[VERASE] = Ctl('H');
+ termios.c_cc[VKILL] = Ctl('U');
+ termios.c_cc[VEOF] = Ctl('D');
+
+ termios.c_cc[VSUSP] = Ctl('Z');
+
+ tcsetattr(0, TCSANOW, &termios);
+}
diff --git a/crypto/heimdal/appl/login/tty.c b/crypto/heimdal/appl/login/tty.c
new file mode 100644
index 000000000000..0ffea7249fd9
--- /dev/null
+++ b/crypto/heimdal/appl/login/tty.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "login_locl.h"
+
+RCSID("$Id: tty.c,v 1.4 1999/12/02 17:04:56 joda Exp $");
+
+/*
+ * Clean the tty name. Return a pointer to the cleaned version.
+ */
+
+char *
+clean_ttyname (char *tty)
+{
+ char *res = tty;
+
+ if (strncmp (res, _PATH_DEV, strlen(_PATH_DEV)) == 0)
+ res += strlen(_PATH_DEV);
+ if (strncmp (res, "pty/", 4) == 0)
+ res += 4;
+ if (strncmp (res, "ptym/", 5) == 0)
+ res += 5;
+ return res;
+}
+
+/*
+ * Generate a name usable as an `ut_id', typically without `tty'.
+ */
+
+char *
+make_id (char *tty)
+{
+ char *res = tty;
+
+ if (strncmp (res, "pts/", 4) == 0)
+ res += 4;
+ if (strncmp (res, "tty", 3) == 0)
+ res += 3;
+ return res;
+}
diff --git a/crypto/heimdal/appl/login/utmp_login.c b/crypto/heimdal/appl/login/utmp_login.c
new file mode 100644
index 000000000000..b584326b768b
--- /dev/null
+++ b/crypto/heimdal/appl/login/utmp_login.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "login_locl.h"
+
+RCSID("$Id: utmp_login.c,v 1.17 1999/12/02 17:04:56 joda Exp $");
+
+void
+prepare_utmp (struct utmp *utmp, char *tty,
+ const char *username, const char *hostname)
+{
+ char *ttyx = clean_ttyname (tty);
+
+ memset(utmp, 0, sizeof(*utmp));
+ utmp->ut_time = time(NULL);
+ strncpy(utmp->ut_line, ttyx, sizeof(utmp->ut_line));
+ strncpy(utmp->ut_name, username, sizeof(utmp->ut_name));
+
+# ifdef HAVE_STRUCT_UTMP_UT_USER
+ strncpy(utmp->ut_user, username, sizeof(utmp->ut_user));
+# endif
+
+# ifdef HAVE_STRUCT_UTMP_UT_ADDR
+ if (hostname[0]) {
+ struct hostent *he;
+ if ((he = gethostbyname(hostname)))
+ memcpy(&utmp->ut_addr, he->h_addr_list[0],
+ sizeof(utmp->ut_addr));
+ }
+# endif
+
+# ifdef HAVE_STRUCT_UTMP_UT_HOST
+ strncpy(utmp->ut_host, hostname, sizeof(utmp->ut_host));
+# endif
+
+# ifdef HAVE_STRUCT_UTMP_UT_TYPE
+ utmp->ut_type = USER_PROCESS;
+# endif
+
+# ifdef HAVE_STRUCT_UTMP_UT_PID
+ utmp->ut_pid = getpid();
+# endif
+
+# ifdef HAVE_STRUCT_UTMP_UT_ID
+ strncpy(utmp->ut_id, make_id(ttyx), sizeof(utmp->ut_id));
+# endif
+}
+
+#ifdef HAVE_UTMPX_H
+void utmp_login(char *tty, const char *username, const char *hostname)
+{
+ return;
+}
+#else
+
+/* update utmp and wtmp - the BSD way */
+
+void utmp_login(char *tty, const char *username, const char *hostname)
+{
+ struct utmp utmp;
+ int fd;
+
+ prepare_utmp (&utmp, tty, username, hostname);
+
+#ifdef HAVE_SETUTENT
+ utmpname(_PATH_UTMP);
+ setutent();
+ pututline(&utmp);
+ endutent();
+#else
+
+#ifdef HAVE_TTYSLOT
+ {
+ int ttyno;
+ ttyno = ttyslot();
+ if (ttyno > 0 && (fd = open(_PATH_UTMP, O_WRONLY, 0)) >= 0) {
+ lseek(fd, (long)(ttyno * sizeof(struct utmp)), SEEK_SET);
+ write(fd, &utmp, sizeof(struct utmp));
+ close(fd);
+ }
+ }
+#endif /* HAVE_TTYSLOT */
+#endif /* HAVE_SETUTENT */
+
+ if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
+ write(fd, &utmp, sizeof(struct utmp));
+ close(fd);
+ }
+}
+#endif /* !HAVE_UTMPX_H */
diff --git a/crypto/heimdal/appl/login/utmpx_login.c b/crypto/heimdal/appl/login/utmpx_login.c
new file mode 100644
index 000000000000..745d64c5822a
--- /dev/null
+++ b/crypto/heimdal/appl/login/utmpx_login.c
@@ -0,0 +1,89 @@
+/* Author: Wietse Venema <wietse@wzv.win.tue.nl> */
+
+#include "login_locl.h"
+
+RCSID("$Id: utmpx_login.c,v 1.24 1999/08/04 17:03:15 assar Exp $");
+
+/* utmpx_login - update utmp and wtmp after login */
+
+#ifndef HAVE_UTMPX_H
+int utmpx_login(char *line, const char *user, const char *host) { return 0; }
+#else
+
+static void
+utmpx_update(struct utmpx *ut, char *line, const char *user, const char *host)
+{
+ struct timeval tmp;
+ char *clean_tty = clean_ttyname(line);
+
+ strncpy(ut->ut_line, clean_tty, sizeof(ut->ut_line));
+#ifdef HAVE_STRUCT_UTMPX_UT_ID
+ strncpy(ut->ut_id, make_id(clean_tty), sizeof(ut->ut_id));
+#endif
+ strncpy(ut->ut_user, user, sizeof(ut->ut_user));
+ strncpy(ut->ut_host, host, sizeof(ut->ut_host));
+#ifdef HAVE_STRUCT_UTMPX_UT_SYSLEN
+ ut->ut_syslen = strlen(host) + 1;
+ if (ut->ut_syslen > sizeof(ut->ut_host))
+ ut->ut_syslen = sizeof(ut->ut_host);
+#endif
+ ut->ut_type = USER_PROCESS;
+ gettimeofday (&tmp, 0);
+ ut->ut_tv.tv_sec = tmp.tv_sec;
+ ut->ut_tv.tv_usec = tmp.tv_usec;
+ pututxline(ut);
+#ifdef WTMPX_FILE
+ updwtmpx(WTMPX_FILE, ut);
+#elif defined(WTMP_FILE)
+ {
+ struct utmp utmp;
+ int fd;
+
+ prepare_utmp (&utmp, line, user, host);
+ if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
+ write(fd, &utmp, sizeof(struct utmp));
+ close(fd);
+ }
+ }
+#endif
+}
+
+int
+utmpx_login(char *line, const char *user, const char *host)
+{
+ struct utmpx *ut, save_ut;
+ pid_t mypid = getpid();
+ int ret = (-1);
+
+ /*
+ * SYSV4 ttymon and login use tty port names with the "/dev/" prefix
+ * stripped off. Rlogind and telnetd, on the other hand, make utmpx
+ * entries with device names like /dev/pts/nnn. We therefore cannot use
+ * getutxline(). Return nonzero if no utmp entry was found with our own
+ * process ID for a login or user process.
+ */
+
+ while ((ut = getutxent())) {
+ /* Try to find a reusable entry */
+ if (ut->ut_pid == mypid
+ && ( ut->ut_type == INIT_PROCESS
+ || ut->ut_type == LOGIN_PROCESS
+ || ut->ut_type == USER_PROCESS)) {
+ save_ut = *ut;
+ utmpx_update(&save_ut, line, user, host);
+ ret = 0;
+ break;
+ }
+ }
+ if (ret == -1) {
+ /* Grow utmpx file by one record. */
+ struct utmpx newut;
+ memset(&newut, 0, sizeof(newut));
+ newut.ut_pid = mypid;
+ utmpx_update(&newut, line, user, host);
+ ret = 0;
+ }
+ endutxent();
+ return (ret);
+}
+#endif /* HAVE_UTMPX_H */
diff --git a/crypto/heimdal/appl/push/ChangeLog b/crypto/heimdal/appl/push/ChangeLog
new file mode 100644
index 000000000000..f01309057bf7
--- /dev/null
+++ b/crypto/heimdal/appl/push/ChangeLog
@@ -0,0 +1,150 @@
+1999-12-28 Assar Westerlund <assar@sics.se>
+
+ * push.c (main): call k_getportbyname with port number in
+ network-byte-order
+
+1999-12-14 Assar Westerlund <assar@sics.se>
+
+ * push.c (do_connect): remove bogus local block variable
+
+1999-12-05 Assar Westerlund <assar@sics.se>
+
+ * push.c (do_connect): use `getaddrinfo'
+ * push.c: add --count (print number of messages and bytes at
+ beginning)
+
+1999-11-13 Assar Westerlund <assar@sics.se>
+
+ * push.c: make `-v' a arg_counter
+
+1999-11-02 Assar Westerlund <assar@sics.se>
+
+ * push.c (main): redo the v4/v5 selection for consistency. -4 ->
+ try only v4 -5 -> try only v5 none, -45 -> try v5, v4
+
+1999-08-19 Assar Westerlund <assar@sics.se>
+
+ * push.c (doit): remember to step over the error message when we
+ discover that XDELE is not supported
+
+1999-08-12 Johan Danielsson <joda@pdc.kth.se>
+
+ * push.c: use XDELE
+
+1999-08-05 Assar Westerlund <assar@sics.se>
+
+ * push.c (do_connect): v6-ify
+
+1999-06-15 Assar Westerlund <assar@sics.se>
+
+ * push.c: get_default_username and the resulting const propagation
+
+1999-05-21 Assar Westerlund <assar@sics.se>
+
+ * push.c (parse_pobox): try $USERNAME
+
+1999-05-11 Assar Westerlund <assar@sics.se>
+
+ * push.c (do_v5): remove unused and non-working code
+
+1999-05-10 Assar Westerlund <assar@sics.se>
+
+ * push.c (do_v5): call krb5_sendauth with ccache == NULL
+
+Wed Apr 7 23:40:00 1999 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: fix names of hesiod variables
+
+Wed Mar 24 04:37:04 1999 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (pfrom): fix typo
+
+ * push.c (get_pobox): try to handle old and new hesiod APIs
+
+Mon Mar 22 22:19:40 1999 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: hesoid -> hesiod
+
+Sun Mar 21 18:02:10 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: bindir -> libexecdir
+
+Sat Mar 20 00:12:26 1999 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: LDADD: add missing backslash
+
+Thu Mar 18 15:28:35 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: clean pfrom
+
+ * Makefile.am: include Makefile.am.common
+
+Mon Mar 15 18:26:16 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * push.c: strncasecmp headers
+
+Mon Feb 15 22:22:09 1999 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (pfrom): use libexecdir
+
+ * Makefile.am: build and install pfrom
+
+ * push.c (do_connect): init `s'
+ (pop_state): spell-check enums
+
+Tue Nov 24 23:20:54 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: build and install pfrom
+
+ * pfrom.in: bindir -> libexecdir
+
+Sun Nov 22 15:33:52 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * push.c: eliminate some warnings
+
+Sun Nov 22 10:34:54 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (WFLAGS): set
+
+Thu Nov 19 01:17:33 1998 Assar Westerlund <assar@sics.se>
+
+ * push_locl.h: add <hesiod.h>
+
+ * Makefile.am, Makefile.in: link and include hesiod
+
+ * push.c (get_pobox): new function. add hesiod support.
+
+1998-11-07 Assar Westerlund <assar@sics.se>
+
+ * push.8: updated
+
+ * push.c: --from implementation from <lha@stacken.kth.se>
+
+Fri Jul 10 01:14:45 1998 Assar Westerlund <assar@sics.se>
+
+ * push.c (net_{read,write}): remove
+
+Wed Jun 24 14:41:41 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * push.c: allow `po:user@host' mailbox syntax
+
+Tue Jun 2 17:35:06 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * push.c: quote '^From ' properly
+
+Mon May 25 05:22:47 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (clean): PROGS -> PROGRAMS
+
+Sun Apr 26 11:42:13 1998 Assar Westerlund <assar@sics.se>
+
+ * push.c (main): better default for v4 and v5
+
+ * push.c (main): init context correctly
+
+ * push.c: should work with krb4
+
+ * push_locl.h: krb4 compat
+
+ * Makefile.in: new file
+
diff --git a/crypto/heimdal/appl/push/Makefile.am b/crypto/heimdal/appl/push/Makefile.am
new file mode 100644
index 000000000000..07ecd0ad9802
--- /dev/null
+++ b/crypto/heimdal/appl/push/Makefile.am
@@ -0,0 +1,27 @@
+# $Id: Makefile.am,v 1.15 1999/04/09 18:29:48 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4) $(INCLUDE_hesiod)
+
+bin_SCRIPTS = pfrom
+
+libexec_PROGRAMS = push
+
+push_SOURCES = push.c push_locl.h
+
+pfrom: pfrom.in
+ sed -e "s!%libexecdir%!$(libexecdir)!" $(srcdir)/pfrom.in > $@
+ chmod +x $@
+
+man_MANS = push.8
+
+CLEANFILES = pfrom
+
+EXTRA_DIST = pfrom.in $(man_MANS)
+
+LDADD = $(LIB_krb5) \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(LIB_roken) \
+ $(LIB_hesiod)
diff --git a/crypto/heimdal/appl/push/Makefile.in b/crypto/heimdal/appl/push/Makefile.in
new file mode 100644
index 000000000000..6e9fef1c2190
--- /dev/null
+++ b/crypto/heimdal/appl/push/Makefile.in
@@ -0,0 +1,713 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.15 1999/04/09 18:29:48 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4) $(INCLUDE_hesiod)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+bin_SCRIPTS = pfrom
+
+libexec_PROGRAMS = push
+
+push_SOURCES = push.c push_locl.h
+
+man_MANS = push.8
+
+CLEANFILES = pfrom
+
+EXTRA_DIST = pfrom.in $(man_MANS)
+
+LDADD = $(LIB_krb5) $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(LIB_roken) $(LIB_hesiod)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+libexec_PROGRAMS = push$(EXEEXT)
+PROGRAMS = $(libexec_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+push_OBJECTS = push.$(OBJEXT)
+push_LDADD = $(LDADD)
+@KRB5_TRUE@push_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB5_FALSE@push_DEPENDENCIES = $(top_builddir)/lib/des/libdes.la
+push_LDFLAGS =
+SCRIPTS = $(bin_SCRIPTS)
+
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man8dir = $(mandir)/man8
+MANS = $(man_MANS)
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(push_SOURCES)
+OBJECTS = $(push_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/push/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libexecPROGRAMS:
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+
+distclean-libexecPROGRAMS:
+
+maintainer-clean-libexecPROGRAMS:
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+push$(EXEEXT): $(push_OBJECTS) $(push_DEPENDENCIES)
+ @rm -f push$(EXEEXT)
+ $(LINK) $(push_LDFLAGS) $(push_OBJECTS) $(push_LDADD) $(LIBS)
+
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ else if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ else :; fi; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_SCRIPTS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ done
+
+install-man8:
+ $(mkinstalldirs) $(DESTDIR)$(man8dir)
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
+ done
+
+uninstall-man8:
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man8dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man8
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man8
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/push
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libexecPROGRAMS install-binSCRIPTS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-man install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libexecPROGRAMS uninstall-binSCRIPTS \
+ uninstall-man
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir) $(DESTDIR)$(bindir) \
+ $(DESTDIR)$(mandir)/man8
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libexecPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libexecPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libexecPROGRAMS distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libexecPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libexecPROGRAMS distclean-libexecPROGRAMS \
+clean-libexecPROGRAMS maintainer-clean-libexecPROGRAMS \
+uninstall-libexecPROGRAMS install-libexecPROGRAMS mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool uninstall-binSCRIPTS install-binSCRIPTS \
+install-man8 uninstall-man8 install-man uninstall-man tags \
+mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \
+distdir info-am info dvi-am dvi check-local check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-local install-data-am install-data install-am install \
+uninstall-am uninstall all-local all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+pfrom: pfrom.in
+ sed -e "s!%libexecdir%!$(libexecdir)!" $(srcdir)/pfrom.in > $@
+ chmod +x $@
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/push/pfrom.in b/crypto/heimdal/appl/push/pfrom.in
new file mode 100644
index 000000000000..6adf4f0f7971
--- /dev/null
+++ b/crypto/heimdal/appl/push/pfrom.in
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $Id: pfrom.in,v 1.2 1998/11/24 13:25:47 assar Exp $
+libexecdir=%libexecdir%
+PATH=$libexecdir:$PATH
+export PATH
+push --from $*
diff --git a/crypto/heimdal/appl/push/push.8 b/crypto/heimdal/appl/push/push.8
new file mode 100644
index 000000000000..d8f440192af0
--- /dev/null
+++ b/crypto/heimdal/appl/push/push.8
@@ -0,0 +1,138 @@
+.\" $Id: push.8,v 1.4 1999/12/05 13:00:56 assar Exp $
+.\"
+.Dd May 31, 1998
+.Dt PUSH 8
+.Os HEIMDAL
+.Sh NAME
+.Nm push
+.Nd
+fetch mail via POP
+.Sh SYNOPSIS
+.Nm
+.Op Fl 4 | Fl -krb4
+.Op Fl 5 | Fl -krb5
+.Op Fl v | Fl -verbose
+.Op Fl f | Fl -fork
+.Op Fl l | -leave
+.Op Fl -from
+.Op Fl c | -count
+.Op Fl -header
+.Oo Fl p Ar port-spec \*(Ba Xo
+.Fl -port= Ns Ar port-spec Oc
+.Xc
+.Ar po-box
+.Pa filename
+.Sh DESCRIPTION
+.Nm
+retrieves mail from the post office box
+.Ar po-box ,
+and stores the mail in mbox format in
+.Pa filename .
+The
+.Ar po-box
+can have any of the following formats:
+.Bl -hang -compact -offset indent
+.It Ql hostname:username
+.It Ql po:hostname:username
+.It Ql username@hostname
+.It Ql po:username@hostname
+.It Ql hostname
+.It Ql po:username
+.El
+
+If no username is specified,
+.Nm
+assumes that it's the same as on the local machine;
+.Ar hostname
+defaults to the value of the
+.Ev MAILHOST
+environment variable.
+
+Supported options:
+.Bl -tag -width Ds
+.It Xo
+.Fl 4 Ns ,
+.Fl -krb4
+.Xc
+use Kerberos 4 (if compiled with support for Kerberos 4)
+.It Xo
+.Fl 5 Ns ,
+.Fl -krb5
+.Xc
+use Kerberos 5 (if compiled with support for Kerberos 5)
+.It Xo
+.Fl f Ns ,
+.Fl -fork
+.Xc
+fork before starting to delete messages
+.It Xo
+.Fl l Ns ,
+.Fl -leave
+.Xc
+don't delete fetched mail
+.It Xo
+.Fl -from
+.Xc
+behave like from.
+.It Xo
+.Fl c Ns ,
+.Fl -count
+.Xc
+first print how many messages and bytes there are.
+.It Xo
+.Fl -header
+.Xc
+which header from should print.
+.It Xo
+.Fl p Ar port-spec Ns ,
+.Fl -port= Ns Ar port-spec
+.Xc
+use this port instead of the default
+.Ql kpop
+or
+.Ql 1109 .
+.El
+
+The default is to first try Kerberos 5 authentication and then, if
+that fails, Kerberos 4.
+.Sh ENVIRONMENT
+
+.Bl -tag -width Ds
+.It Ev MAILHOST
+points to the post office, if no other hostname is specified.
+.El
+.\".Sh FILES
+.Sh EXAMPLES
+.Bd -literal -offset indent
+$ push cornfield:roosta ~/.gnus-crash-box
+.Ed
+
+tries to fetch mail for the user
+.Ar roosta
+from the post office at
+.Dq cornfield ,
+and stores the mail in
+.Pa ~/.gnus-crash-box
+(you are using Gnus, aren't you?)
+.Bd -literal -offset indent
+$ push --from -5 havregryn
+.Ed
+
+tries to fetch
+.Nm From:
+lines for current user at post office
+.Dq havregryn
+using Kerberos 5.
+.\".Sh DIAGNOSTICS
+.Sh SEE ALSO
+.Xr movemail 8 ,
+.Xr popper 8 ,
+.Xr from 1
+.\".Sh STANDARDS
+.Sh HISTORY
+.Nm
+was written while waiting for
+.Nm movemail
+to finish getting the mail.
+.\".Sh AUTHORS
+.\".Sh BUGS
diff --git a/crypto/heimdal/appl/push/push.c b/crypto/heimdal/appl/push/push.c
new file mode 100644
index 000000000000..1689a83f0b5f
--- /dev/null
+++ b/crypto/heimdal/appl/push/push.c
@@ -0,0 +1,790 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "push_locl.h"
+RCSID("$Id: push.c,v 1.38 1999/12/28 03:46:06 assar Exp $");
+
+#ifdef KRB4
+static int use_v4 = -1;
+#endif
+
+#ifdef KRB5
+static int use_v5 = -1;
+static krb5_context context;
+#endif
+
+static char *port_str;
+static int verbose_level;
+static int do_fork;
+static int do_leave;
+static int do_version;
+static int do_help;
+static int do_from;
+static int do_count;
+static char *header_str;
+
+struct getargs args[] = {
+#ifdef KRB4
+ { "krb4", '4', arg_flag, &use_v4, "Use Kerberos V4",
+ NULL },
+#endif
+#ifdef KRB5
+ { "krb5", '5', arg_flag, &use_v5, "Use Kerberos V5",
+ NULL },
+#endif
+ { "verbose",'v', arg_counter, &verbose_level, "Verbose",
+ NULL },
+ { "fork", 'f', arg_flag, &do_fork, "Fork deleting proc",
+ NULL },
+ { "leave", 'l', arg_flag, &do_leave, "Leave mail on server",
+ NULL },
+ { "port", 'p', arg_string, &port_str, "Use this port",
+ "number-or-service" },
+ { "from", 0, arg_flag, &do_from, "Behave like from",
+ NULL },
+ { "header", 0, arg_string, &header_str, "Header string to print", NULL },
+ { "count", 'c', arg_flag, &do_count, "Print number of messages", NULL},
+ { "version", 0, arg_flag, &do_version, "Print version",
+ NULL },
+ { "help", 0, arg_flag, &do_help, NULL,
+ NULL }
+
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args) / sizeof(args[0]),
+ NULL,
+ "[[{po:username[@hostname] | hostname[:username]}] ...]"
+ "filename");
+ exit (ret);
+}
+
+static int
+do_connect (const char *hostname, int port, int nodelay)
+{
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ int s;
+ char portstr[NI_MAXSERV];
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(port));
+
+ error = getaddrinfo (hostname, portstr, &hints, &ai);
+ if (error)
+ errx (1, "getaddrinfo(%s): %s", hostname, gai_strerror(error));
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0)
+ continue;
+ if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
+ warn ("connect(%s)", hostname);
+ close (s);
+ continue;
+ }
+ break;
+ }
+ freeaddrinfo (ai);
+ if (a == NULL) {
+ warnx ("failed to contact %s", hostname);
+ return -1;
+ }
+
+ if(setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
+ (void *)&nodelay, sizeof(nodelay)) < 0)
+ err (1, "setsockopt TCP_NODELAY");
+ return s;
+}
+
+typedef enum { INIT = 0, GREET, USER, PASS, STAT, RETR, TOP,
+ DELE, XDELE, QUIT} pop_state;
+
+#define PUSH_BUFSIZ 65536
+
+#define STEP 16
+
+struct write_state {
+ struct iovec *iovecs;
+ size_t niovecs, maxiovecs, allociovecs;
+ int fd;
+};
+
+static void
+write_state_init (struct write_state *w, int fd)
+{
+#ifdef UIO_MAXIOV
+ w->maxiovecs = UIO_MAXIOV;
+#else
+ w->maxiovecs = 16;
+#endif
+ w->allociovecs = min(STEP, w->maxiovecs);
+ w->niovecs = 0;
+ w->iovecs = malloc(w->allociovecs * sizeof(*w->iovecs));
+ if (w->iovecs == NULL)
+ err (1, "malloc");
+ w->fd = fd;
+}
+
+static void
+write_state_add (struct write_state *w, void *v, size_t len)
+{
+ if(w->niovecs == w->allociovecs) {
+ if(w->niovecs == w->maxiovecs) {
+ if(writev (w->fd, w->iovecs, w->niovecs) < 0)
+ err(1, "writev");
+ w->niovecs = 0;
+ } else {
+ w->allociovecs = min(w->allociovecs + STEP, w->maxiovecs);
+ w->iovecs = realloc (w->iovecs,
+ w->allociovecs * sizeof(*w->iovecs));
+ if (w->iovecs == NULL)
+ errx (1, "realloc");
+ }
+ }
+ w->iovecs[w->niovecs].iov_base = v;
+ w->iovecs[w->niovecs].iov_len = len;
+ ++w->niovecs;
+}
+
+static void
+write_state_flush (struct write_state *w)
+{
+ if (w->niovecs) {
+ if (writev (w->fd, w->iovecs, w->niovecs) < 0)
+ err (1, "writev");
+ w->niovecs = 0;
+ }
+}
+
+static void
+write_state_destroy (struct write_state *w)
+{
+ free (w->iovecs);
+}
+
+static int
+doit(int s,
+ const char *host,
+ const char *user,
+ const char *outfilename,
+ const char *header_str,
+ int leavep,
+ int verbose,
+ int forkp)
+{
+ int ret;
+ char out_buf[PUSH_BUFSIZ];
+ size_t out_len = 0;
+ char in_buf[PUSH_BUFSIZ + 1]; /* sentinel */
+ size_t in_len = 0;
+ char *in_ptr = in_buf;
+ pop_state state = INIT;
+ unsigned count, bytes;
+ unsigned asked_for = 0, retrieved = 0, asked_deleted = 0, deleted = 0;
+ unsigned sent_xdele = 0;
+ int out_fd;
+ char from_line[128];
+ size_t from_line_length;
+ time_t now;
+ struct write_state write_state;
+
+ if (do_from) {
+ out_fd = -1;
+ if (verbose)
+ fprintf (stderr, "%s@%s\n", user, host);
+ } else {
+ out_fd = open(outfilename, O_WRONLY | O_APPEND | O_CREAT, 0666);
+ if (out_fd < 0)
+ err (1, "open %s", outfilename);
+ if (verbose)
+ fprintf (stderr, "%s@%s -> %s\n", user, host, outfilename);
+ }
+
+ now = time(NULL);
+ from_line_length = snprintf (from_line, sizeof(from_line),
+ "From %s %s", "push", ctime(&now));
+
+ out_len = snprintf (out_buf, sizeof(out_buf),
+ "USER %s\r\nPASS hej\r\nSTAT\r\n",
+ user);
+ if (net_write (s, out_buf, out_len) != out_len)
+ err (1, "write");
+ if (verbose > 1)
+ write (STDERR_FILENO, out_buf, out_len);
+
+ if (!do_from)
+ write_state_init (&write_state, out_fd);
+
+ while(state != QUIT) {
+ fd_set readset, writeset;
+
+ FD_ZERO(&readset);
+ FD_ZERO(&writeset);
+ FD_SET(s,&readset);
+ if (((state == STAT || state == RETR || state == TOP)
+ && asked_for < count)
+ || (state == XDELE && !sent_xdele)
+ || (state == DELE && asked_deleted < count))
+ FD_SET(s,&writeset);
+ ret = select (s + 1, &readset, &writeset, NULL, NULL);
+ if (ret < 0) {
+ if (errno == EAGAIN)
+ continue;
+ else
+ err (1, "select");
+ }
+
+ if (FD_ISSET(s, &readset)) {
+ char *beg, *p;
+ size_t rem;
+ int blank_line = 0;
+
+ ret = read (s, in_ptr, sizeof(in_buf) - in_len - 1);
+ if (ret < 0)
+ err (1, "read");
+ else if (ret == 0)
+ errx (1, "EOF during read");
+
+ in_len += ret;
+ in_ptr += ret;
+ *in_ptr = '\0';
+
+ beg = in_buf;
+ rem = in_len;
+ while(rem > 1
+ && (p = strstr(beg, "\r\n")) != NULL) {
+ if (state == TOP) {
+ char *copy = beg;
+
+ if (strncasecmp(copy,
+ header_str,
+ min(p - copy + 1, strlen(header_str))) == 0) {
+ fprintf (stdout, "%.*s\n", (int)(p - copy), copy);
+ }
+ if (beg[0] == '.' && beg[1] == '\r' && beg[2] == '\n') {
+ state = STAT;
+ if (++retrieved == count) {
+ state = QUIT;
+ net_write (s, "QUIT\r\n", 6);
+ if (verbose > 1)
+ net_write (STDERR_FILENO, "QUIT\r\n", 6);
+ }
+ }
+ rem -= p - beg + 2;
+ beg = p + 2;
+ } else if (state == RETR) {
+ char *copy = beg;
+ if (beg[0] == '.') {
+ if (beg[1] == '\r' && beg[2] == '\n') {
+ if(!blank_line)
+ write_state_add(&write_state, "\n", 1);
+ state = STAT;
+ rem -= p - beg + 2;
+ beg = p + 2;
+ if (++retrieved == count) {
+ write_state_flush (&write_state);
+ if (fsync (out_fd) < 0)
+ err (1, "fsync");
+ close(out_fd);
+ if (leavep) {
+ state = QUIT;
+ net_write (s, "QUIT\r\n", 6);
+ if (verbose > 1)
+ net_write (STDERR_FILENO, "QUIT\r\n", 6);
+ } else {
+ if (forkp) {
+ pid_t pid;
+
+ pid = fork();
+ if (pid < 0)
+ warn ("fork");
+ else if(pid != 0) {
+ if(verbose)
+ fprintf (stderr,
+ "(exiting)");
+ return 0;
+ }
+ }
+
+ state = XDELE;
+ if (verbose)
+ fprintf (stderr, "deleting... ");
+ }
+ }
+ continue;
+ } else
+ ++copy;
+ }
+ *p = '\n';
+ if(blank_line &&
+ strncmp(copy, "From ", min(p - copy + 1, 5)) == 0)
+ write_state_add(&write_state, ">", 1);
+ write_state_add(&write_state, copy, p - copy + 1);
+ blank_line = (*copy == '\n');
+ rem -= p - beg + 2;
+ beg = p + 2;
+ } else if (rem >= 3 && strncmp (beg, "+OK", 3) == 0) {
+ if (state == STAT) {
+ if (!do_from)
+ write_state_add(&write_state,
+ from_line, from_line_length);
+ blank_line = 0;
+ if (do_from)
+ state = TOP;
+ else
+ state = RETR;
+ } else if (state == XDELE) {
+ state = QUIT;
+ net_write (s, "QUIT\r\n", 6);
+ if (verbose > 1)
+ net_write (STDERR_FILENO, "QUIT\r\n", 6);
+ break;
+ } else if (state == DELE) {
+ if (++deleted == count) {
+ state = QUIT;
+ net_write (s, "QUIT\r\n", 6);
+ if (verbose > 1)
+ net_write (STDERR_FILENO, "QUIT\r\n", 6);
+ break;
+ }
+ } else if (++state == STAT) {
+ if(sscanf (beg + 4, "%u %u", &count, &bytes) != 2)
+ errx(1, "Bad STAT-line: %.*s", (int)(p - beg), beg);
+ if (verbose) {
+ fprintf (stderr, "%u message(s) (%u bytes). "
+ "fetching... ",
+ count, bytes);
+ if (do_from)
+ fprintf (stderr, "\n");
+ } else if (do_count) {
+ fprintf (stderr, "%u message(s) (%u bytes).\n",
+ count, bytes);
+ }
+ if (count == 0) {
+ state = QUIT;
+ net_write (s, "QUIT\r\n", 6);
+ if (verbose > 1)
+ net_write (STDERR_FILENO, "QUIT\r\n", 6);
+ break;
+ }
+ }
+
+ rem -= p - beg + 2;
+ beg = p + 2;
+ } else {
+ if(state == XDELE) {
+ state = DELE;
+ rem -= p - beg + 2;
+ beg = p + 2;
+ } else
+ errx (1, "Bad response: %.*s", (int)(p - beg), beg);
+ }
+ }
+ if (!do_from)
+ write_state_flush (&write_state);
+
+ memmove (in_buf, beg, rem);
+ in_len = rem;
+ in_ptr = in_buf + rem;
+ }
+ if (FD_ISSET(s, &writeset)) {
+ if ((state == STAT && !do_from) || state == RETR)
+ out_len = snprintf (out_buf, sizeof(out_buf),
+ "RETR %u\r\n", ++asked_for);
+ else if ((state == STAT && do_from) || state == TOP)
+ out_len = snprintf (out_buf, sizeof(out_buf),
+ "TOP %u 0\r\n", ++asked_for);
+ else if(state == XDELE) {
+ out_len = snprintf(out_buf, sizeof(out_buf),
+ "XDELE %u %u\r\n", 1, count);
+ sent_xdele++;
+ }
+ else if(state == DELE)
+ out_len = snprintf (out_buf, sizeof(out_buf),
+ "DELE %u\r\n", ++asked_deleted);
+ if (net_write (s, out_buf, out_len) != out_len)
+ err (1, "write");
+ if (verbose > 1)
+ write (STDERR_FILENO, out_buf, out_len);
+ }
+ }
+ if (verbose)
+ fprintf (stderr, "Done\n");
+ if (!do_from)
+ write_state_destroy (&write_state);
+ return 0;
+}
+
+#ifdef KRB5
+static int
+do_v5 (const char *host,
+ int port,
+ const char *user,
+ const char *filename,
+ const char *header_str,
+ int leavep,
+ int verbose,
+ int forkp)
+{
+ krb5_error_code ret;
+ krb5_auth_context auth_context = NULL;
+ krb5_principal server;
+ int s;
+
+ s = do_connect (host, port, 1);
+ if (s < 0)
+ return 1;
+
+ ret = krb5_sname_to_principal (context,
+ host,
+ "pop",
+ KRB5_NT_SRV_HST,
+ &server);
+ if (ret) {
+ warnx ("krb5_sname_to_principal: %s",
+ krb5_get_err_text (context, ret));
+ return 1;
+ }
+
+ ret = krb5_sendauth (context,
+ &auth_context,
+ &s,
+ "KPOPV1.0",
+ NULL,
+ server,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ krb5_free_principal (context, server);
+ if (ret) {
+ warnx ("krb5_sendauth: %s",
+ krb5_get_err_text (context, ret));
+ return 1;
+ }
+ return doit (s, host, user, filename, header_str, leavep, verbose, forkp);
+}
+#endif
+
+#ifdef KRB4
+static int
+do_v4 (const char *host,
+ int port,
+ const char *user,
+ const char *filename,
+ const char *header_str,
+ int leavep,
+ int verbose,
+ int forkp)
+{
+ KTEXT_ST ticket;
+ MSG_DAT msg_data;
+ CREDENTIALS cred;
+ des_key_schedule sched;
+ int s;
+ int ret;
+
+ s = do_connect (host, port, 1);
+ if (s < 0)
+ return 1;
+ ret = krb_sendauth(0,
+ s,
+ &ticket,
+ "pop",
+ (char *)host,
+ krb_realmofhost(host),
+ getpid(),
+ &msg_data,
+ &cred,
+ sched,
+ NULL,
+ NULL,
+ "KPOPV0.1");
+ if(ret) {
+ warnx("krb_sendauth: %s", krb_get_err_text(ret));
+ return 1;
+ }
+ return doit (s, host, user, filename, header_str, leavep, verbose, forkp);
+}
+#endif /* KRB4 */
+
+#ifdef HESIOD
+
+#ifdef HESIOD_INTERFACES
+
+static char *
+hesiod_get_pobox (const char **user)
+{
+ void *context;
+ struct hesiod_postoffice *hpo;
+ char *ret = NULL;
+
+ if(hesiod_init (&context) != 0)
+ err (1, "hesiod_init");
+
+ hpo = hesiod_getmailhost (context, *user);
+ if (hpo == NULL) {
+ warn ("hesiod_getmailhost %s", *user);
+ } else {
+ if (strcasecmp(hpo->hesiod_po_type, "pop") != 0)
+ errx (1, "Unsupported po type %s", hpo->hesiod_po_type);
+
+ ret = strdup(hpo->hesiod_po_host);
+ if(ret == NULL)
+ errx (1, "strdup: out of memory");
+ *user = strdup(hpo->hesiod_po_name);
+ if (*user == NULL)
+ errx (1, "strdup: out of memory");
+ hesiod_free_postoffice (context, hpo);
+ }
+ hesiod_end (context);
+ return ret;
+}
+
+#else /* !HESIOD_INTERFACES */
+
+static char *
+hesiod_get_pobox (const char **user)
+{
+ char *ret = NULL;
+ struct hes_postoffice *hpo;
+
+ hpo = hes_getmailhost (*user);
+ if (hpo == NULL) {
+ warn ("hes_getmailhost %s", *user);
+ } else {
+ if (strcasecmp(hpo->po_type, "pop") != 0)
+ errx (1, "Unsupported po type %s", hpo->po_type);
+
+ ret = strdup(hpo->po_host);
+ if(ret == NULL)
+ errx (1, "strdup: out of memory");
+ *user = strdup(hpo->po_name);
+ if (*user == NULL)
+ errx (1, "strdup: out of memory");
+ }
+ return ret;
+}
+
+#endif /* HESIOD_INTERFACES */
+
+#endif /* HESIOD */
+
+static char *
+get_pobox (const char **user)
+{
+ char *ret = NULL;
+
+#ifdef HESIOD
+ ret = hesiod_get_pobox (user);
+#endif
+
+ if (ret == NULL)
+ ret = getenv("MAILHOST");
+ if (ret == NULL)
+ errx (1, "MAILHOST not set");
+ return ret;
+}
+
+static void
+parse_pobox (char *a0, const char **host, const char **user)
+{
+ const char *h, *u;
+ char *p;
+ int po = 0;
+
+ if (a0 == NULL) {
+
+ *user = getenv ("USERNAME");
+ if (*user == NULL) {
+ struct passwd *pwd = getpwuid (getuid ());
+
+ if (pwd == NULL)
+ errx (1, "Who are you?");
+ *user = strdup (pwd->pw_name);
+ if (*user == NULL)
+ errx (1, "strdup: out of memory");
+ }
+ *host = get_pobox (user);
+ return;
+ }
+
+ /* if the specification starts with po:, remember this information */
+ if(strncmp(a0, "po:", 3) == 0) {
+ a0 += 3;
+ po++;
+ }
+ /* if there is an `@', the hostname is after it, otherwise at the
+ beginning of the string */
+ p = strchr(a0, '@');
+ if(p != NULL) {
+ *p++ = '\0';
+ h = p;
+ } else {
+ h = a0;
+ }
+ /* if there is a `:', the username comes before it, otherwise at
+ the beginning of the string */
+ p = strchr(a0, ':');
+ if(p != NULL) {
+ *p++ = '\0';
+ u = p;
+ } else {
+ u = a0;
+ }
+ if(h == u) {
+ /* some inconsistent compatibility with various mailers */
+ if(po) {
+ h = get_pobox (&u);
+ } else {
+ u = get_default_username ();
+ if (u == NULL)
+ errx (1, "Who are you?");
+ }
+ }
+ *host = h;
+ *user = u;
+}
+
+int
+main(int argc, char **argv)
+{
+ int port = 0;
+ int optind = 0;
+ int ret = 1;
+ const char *host, *user, *filename = NULL;
+ char *pobox = NULL;
+
+ set_progname (argv[0]);
+
+#ifdef KRB5
+ krb5_init_context (&context);
+#endif
+
+ if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
+ &optind))
+ usage (1);
+
+ argc -= optind;
+ argv += optind;
+
+#if defined(KRB4) && defined(KRB5)
+ if(use_v4 == -1 && use_v5 == 1)
+ use_v4 = 0;
+ if(use_v5 == -1 && use_v4 == 1)
+ use_v5 = 0;
+#endif
+
+ if (do_help)
+ usage (0);
+
+ if (do_version) {
+ print_version(NULL);
+ return 0;
+ }
+
+ if (do_from && header_str == NULL)
+ header_str = "From:";
+ else if (header_str != NULL)
+ do_from = 1;
+
+ if (do_from) {
+ if (argc == 0)
+ pobox = NULL;
+ else if (argc == 1)
+ pobox = argv[0];
+ else
+ usage (1);
+ } else {
+ if (argc == 1) {
+ filename = argv[0];
+ pobox = NULL;
+ } else if (argc == 2) {
+ filename = argv[1];
+ pobox = argv[0];
+ } else
+ usage (1);
+ }
+
+ if (port_str) {
+ struct servent *s = roken_getservbyname (port_str, "tcp");
+
+ if (s)
+ port = s->s_port;
+ else {
+ char *ptr;
+
+ port = strtol (port_str, &ptr, 10);
+ if (port == 0 && ptr == port_str)
+ errx (1, "Bad port `%s'", port_str);
+ port = htons(port);
+ }
+ }
+ if (port == 0) {
+#ifdef KRB5
+ port = krb5_getportbyname (context, "kpop", "tcp", 1109);
+#elif defined(KRB4)
+ port = k_getportbyname ("kpop", "tcp", htons(1109));
+#else
+#error must define KRB4 or KRB5
+#endif
+ }
+
+ parse_pobox (pobox, &host, &user);
+
+#ifdef KRB5
+ if (ret && use_v5) {
+ ret = do_v5 (host, port, user, filename, header_str,
+ do_leave, verbose_level, do_fork);
+ }
+#endif
+
+#ifdef KRB4
+ if (ret && use_v4) {
+ ret = do_v4 (host, port, user, filename, header_str,
+ do_leave, verbose_level, do_fork);
+ }
+#endif /* KRB4 */
+ return ret;
+}
diff --git a/crypto/heimdal/appl/push/push_locl.h b/crypto/heimdal/appl/push/push_locl.h
new file mode 100644
index 000000000000..1e5ca784c845
--- /dev/null
+++ b/crypto/heimdal/appl/push/push_locl.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: push_locl.h,v 1.6 1999/12/02 16:58:33 joda Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <ctype.h>
+#include <limits.h>
+#include <time.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HESIOD
+#include <hesiod.h>
+#endif
+
+#include <roken.h>
+#include <err.h>
+#include <getarg.h>
+#ifdef KRB5
+#include <krb5.h>
+#endif
+
+#ifdef KRB4
+#include <krb.h>
+#endif
diff --git a/crypto/heimdal/appl/rsh/ChangeLog b/crypto/heimdal/appl/rsh/ChangeLog
new file mode 100644
index 000000000000..c07d8d0be9b2
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/ChangeLog
@@ -0,0 +1,237 @@
+1999-12-16 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (doit): addrinfo returned from getaddrinfo() is not usable
+ directly as hints. copy it and set AI_PASSIVE.
+
+1999-11-20 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (main): remember to close the priviledged sockets before
+ calling rlogin
+
+1999-11-02 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (main): redo the v4/v5 selection for consistency. -4 ->
+ try only v4 -5 -> try only v5 none, -45 -> try v5, v4
+
+1999-10-26 Assar Westerlund <assar@sics.se>
+
+ * rshd.c (main): ignore SIGPIPE
+
+ * common.c (do_read): the encoded length can be longer than the
+ buffer being used, allocate memory for it dynamically. From Brian
+ A May <bmay@dgs.monash.edu.au>
+
+1999-10-14 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (proto): be more careful and don't print errno when read()
+ returns 0
+
+1999-09-20 Assar Westerlund <assar@sics.se>
+
+ * rshd.c (recv_krb4_auth): set `iv'
+
+1999-08-16 Assar Westerlund <assar@sics.se>
+
+ * common.c (do_read): be careful with the return value from
+ krb5_net_read
+
+1999-08-05 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: call freehostent
+
+ * rsh.c: remove some dead code
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * rshd.c: re-write the handling of forwarded credentials and
+ stuff. From Miroslav Ruda <ruda@ics.muni.cz>
+
+ * rsh_locl.h: always include kafs.h
+
+ * rsh.c: add `-z' and `-G' options
+
+ * rsh.c (loop): shutdown one side of the TCP connection on EOF.
+ From Brian A May <bmay@dgs.monash.edu.au>
+
+ * common.c (do_read): handle EOF. From Brian A May
+ <bmay@dgs.monash.edu.au>
+
+1999-08-01 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: const fixes
+
+1999-07-29 Assar Westerlund <assar@sics.se>
+
+ * rshd.c: v6-ify
+
+ * rsh.c: v6-ify
+
+1999-07-28 Assar Westerlund <assar@sics.se>
+
+ * rsh_locl.h: move around kafs.h
+
+1999-07-24 Assar Westerlund <assar@sics.se>
+
+ * rsh_locl.h: <shadow.h>
+
+ * rsh.c, rshd.c: improve forwarding and implement unique ccache on
+ server. From Miroslav Ruda <ruda@ics.muni.cz>
+
+1999-07-03 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (construct_command): handle argc == 0 for generality
+
+1999-06-23 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: new option `-e' for not trying to open an stderr socket
+
+1999-06-17 Assar Westerlund <assar@sics.se>
+
+ * rsh_locl.h (RSH_BUFSIZ): bump to 16 * 1024 to be sure that we
+ don't leave any data inside des_enc_read. (that constant should
+ really be exported in some way...)
+
+1999-06-15 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: use get_default_username and resulting const pollution
+
+1999-05-21 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (main): try $USERNAME
+
+1999-05-14 Assar Westerlund <assar@sics.se>
+
+ * rshd.c (doit): afslog correctly
+
+1999-05-11 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (main): add fallback to rlogin
+
+1999-05-10 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (send_krb5_auth): call krb5_sendauth with ccache == NULL.
+ check return value from krb5_crypto_init
+
+ * common.c (do_write, do_read): always return -1 for failure
+ (net_write, net_read): remove. they already exist in libroken
+
+1999-05-09 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: make sure it tries with all other authentication methods
+ after one has failed
+ * rsh.c (main): detect the case of no command given.
+
+1999-04-11 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: new option --forwardable. use print_version
+
+Sat Apr 10 17:10:55 1999 Assar Westerlund <assar@sics.se>
+
+ * rshd.c (setup_copier): use `socketpair' instead of `pipe'. Some
+ shells don't think it's a rsh session if they find a pipe at the
+ other end.
+ (setup_environment): add SSH_CLIENT just to make bash happy
+
+ * common.c (do_read): use krb5_get_wrapped_length
+
+Wed Mar 24 03:59:42 1999 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (loop): more braces to make gcc happy
+
+Tue Mar 23 17:08:32 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * rsh_locl.h: kafs.h
+
+ * rshd.c: add `-P', `-v', and `-L' flags
+
+Thu Mar 18 11:37:24 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: include Makefile.am.common
+
+Tue Dec 1 14:44:44 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * appl/rsh/rshd.c: update to new crypto framework
+
+ * appl/rsh/rsh_locl.h: update to new crypto framework
+
+ * appl/rsh/rsh.c: update to new crypto framework
+
+ * appl/rsh/common.c: update to new crypto framework
+
+Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rsh.c (main): initialize host
+
+ * appl/rsh/rshd.c (recv_krb5_auth): disable `do_encrypt' if not
+ encrypting.
+
+Thu Jul 30 23:12:17 1998 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rsh.c: kludges for parsing `rsh hostname -l user'
+
+Thu Jul 23 19:49:03 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * appl/rsh/rshd.c: use krb5_verify_authenticator_checksum
+
+Sat Apr 18 21:13:06 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * appl/rsh/rsh.c: Don't try v5 if (only) `-4' is specified.
+
+Sun Dec 21 09:44:05 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rshd.c (recv_krb5_auth): swap the order of the
+ `local_user' and the `remote_user'
+
+ * appl/rsh/rsh.c (send_krb5_auth): swap the order of the
+ `local_user' and the `remote_user'
+
+Sat Nov 29 07:10:11 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rshd.c: updated to use getarg.
+ changed `struct fd_set' to `fd_set'.
+ implemented broken/BSD authentication (requires iruserok)
+
+Wed Nov 12 02:35:57 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rsh_locl.h: add AUTH_BROKEN and PATH_RSH
+
+ * appl/rsh/Makefile.am: set BINDIR
+
+ * appl/rsh/rsh.c: implemented BSD-style reserved port
+ `authentication'
+
+Sun Aug 24 08:06:54 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rshd.c: syslog remote shells
+
+Tue Aug 12 01:29:46 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rshd/rshd.c: Use `krb5_sock_to_principal'. Send server
+ parameter to krb5_rd_req/krb5_recvauth. Set addresses in
+ auth_context.
+
+Fri Jul 25 17:32:12 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rshd.c: implement forwarding
+
+ * appl/rsh/rsh.c: Use getarg. Implement forwarding.
+
+Sun Jul 13 00:32:16 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh: Conditionalize the krb4-support.
+
+Wed Jul 9 06:58:00 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rsh.c: use the correct user for the checksum
+
+Mon Jul 7 11:15:51 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rshd.c: Now works. Also implementd encryption and
+ `-p'.
+
+ * appl/rsh/common.c: new file
+
+Mon Jun 30 06:08:14 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh: New program.
+
diff --git a/crypto/heimdal/appl/rsh/Makefile.am b/crypto/heimdal/appl/rsh/Makefile.am
new file mode 100644
index 000000000000..0875f9ffe7dc
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/Makefile.am
@@ -0,0 +1,19 @@
+# $Id: Makefile.am,v 1.13 1999/04/09 18:24:05 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+bin_PROGRAMS = rsh
+
+libexec_PROGRAMS = rshd
+
+rsh_SOURCES = rsh.c common.c rsh_locl.h
+
+rshd_SOURCES = rshd.c common.c rsh_locl.h
+
+LDADD = $(LIB_kafs) \
+ $(LIB_krb5) \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(LIB_roken)
diff --git a/crypto/heimdal/appl/rsh/Makefile.in b/crypto/heimdal/appl/rsh/Makefile.in
new file mode 100644
index 000000000000..1800c7b81d9c
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/Makefile.in
@@ -0,0 +1,698 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.13 1999/04/09 18:24:05 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+bin_PROGRAMS = rsh
+
+libexec_PROGRAMS = rshd
+
+rsh_SOURCES = rsh.c common.c rsh_locl.h
+
+rshd_SOURCES = rshd.c common.c rsh_locl.h
+
+LDADD = $(LIB_kafs) $(LIB_krb5) $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(LIB_roken)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = rsh$(EXEEXT)
+libexec_PROGRAMS = rshd$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+rsh_OBJECTS = rsh.$(OBJEXT) common.$(OBJEXT)
+rsh_LDADD = $(LDADD)
+@KRB4_TRUE@@KRB5_FALSE@rsh_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_TRUE@rsh_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_FALSE@rsh_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_TRUE@@KRB5_TRUE@rsh_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+rsh_LDFLAGS =
+rshd_OBJECTS = rshd.$(OBJEXT) common.$(OBJEXT)
+rshd_LDADD = $(LDADD)
+@KRB4_TRUE@@KRB5_FALSE@rshd_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_TRUE@rshd_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_FALSE@rshd_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_TRUE@@KRB5_TRUE@rshd_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+rshd_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(rsh_SOURCES) $(rshd_SOURCES)
+OBJECTS = $(rsh_OBJECTS) $(rshd_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/rsh/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-libexecPROGRAMS:
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+
+distclean-libexecPROGRAMS:
+
+maintainer-clean-libexecPROGRAMS:
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+rsh$(EXEEXT): $(rsh_OBJECTS) $(rsh_DEPENDENCIES)
+ @rm -f rsh$(EXEEXT)
+ $(LINK) $(rsh_LDFLAGS) $(rsh_OBJECTS) $(rsh_LDADD) $(LIBS)
+
+rshd$(EXEEXT): $(rshd_OBJECTS) $(rshd_DEPENDENCIES)
+ @rm -f rshd$(EXEEXT)
+ $(LINK) $(rshd_LDFLAGS) $(rshd_OBJECTS) $(rshd_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/rsh
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS install-libexecPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS uninstall-libexecPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(libexecdir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-libexecPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-libexecPROGRAMS clean-compile \
+ clean-libtool clean-tags clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-libexecPROGRAMS \
+ distclean-compile distclean-libtool distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-libexecPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-libexecPROGRAMS distclean-libexecPROGRAMS \
+clean-libexecPROGRAMS maintainer-clean-libexecPROGRAMS \
+uninstall-libexecPROGRAMS install-libexecPROGRAMS mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-local install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/rsh/common.c b/crypto/heimdal/appl/rsh/common.c
new file mode 100644
index 000000000000..6614137cf695
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/common.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "rsh_locl.h"
+RCSID("$Id: common.c,v 1.12 1999/12/02 17:04:56 joda Exp $");
+
+ssize_t
+do_read (int fd,
+ void *buf,
+ size_t sz)
+{
+ int ret;
+
+ if (do_encrypt) {
+#ifdef KRB4
+ if (auth_method == AUTH_KRB4) {
+ return des_enc_read (fd, buf, sz, schedule, &iv);
+ } else
+#endif /* KRB4 */
+ if(auth_method == AUTH_KRB5) {
+ u_int32_t len, outer_len;
+ int status;
+ krb5_data data;
+ void *edata;
+
+ ret = krb5_net_read (context, &fd, &len, 4);
+ if (ret <= 0)
+ return ret;
+ len = ntohl(len);
+ if (len > sz)
+ abort ();
+ outer_len = krb5_get_wrapped_length (context, crypto, len);
+ edata = malloc (outer_len);
+ if (edata == NULL)
+ errx (1, "malloc: cannot allocate %u bytes", outer_len);
+ ret = krb5_net_read (context, &fd, edata, outer_len);
+ if (ret <= 0)
+ return ret;
+
+ status = krb5_decrypt(context, crypto, KRB5_KU_OTHER_ENCRYPTED,
+ edata, outer_len, &data);
+ free (edata);
+
+ if (status)
+ errx (1, "%s", krb5_get_err_text (context, status));
+ memcpy (buf, data.data, len);
+ krb5_data_free (&data);
+ return len;
+ } else {
+ abort ();
+ }
+ } else
+ return read (fd, buf, sz);
+}
+
+ssize_t
+do_write (int fd, void *buf, size_t sz)
+{
+ if (do_encrypt) {
+#ifdef KRB4
+ if(auth_method == AUTH_KRB4) {
+ return des_enc_write (fd, buf, sz, schedule, &iv);
+ } else
+#endif /* KRB4 */
+ if(auth_method == AUTH_KRB5) {
+ krb5_error_code status;
+ krb5_data data;
+ u_int32_t len;
+ int ret;
+
+ status = krb5_encrypt(context, crypto, KRB5_KU_OTHER_ENCRYPTED,
+ buf, sz, &data);
+
+ if (status)
+ errx (1, "%s", krb5_get_err_text(context, status));
+
+ assert (krb5_get_wrapped_length (context, crypto,
+ sz) == data.length);
+
+ len = htonl(sz);
+ ret = krb5_net_write (context, &fd, &len, 4);
+ if (ret != 4)
+ return ret;
+ ret = krb5_net_write (context, &fd, data.data, data.length);
+ if (ret != data.length)
+ return ret;
+ free (data.data);
+ return sz;
+ } else {
+ abort();
+ }
+ } else
+ return write (fd, buf, sz);
+}
diff --git a/crypto/heimdal/appl/rsh/rsh.c b/crypto/heimdal/appl/rsh/rsh.c
new file mode 100644
index 000000000000..444748ea6f87
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/rsh.c
@@ -0,0 +1,948 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "rsh_locl.h"
+RCSID("$Id: rsh.c,v 1.46 1999/12/16 11:53:50 assar Exp $");
+
+enum auth_method auth_method;
+int do_encrypt;
+int do_forward;
+int do_forwardable;
+int do_unique_tkfile = 0;
+char *unique_tkfile = NULL;
+char tkfile[MAXPATHLEN];
+krb5_context context;
+krb5_keyblock *keyblock;
+krb5_crypto crypto;
+des_key_schedule schedule;
+des_cblock iv;
+
+
+/*
+ *
+ */
+
+static int input = 1; /* Read from stdin */
+
+static int
+loop (int s, int errsock)
+{
+ fd_set real_readset;
+ int count = 1;
+
+ FD_ZERO(&real_readset);
+ FD_SET(s, &real_readset);
+ if (errsock != -1) {
+ FD_SET(errsock, &real_readset);
+ ++count;
+ }
+ if(input)
+ FD_SET(STDIN_FILENO, &real_readset);
+
+ for (;;) {
+ int ret;
+ fd_set readset;
+ char buf[RSH_BUFSIZ];
+
+ readset = real_readset;
+ ret = select (max(s, errsock) + 1, &readset, NULL, NULL, NULL);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ err (1, "select");
+ }
+ if (FD_ISSET(s, &readset)) {
+ ret = do_read (s, buf, sizeof(buf));
+ if (ret < 0)
+ err (1, "read");
+ else if (ret == 0) {
+ close (s);
+ FD_CLR(s, &real_readset);
+ if (--count == 0)
+ return 0;
+ } else
+ net_write (STDOUT_FILENO, buf, ret);
+ }
+ if (errsock != -1 && FD_ISSET(errsock, &readset)) {
+ ret = do_read (errsock, buf, sizeof(buf));
+ if (ret < 0)
+ err (1, "read");
+ else if (ret == 0) {
+ close (errsock);
+ FD_CLR(errsock, &real_readset);
+ if (--count == 0)
+ return 0;
+ } else
+ net_write (STDERR_FILENO, buf, ret);
+ }
+ if (FD_ISSET(STDIN_FILENO, &readset)) {
+ ret = read (STDIN_FILENO, buf, sizeof(buf));
+ if (ret < 0)
+ err (1, "read");
+ else if (ret == 0) {
+ close (STDIN_FILENO);
+ FD_CLR(STDIN_FILENO, &real_readset);
+ shutdown (s, SHUT_WR);
+ } else
+ do_write (s, buf, ret);
+ }
+ }
+}
+
+#ifdef KRB4
+static int
+send_krb4_auth(int s,
+ struct sockaddr *thisaddr,
+ struct sockaddr *thataddr,
+ const char *hostname,
+ const char *remote_user,
+ const char *local_user,
+ size_t cmd_len,
+ const char *cmd)
+{
+ KTEXT_ST text;
+ CREDENTIALS cred;
+ MSG_DAT msg;
+ int status;
+ size_t len;
+
+ status = krb_sendauth (do_encrypt ? KOPT_DO_MUTUAL : 0,
+ s, &text, "rcmd",
+ (char *)hostname, krb_realmofhost (hostname),
+ getpid(), &msg, &cred, schedule,
+ (struct sockaddr_in *)thisaddr,
+ (struct sockaddr_in *)thataddr,
+ KCMD_VERSION);
+ if (status != KSUCCESS) {
+ warnx ("%s: %s", hostname, krb_get_err_text(status));
+ return 1;
+ }
+ memcpy (iv, cred.session, sizeof(iv));
+
+ len = strlen(remote_user) + 1;
+ if (net_write (s, remote_user, len) != len) {
+ warn("write");
+ return 1;
+ }
+ if (net_write (s, cmd, cmd_len) != cmd_len) {
+ warn("write");
+ return 1;
+ }
+ return 0;
+}
+#endif /* KRB4 */
+
+/*
+ * Send forward information on `s' for host `hostname', them being
+ * forwardable themselves if `forwardable'
+ */
+
+static int
+krb5_forward_cred (krb5_auth_context auth_context,
+ int s,
+ const char *hostname,
+ int forwardable)
+{
+ krb5_error_code ret;
+ krb5_ccache ccache;
+ krb5_creds creds;
+ krb5_kdc_flags flags;
+ krb5_data out_data;
+ krb5_principal principal;
+
+ memset (&creds, 0, sizeof(creds));
+
+ ret = krb5_cc_default (context, &ccache);
+ if (ret) {
+ warnx ("could not forward creds: krb5_cc_default: %s",
+ krb5_get_err_text (context, ret));
+ return 1;
+ }
+
+ ret = krb5_cc_get_principal (context, ccache, &principal);
+ if (ret) {
+ warnx ("could not forward creds: krb5_cc_get_principal: %s",
+ krb5_get_err_text (context, ret));
+ return 1;
+ }
+
+ creds.client = principal;
+
+ ret = krb5_build_principal (context,
+ &creds.server,
+ strlen(principal->realm),
+ principal->realm,
+ "krbtgt",
+ principal->realm,
+ NULL);
+
+ if (ret) {
+ warnx ("could not forward creds: krb5_build_principal: %s",
+ krb5_get_err_text (context, ret));
+ return 1;
+ }
+
+ creds.times.endtime = 0;
+
+ flags.i = 0;
+ flags.b.forwarded = 1;
+ flags.b.forwardable = forwardable;
+
+ ret = krb5_get_forwarded_creds (context,
+ auth_context,
+ ccache,
+ flags.i,
+ hostname,
+ &creds,
+ &out_data);
+ if (ret) {
+ warnx ("could not forward creds: krb5_get_forwarded_creds: %s",
+ krb5_get_err_text (context, ret));
+ return 1;
+ }
+
+ ret = krb5_write_message (context,
+ (void *)&s,
+ &out_data);
+ krb5_data_free (&out_data);
+
+ if (ret)
+ warnx ("could not forward creds: krb5_write_message: %s",
+ krb5_get_err_text (context, ret));
+ return 0;
+}
+
+static int
+send_krb5_auth(int s,
+ struct sockaddr *thisaddr,
+ struct sockaddr *thataddr,
+ const char *hostname,
+ const char *remote_user,
+ const char *local_user,
+ size_t cmd_len,
+ const char *cmd)
+{
+ krb5_principal server;
+ krb5_data cksum_data;
+ int status;
+ size_t len;
+ krb5_auth_context auth_context = NULL;
+
+ status = krb5_sname_to_principal(context,
+ hostname,
+ "host",
+ KRB5_NT_SRV_HST,
+ &server);
+ if (status) {
+ warnx ("%s: %s", hostname, krb5_get_err_text(context, status));
+ return 1;
+ }
+
+ cksum_data.length = asprintf ((char **)&cksum_data.data,
+ "%u:%s%s%s",
+ ntohs(socket_get_port(thataddr)),
+ do_encrypt ? "-x " : "",
+ cmd,
+ remote_user);
+
+ status = krb5_sendauth (context,
+ &auth_context,
+ &s,
+ KCMD_VERSION,
+ NULL,
+ server,
+ do_encrypt ? AP_OPTS_MUTUAL_REQUIRED : 0,
+ &cksum_data,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (status) {
+ warnx ("%s: %s", hostname, krb5_get_err_text(context, status));
+ return 1;
+ }
+
+ status = krb5_auth_con_getkey (context, auth_context, &keyblock);
+ if (status) {
+ warnx ("krb5_auth_con_getkey: %s", krb5_get_err_text(context, status));
+ return 1;
+ }
+
+ status = krb5_auth_con_setaddrs_from_fd (context,
+ auth_context,
+ &s);
+ if (status) {
+ warnx("krb5_auth_con_setaddrs_from_fd: %s",
+ krb5_get_err_text(context, status));
+ return(1);
+ }
+
+ status = krb5_crypto_init(context, keyblock, 0, &crypto);
+ if(status) {
+ warnx ("krb5_crypto_init: %s", krb5_get_err_text(context, status));
+ return 1;
+ }
+
+ len = strlen(remote_user) + 1;
+ if (net_write (s, remote_user, len) != len) {
+ warn ("write");
+ return 1;
+ }
+ if (do_encrypt && net_write (s, "-x ", 3) != 3) {
+ warn ("write");
+ return 1;
+ }
+ if (net_write (s, cmd, cmd_len) != cmd_len) {
+ warn ("write");
+ return 1;
+ }
+
+ if (do_unique_tkfile) {
+ if (net_write (s, tkfile, strlen(tkfile)) != strlen(tkfile)) {
+ warn ("write");
+ return 1;
+ }
+ }
+ len = strlen(local_user) + 1;
+ if (net_write (s, local_user, len) != len) {
+ warn ("write");
+ return 1;
+ }
+
+ if (!do_forward
+ || krb5_forward_cred (auth_context, s, hostname, do_forwardable)) {
+ /* Empty forwarding info */
+
+ u_char zero[4] = {0, 0, 0, 0};
+ write (s, &zero, 4);
+ }
+ krb5_auth_con_free (context, auth_context);
+ return 0;
+}
+
+static int
+send_broken_auth(int s,
+ struct sockaddr *thisaddr,
+ struct sockaddr *thataddr,
+ const char *hostname,
+ const char *remote_user,
+ const char *local_user,
+ size_t cmd_len,
+ const char *cmd)
+{
+ size_t len;
+
+ len = strlen(local_user) + 1;
+ if (net_write (s, local_user, len) != len) {
+ warn ("write");
+ return 1;
+ }
+ len = strlen(remote_user) + 1;
+ if (net_write (s, remote_user, len) != len) {
+ warn ("write");
+ return 1;
+ }
+ if (net_write (s, cmd, cmd_len) != cmd_len) {
+ warn ("write");
+ return 1;
+ }
+ return 0;
+}
+
+static int
+proto (int s, int errsock,
+ const char *hostname, const char *local_user, const char *remote_user,
+ const char *cmd, size_t cmd_len,
+ int (*auth_func)(int s,
+ struct sockaddr *this, struct sockaddr *that,
+ const char *hostname, const char *remote_user,
+ const char *local_user, size_t cmd_len,
+ const char *cmd))
+{
+ int errsock2;
+ char buf[BUFSIZ];
+ char *p;
+ size_t len;
+ char reply;
+ struct sockaddr_storage thisaddr_ss;
+ struct sockaddr *thisaddr = (struct sockaddr *)&thisaddr_ss;
+ struct sockaddr_storage thataddr_ss;
+ struct sockaddr *thataddr = (struct sockaddr *)&thataddr_ss;
+ struct sockaddr_storage erraddr_ss;
+ struct sockaddr *erraddr = (struct sockaddr *)&erraddr_ss;
+ int addrlen;
+ int ret;
+
+ addrlen = sizeof(thisaddr_ss);
+ if (getsockname (s, thisaddr, &addrlen) < 0) {
+ warn ("getsockname(%s)", hostname);
+ return 1;
+ }
+ addrlen = sizeof(thataddr_ss);
+ if (getpeername (s, thataddr, &addrlen) < 0) {
+ warn ("getpeername(%s)", hostname);
+ return 1;
+ }
+
+ if (errsock != -1) {
+
+ addrlen = sizeof(erraddr_ss);
+ if (getsockname (errsock, erraddr, &addrlen) < 0) {
+ warn ("getsockname");
+ return 1;
+ }
+
+ if (listen (errsock, 1) < 0) {
+ warn ("listen");
+ return 1;
+ }
+
+ p = buf;
+ snprintf (p, sizeof(buf), "%u",
+ ntohs(socket_get_port(erraddr)));
+ len = strlen(buf) + 1;
+ if(net_write (s, buf, len) != len) {
+ warn ("write");
+ close (errsock);
+ return 1;
+ }
+
+ errsock2 = accept (errsock, NULL, NULL);
+ if (errsock2 < 0) {
+ warn ("accept");
+ close (errsock);
+ return 1;
+ }
+ close (errsock);
+
+ } else {
+ if (net_write (s, "0", 2) != 2) {
+ warn ("write");
+ return 1;
+ }
+ errsock2 = -1;
+ }
+
+ if ((*auth_func)(s, thisaddr, thataddr, hostname,
+ remote_user, local_user,
+ cmd_len, cmd)) {
+ close (errsock2);
+ return 1;
+ }
+
+ ret = net_read (s, &reply, 1);
+ if (ret < 0) {
+ warn ("read");
+ close (errsock2);
+ return 1;
+ } else if (ret == 0) {
+ warnx ("unexpected EOF from %s", hostname);
+ close (errsock2);
+ return 1;
+ }
+ if (reply != 0) {
+
+ warnx ("Error from rshd at %s:", hostname);
+
+ while ((ret = read (s, buf, sizeof(buf))) > 0)
+ write (STDOUT_FILENO, buf, ret);
+ write (STDOUT_FILENO,"\n",1);
+ close (errsock2);
+ return 1;
+ }
+
+ return loop (s, errsock2);
+}
+
+/*
+ * Return in `res' a copy of the concatenation of `argc, argv' into
+ * malloced space.
+ */
+
+static size_t
+construct_command (char **res, int argc, char **argv)
+{
+ int i;
+ size_t len = 0;
+ char *tmp;
+
+ for (i = 0; i < argc; ++i)
+ len += strlen(argv[i]) + 1;
+ len = max (1, len);
+ tmp = malloc (len);
+ if (tmp == NULL)
+ errx (1, "malloc %u failed", len);
+
+ *tmp = '\0';
+ for (i = 0; i < argc - 1; ++i) {
+ strcat (tmp, argv[i]);
+ strcat (tmp, " ");
+ }
+ if (argc > 0)
+ strcat (tmp, argv[argc-1]);
+ *res = tmp;
+ return len;
+}
+
+static char *
+print_addr (const struct sockaddr_in *sin)
+{
+ char addr_str[256];
+ char *res;
+
+ inet_ntop (AF_INET, &sin->sin_addr, addr_str, sizeof(addr_str));
+ res = strdup(addr_str);
+ if (res == NULL)
+ errx (1, "malloc: out of memory");
+ return res;
+}
+
+static int
+doit_broken (int argc,
+ char **argv,
+ int optind,
+ const char *host,
+ const char *remote_user,
+ const char *local_user,
+ int port,
+ int priv_socket1,
+ int priv_socket2,
+ const char *cmd,
+ size_t cmd_len)
+{
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char portstr[NI_MAXSERV];
+
+ if (priv_socket1 < 0) {
+ warnx ("unable to bind reserved port: is rsh setuid root?");
+ return 1;
+ }
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_family = AF_INET;
+
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(port));
+
+ error = getaddrinfo (host, portstr, &hints, &ai);
+ if (error) {
+ warnx ("%s: %s", host, gai_strerror(error));
+ return 1;
+ }
+
+ if (connect (priv_socket1, ai->ai_addr, ai->ai_addrlen) < 0) {
+ if (ai->ai_next == NULL) {
+ freeaddrinfo (ai);
+ return 1;
+ }
+
+ close(priv_socket1);
+ close(priv_socket2);
+
+ for (a = ai->ai_next; a != NULL; a = a->ai_next) {
+ pid_t pid;
+
+ pid = fork();
+ if (pid < 0)
+ err (1, "fork");
+ else if(pid == 0) {
+ char **new_argv;
+ int i = 0;
+ struct sockaddr_in *sin = (struct sockaddr_in *)a->ai_addr;
+
+ new_argv = malloc((argc + 2) * sizeof(*new_argv));
+ if (new_argv == NULL)
+ errx (1, "malloc: out of memory");
+ new_argv[i] = argv[i];
+ ++i;
+ if (optind == i)
+ new_argv[i++] = print_addr (sin);
+ new_argv[i++] = "-K";
+ for(; i <= argc; ++i)
+ new_argv[i] = argv[i - 1];
+ if (optind > 1)
+ new_argv[optind + 1] = print_addr(sin);
+ new_argv[argc + 1] = NULL;
+ execv(PATH_RSH, new_argv);
+ err(1, "execv(%s)", PATH_RSH);
+ } else {
+ int status;
+
+ freeaddrinfo (ai);
+
+ while(waitpid(pid, &status, 0) < 0)
+ ;
+ if(WIFEXITED(status) && WEXITSTATUS(status) == 0)
+ return 0;
+ }
+ }
+ return 1;
+ } else {
+ int ret;
+
+ freeaddrinfo (ai);
+
+ ret = proto (priv_socket1, priv_socket2,
+ argv[optind],
+ local_user, remote_user,
+ cmd, cmd_len,
+ send_broken_auth);
+ return ret;
+ }
+}
+
+static int
+doit (const char *hostname,
+ const char *remote_user,
+ const char *local_user,
+ int port,
+ const char *cmd,
+ size_t cmd_len,
+ int do_errsock,
+ int (*auth_func)(int s,
+ struct sockaddr *this, struct sockaddr *that,
+ const char *hostname, const char *remote_user,
+ const char *local_user, size_t cmd_len,
+ const char *cmd))
+{
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char portstr[NI_MAXSERV];
+ int ret;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(port));
+
+ error = getaddrinfo (hostname, portstr, &hints, &ai);
+ if (error) {
+ errx (1, "%s: %s", hostname, gai_strerror(error));
+ return -1;
+ }
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ int s;
+ int errsock;
+
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0)
+ continue;
+ if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
+ warn ("connect(%s)", hostname);
+ close (s);
+ continue;
+ }
+ if (do_errsock) {
+ struct addrinfo *ea;
+ struct addrinfo hints;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = a->ai_socktype;
+ hints.ai_protocol = a->ai_protocol;
+ hints.ai_family = a->ai_family;
+ hints.ai_flags = AI_PASSIVE;
+
+ error = getaddrinfo (NULL, "0", &hints, &ea);
+ if (error)
+ errx (1, "getaddrinfo: %s", gai_strerror(error));
+ errsock = socket (ea->ai_family, ea->ai_socktype, ea->ai_protocol);
+ if (errsock < 0)
+ err (1, "socket");
+ if (bind (errsock, ea->ai_addr, ea->ai_addrlen) < 0)
+ err (1, "bind");
+ freeaddrinfo (ea);
+ } else
+ errsock = -1;
+
+ freeaddrinfo (ai);
+ ret = proto (s, errsock,
+ hostname,
+ local_user, remote_user,
+ cmd, cmd_len, auth_func);
+ close (s);
+ return ret;
+ }
+ warnx ("failed to contact %s", hostname);
+ freeaddrinfo (ai);
+ return -1;
+}
+
+#ifdef KRB4
+static int use_v4 = -1;
+#endif
+static int use_v5 = -1;
+static int use_only_broken = 0;
+static int use_broken = 1;
+static char *port_str;
+static const char *user;
+static int do_version;
+static int do_help;
+static int do_errsock = 1;
+
+struct getargs args[] = {
+#ifdef KRB4
+ { "krb4", '4', arg_flag, &use_v4, "Use Kerberos V4",
+ NULL },
+#endif
+ { "krb5", '5', arg_flag, &use_v5, "Use Kerberos V5",
+ NULL },
+ { "broken", 'K', arg_flag, &use_only_broken, "Use priv port",
+ NULL },
+ { "input", 'n', arg_negative_flag, &input, "Close stdin",
+ NULL },
+ { "encrypt", 'x', arg_flag, &do_encrypt, "Encrypt connection",
+ NULL },
+ { "encrypt", 'z', arg_negative_flag, &do_encrypt,
+ "Don't encrypt connection", NULL },
+ { "forward", 'f', arg_flag, &do_forward, "Forward credentials",
+ NULL },
+ { "forward", 'G', arg_negative_flag,&do_forward, "Forward credentials",
+ NULL },
+ { "forwardable", 'F', arg_flag, &do_forwardable,
+ "Forward forwardable credentials", NULL },
+ { "unique", 'u', arg_flag, &do_unique_tkfile,
+ "Use unique remote tkfile", NULL },
+ { "tkfile", 'U', arg_string, &unique_tkfile,
+ "Use that remote tkfile", NULL },
+ { "port", 'p', arg_string, &port_str, "Use this port",
+ "number-or-service" },
+ { "user", 'l', arg_string, &user, "Run as this user",
+ NULL },
+ { "stderr", 'e', arg_negative_flag, &do_errsock, "don't open stderr"},
+ { "version", 0, arg_flag, &do_version, "Print version",
+ NULL },
+ { "help", 0, arg_flag, &do_help, NULL,
+ NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args) / sizeof(args[0]),
+ NULL,
+ "host [command]");
+ exit (ret);
+}
+
+/*
+ *
+ */
+
+int
+main(int argc, char **argv)
+{
+ int priv_port1, priv_port2;
+ int priv_socket1, priv_socket2;
+ int port = 0;
+ int optind = 0;
+ int ret = 1;
+ char *cmd;
+ size_t cmd_len;
+ const char *local_user;
+ char *host = NULL;
+ int host_index = -1;
+ int status;
+
+ priv_port1 = priv_port2 = IPPORT_RESERVED-1;
+ priv_socket1 = rresvport(&priv_port1);
+ priv_socket2 = rresvport(&priv_port2);
+ setuid(getuid());
+
+ set_progname (argv[0]);
+
+ if (argc >= 2 && argv[1][0] != '-') {
+ host = argv[host_index = 1];
+ optind = 1;
+ }
+
+ status = krb5_init_context (&context);
+ if (status)
+ errx(1, "krb5_init_context failed: %u", status);
+
+ do_forwardable = krb5_config_get_bool (context, NULL,
+ "libdefaults",
+ "forwardable",
+ NULL);
+
+ do_forward = krb5_config_get_bool (context, NULL,
+ "libdefaults",
+ "forward",
+ NULL);
+
+ do_encrypt = krb5_config_get_bool (context, NULL,
+ "libdefaults",
+ "encrypt",
+ NULL);
+
+ if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
+ &optind))
+ usage (1);
+
+ if (do_forwardable)
+ do_forward = 1;
+
+#if defined(KRB4) && defined(KRB5)
+ if(use_v4 == -1 && use_v5 == 1)
+ use_v4 = 0;
+ if(use_v5 == -1 && use_v4 == 1)
+ use_v5 = 0;
+#endif
+
+ if (use_only_broken) {
+#ifdef KRB4
+ use_v4 = 0;
+#endif
+ use_v5 = 0;
+ }
+
+ if (do_help)
+ usage (0);
+
+ if (do_version) {
+ print_version (NULL);
+ return 0;
+ }
+
+ if (do_unique_tkfile && unique_tkfile != NULL)
+ errx (1, "Only one of -u and -U allowed.");
+
+ if (do_unique_tkfile)
+ strcpy(tkfile,"-u ");
+ else if (unique_tkfile != NULL) {
+ if (strchr(unique_tkfile,' ') != NULL) {
+ warnx("Space is not allowed in tkfilename");
+ usage(1);
+ }
+ do_unique_tkfile = 1;
+ snprintf (tkfile, sizeof(tkfile), "-U %s ", unique_tkfile);
+ }
+
+ if (host == NULL) {
+ if (argc - optind < 1)
+ usage (1);
+ else
+ host = argv[host_index = optind++];
+ }
+
+ if (optind == argc) {
+ close (priv_socket1);
+ close (priv_socket2);
+ argv[0] = "rlogin";
+ execvp ("rlogin", argv);
+ err (1, "execvp rlogin");
+ }
+
+ if (port_str) {
+ struct servent *s = roken_getservbyname (port_str, "tcp");
+
+ if (s)
+ port = s->s_port;
+ else {
+ char *ptr;
+
+ port = strtol (port_str, &ptr, 10);
+ if (port == 0 && ptr == port_str)
+ errx (1, "Bad port `%s'", port_str);
+ port = htons(port);
+ }
+ }
+
+ local_user = get_default_username ();
+ if (local_user == NULL)
+ errx (1, "who are you?");
+
+ if (user == NULL)
+ user = local_user;
+
+ cmd_len = construct_command(&cmd, argc - optind, argv + optind);
+
+ /*
+ * Try all different authentication methods
+ */
+
+ if (ret && use_v5) {
+ int tmp_port;
+
+ if (port)
+ tmp_port = port;
+ else
+ tmp_port = krb5_getportbyname (context, "kshell", "tcp", 544);
+
+ auth_method = AUTH_KRB5;
+ ret = doit (host, user, local_user, tmp_port, cmd, cmd_len,
+ do_errsock,
+ send_krb5_auth);
+ }
+#ifdef KRB4
+ if (ret && use_v4) {
+ int tmp_port;
+
+ if (port)
+ tmp_port = port;
+ else if (do_encrypt)
+ tmp_port = krb5_getportbyname (context, "ekshell", "tcp", 545);
+ else
+ tmp_port = krb5_getportbyname (context, "kshell", "tcp", 544);
+
+ auth_method = AUTH_KRB4;
+ ret = doit (host, user, local_user, tmp_port, cmd, cmd_len,
+ do_errsock,
+ send_krb4_auth);
+ }
+#endif
+ if (ret && use_broken) {
+ int tmp_port;
+
+ if(port)
+ tmp_port = port;
+ else
+ tmp_port = krb5_getportbyname(context, "shell", "tcp", 514);
+ auth_method = AUTH_BROKEN;
+ ret = doit_broken (argc, argv, host_index, host,
+ user, local_user,
+ tmp_port,
+ priv_socket1,
+ do_errsock ? priv_socket2 : -1,
+ cmd, cmd_len);
+ }
+ return ret;
+}
diff --git a/crypto/heimdal/appl/rsh/rsh_locl.h b/crypto/heimdal/appl/rsh/rsh_locl.h
new file mode 100644
index 000000000000..ecf0f85ab6f9
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/rsh_locl.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: rsh_locl.h,v 1.22 1999/12/02 17:04:56 joda Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#include <errno.h>
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <err.h>
+#include <roken.h>
+#include <getarg.h>
+#ifdef KRB4
+#include <krb.h>
+#include <prot.h>
+#endif
+#include <krb5.h>
+#include <kafs.h>
+
+#ifndef _PATH_NOLOGIN
+#define _PATH_NOLOGIN "/etc/nologin"
+#endif
+
+#ifndef _PATH_BSHELL
+#define _PATH_BSHELL "/bin/sh"
+#endif
+
+#ifndef _PATH_DEFPATH
+#define _PATH_DEFPATH "/usr/bin:/bin"
+#endif
+
+/*
+ *
+ */
+
+enum auth_method { AUTH_KRB4, AUTH_KRB5, AUTH_BROKEN };
+
+extern enum auth_method auth_method;
+extern int do_encrypt;
+extern krb5_context context;
+extern krb5_keyblock *keyblock;
+extern krb5_crypto crypto;
+extern des_key_schedule schedule;
+extern des_cblock iv;
+
+#define KCMD_VERSION "KCMDV0.1"
+
+#define USERNAME_SZ 16
+#define COMMAND_SZ 1024
+
+#define RSH_BUFSIZ (16 * 1024)
+
+#define PATH_RSH BINDIR "/rsh"
+
+ssize_t do_read (int fd, void *buf, size_t sz);
+ssize_t do_write (int fd, void *buf, size_t sz);
diff --git a/crypto/heimdal/appl/rsh/rshd.c b/crypto/heimdal/appl/rsh/rshd.c
new file mode 100644
index 000000000000..f9b685768bd6
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/rshd.c
@@ -0,0 +1,850 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "rsh_locl.h"
+RCSID("$Id: rshd.c,v 1.29 1999/12/02 17:04:56 joda Exp $");
+
+enum auth_method auth_method;
+
+krb5_context context;
+krb5_keyblock *keyblock;
+krb5_crypto crypto;
+des_key_schedule schedule;
+des_cblock iv;
+
+krb5_ccache ccache, ccache2;
+int kerberos_status = 0;
+
+int do_encrypt = 0;
+
+static int do_unique_tkfile = 0;
+static char tkfile[MAXPATHLEN] = "";
+
+static int do_inetd = 1;
+static char *port_str;
+static int do_rhosts;
+static int do_kerberos = 0;
+static int do_vacuous = 0;
+static int do_log = 1;
+static int do_newpag = 1;
+static int do_version;
+static int do_help = 0;
+
+static void
+syslog_and_die (const char *m, ...)
+{
+ va_list args;
+
+ va_start(args, m);
+ vsyslog (LOG_ERR, m, args);
+ va_end(args);
+ exit (1);
+}
+
+static void
+fatal (int sock, const char *m, ...)
+{
+ va_list args;
+ char buf[BUFSIZ];
+ size_t len;
+
+ *buf = 1;
+ va_start(args, m);
+ len = vsnprintf (buf + 1, sizeof(buf) - 1, m, args);
+ va_end(args);
+ syslog (LOG_ERR, buf + 1);
+ net_write (sock, buf, len + 1);
+ exit (1);
+}
+
+static void
+read_str (int s, char *str, size_t sz, char *expl)
+{
+ while (sz > 0) {
+ if (net_read (s, str, 1) != 1)
+ syslog_and_die ("read: %m");
+ if (*str == '\0')
+ return;
+ --sz;
+ ++str;
+ }
+ fatal (s, "%s too long", expl);
+}
+
+static int
+recv_bsd_auth (int s, u_char *buf,
+ struct sockaddr_in *thisaddr,
+ struct sockaddr_in *thataddr,
+ char *client_username,
+ char *server_username,
+ char *cmd)
+{
+ struct passwd *pwd;
+
+ read_str (s, client_username, USERNAME_SZ, "local username");
+ read_str (s, server_username, USERNAME_SZ, "remote username");
+ read_str (s, cmd, COMMAND_SZ, "command");
+ pwd = getpwnam(server_username);
+ if (pwd == NULL)
+ fatal(s, "Login incorrect.");
+ if (iruserok(thataddr->sin_addr.s_addr, pwd->pw_uid == 0,
+ client_username, server_username))
+ fatal(s, "Login incorrect.");
+ return 0;
+}
+
+#ifdef KRB4
+static int
+recv_krb4_auth (int s, u_char *buf,
+ struct sockaddr *thisaddr,
+ struct sockaddr *thataddr,
+ char *client_username,
+ char *server_username,
+ char *cmd)
+{
+ int status;
+ int32_t options;
+ KTEXT_ST ticket;
+ AUTH_DAT auth;
+ char instance[INST_SZ + 1];
+ char version[KRB_SENDAUTH_VLEN + 1];
+
+ if (memcmp (buf, KRB_SENDAUTH_VERS, 4) != 0)
+ return -1;
+ if (net_read (s, buf + 4, KRB_SENDAUTH_VLEN - 4) !=
+ KRB_SENDAUTH_VLEN - 4)
+ syslog_and_die ("reading auth info: %m");
+ if (memcmp (buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN) != 0)
+ syslog_and_die("unrecognized auth protocol: %.8s", buf);
+
+ options = KOPT_IGNORE_PROTOCOL;
+ if (do_encrypt)
+ options |= KOPT_DO_MUTUAL;
+ k_getsockinst (s, instance, sizeof(instance));
+ status = krb_recvauth (options,
+ s,
+ &ticket,
+ "rcmd",
+ instance,
+ (struct sockaddr_in *)thataddr,
+ (struct sockaddr_in *)thisaddr,
+ &auth,
+ "",
+ schedule,
+ version);
+ if (status != KSUCCESS)
+ syslog_and_die ("recvauth: %s", krb_get_err_text(status));
+ if (strncmp (version, KCMD_VERSION, KRB_SENDAUTH_VLEN) != 0)
+ syslog_and_die ("bad version: %s", version);
+
+ read_str (s, server_username, USERNAME_SZ, "remote username");
+ if (kuserok (&auth, server_username) != 0)
+ fatal (s, "Permission denied");
+ read_str (s, cmd, COMMAND_SZ, "command");
+
+ syslog(LOG_INFO|LOG_AUTH,
+ "kerberos v4 shell from %s on %s as %s, cmd '%.80s'",
+ krb_unparse_name_long(auth.pname, auth.pinst, auth.prealm),
+
+ inet_ntoa(((struct sockaddr_in *)thataddr)->sin_addr),
+ server_username,
+ cmd);
+
+ memcpy (iv, auth.session, sizeof(iv));
+
+ return 0;
+}
+
+#endif /* KRB4 */
+
+static int
+save_krb5_creds (int s,
+ krb5_auth_context auth_context,
+ krb5_principal client)
+
+{
+ int ret;
+ krb5_data remote_cred;
+
+ krb5_data_zero (&remote_cred);
+ ret= krb5_read_message (context, (void *)&s, &remote_cred);
+ if (ret) {
+ krb5_data_free(&remote_cred);
+ return 0;
+ }
+ if (remote_cred.length == 0)
+ return 0;
+
+ ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache);
+ if (ret) {
+ krb5_data_free(&remote_cred);
+ return 0;
+ }
+
+ krb5_cc_initialize(context,ccache,client);
+ ret = krb5_rd_cred(context, auth_context, ccache,&remote_cred);
+ krb5_data_free (&remote_cred);
+ if (ret)
+ return 0;
+ return 1;
+}
+
+static void
+krb5_start_session (void)
+{
+ krb5_error_code ret;
+
+ ret = krb5_cc_resolve (context, tkfile, &ccache2);
+ if (ret) {
+ krb5_cc_destroy(context, ccache);
+ return;
+ }
+
+ ret = krb5_cc_copy_cache (context, ccache, ccache2);
+ if (ret) {
+ krb5_cc_destroy(context, ccache);
+ return ;
+ }
+
+ krb5_cc_close(context, ccache2);
+ krb5_cc_destroy(context, ccache);
+ return;
+}
+
+static int
+recv_krb5_auth (int s, u_char *buf,
+ struct sockaddr *thisaddr,
+ struct sockaddr *thataddr,
+ char *client_username,
+ char *server_username,
+ char *cmd)
+{
+ u_int32_t len;
+ krb5_auth_context auth_context = NULL;
+ krb5_ticket *ticket;
+ krb5_error_code status;
+ krb5_data cksum_data;
+ krb5_principal server;
+
+ if (memcmp (buf, "\x00\x00\x00\x13", 4) != 0)
+ return -1;
+ len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]);
+
+ if (net_read(s, buf, len) != len)
+ syslog_and_die ("reading auth info: %m");
+ if (len != sizeof(KRB5_SENDAUTH_VERSION)
+ || memcmp (buf, KRB5_SENDAUTH_VERSION, len) != 0)
+ syslog_and_die ("bad sendauth version: %.8s", buf);
+
+ status = krb5_sock_to_principal (context,
+ s,
+ "host",
+ KRB5_NT_SRV_HST,
+ &server);
+ if (status)
+ syslog_and_die ("krb5_sock_to_principal: %s",
+ krb5_get_err_text(context, status));
+
+ status = krb5_recvauth(context,
+ &auth_context,
+ &s,
+ KCMD_VERSION,
+ server,
+ KRB5_RECVAUTH_IGNORE_VERSION,
+ NULL,
+ &ticket);
+ krb5_free_principal (context, server);
+ if (status)
+ syslog_and_die ("krb5_recvauth: %s",
+ krb5_get_err_text(context, status));
+
+ read_str (s, server_username, USERNAME_SZ, "remote username");
+ read_str (s, cmd, COMMAND_SZ, "command");
+ read_str (s, client_username, COMMAND_SZ, "local username");
+
+ status = krb5_auth_con_getkey (context, auth_context, &keyblock);
+ if (status)
+ syslog_and_die ("krb5_auth_con_getkey: %s",
+ krb5_get_err_text(context, status));
+
+ status = krb5_crypto_init(context, keyblock, 0, &crypto);
+ if(status)
+ syslog_and_die("krb5_crypto_init: %s",
+ krb5_get_err_text(context, status));
+
+
+ cksum_data.length = asprintf ((char **)&cksum_data.data,
+ "%u:%s%s",
+ ntohs(socket_get_port (thisaddr)),
+ cmd,
+ server_username);
+
+ status = krb5_verify_authenticator_checksum(context,
+ auth_context,
+ cksum_data.data,
+ cksum_data.length);
+
+ if (status)
+ syslog_and_die ("krb5_verify_authenticator_checksum: %s",
+ krb5_get_err_text(context, status));
+
+ free (cksum_data.data);
+
+ if (strncmp (client_username, "-u ", 3) == 0) {
+ do_unique_tkfile = 1;
+ memmove (client_username, client_username + 3,
+ strlen(client_username) - 2);
+ }
+
+ if (strncmp (client_username, "-U ", 3) == 0) {
+ char *end, *temp_tkfile;
+
+ do_unique_tkfile = 1;
+ if (strncmp (server_username + 3, "FILE:", 5) == 0) {
+ temp_tkfile = tkfile;
+ } else {
+ strcpy (tkfile, "FILE:");
+ temp_tkfile = tkfile + 5;
+ }
+ end = strchr(client_username + 3,' ');
+ strncpy(temp_tkfile, client_username + 3, end - client_username - 3);
+ temp_tkfile[end - client_username - 3] = '\0';
+ memmove (client_username, end +1, strlen(end+1)+1);
+ }
+
+ kerberos_status = save_krb5_creds (s, auth_context, ticket->client);
+
+ if(!krb5_kuserok (context,
+ ticket->client,
+ server_username))
+ fatal (s, "Permission denied");
+
+ if (strncmp (cmd, "-x ", 3) == 0) {
+ do_encrypt = 1;
+ memmove (cmd, cmd + 3, strlen(cmd) - 2);
+ } else {
+ do_encrypt = 0;
+ }
+
+ {
+ char *name;
+
+ if (krb5_unparse_name (context, ticket->client, &name) == 0) {
+ char addr_str[256];
+
+ if (inet_ntop (thataddr->sa_family,
+ socket_get_address (thataddr),
+ addr_str, sizeof(addr_str)) == NULL)
+ strlcpy (addr_str, "unknown address",
+ sizeof(addr_str));
+
+ syslog(LOG_INFO|LOG_AUTH,
+ "kerberos v5 shell from %s on %s as %s, cmd '%.80s'",
+ name,
+ addr_str,
+ server_username,
+ cmd);
+ free (name);
+ }
+ }
+
+ return 0;
+}
+
+static void
+loop (int from0, int to0,
+ int to1, int from1,
+ int to2, int from2)
+{
+ fd_set real_readset;
+ int max_fd;
+ int count = 2;
+
+ FD_ZERO(&real_readset);
+ FD_SET(from0, &real_readset);
+ FD_SET(from1, &real_readset);
+ FD_SET(from2, &real_readset);
+ max_fd = max(from0, max(from1, from2)) + 1;
+ for (;;) {
+ int ret;
+ fd_set readset = real_readset;
+ char buf[RSH_BUFSIZ];
+
+ ret = select (max_fd, &readset, NULL, NULL, NULL);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ syslog_and_die ("select: %m");
+ }
+ if (FD_ISSET(from0, &readset)) {
+ ret = do_read (from0, buf, sizeof(buf));
+ if (ret < 0)
+ syslog_and_die ("read: %m");
+ else if (ret == 0) {
+ close (from0);
+ close (to0);
+ FD_CLR(from0, &real_readset);
+ } else
+ net_write (to0, buf, ret);
+ }
+ if (FD_ISSET(from1, &readset)) {
+ ret = read (from1, buf, sizeof(buf));
+ if (ret < 0)
+ syslog_and_die ("read: %m");
+ else if (ret == 0) {
+ close (from1);
+ close (to1);
+ FD_CLR(from1, &real_readset);
+ if (--count == 0)
+ exit (0);
+ } else
+ do_write (to1, buf, ret);
+ }
+ if (FD_ISSET(from2, &readset)) {
+ ret = read (from2, buf, sizeof(buf));
+ if (ret < 0)
+ syslog_and_die ("read: %m");
+ else if (ret == 0) {
+ close (from2);
+ close (to2);
+ FD_CLR(from2, &real_readset);
+ if (--count == 0)
+ exit (0);
+ } else
+ do_write (to2, buf, ret);
+ }
+ }
+}
+
+/*
+ * Used by `setup_copier' to create some pipe-like means of
+ * communcation. Real pipes would probably be the best thing, but
+ * then the shell doesn't understand it's talking to rshd. If
+ * socketpair doesn't work everywhere, some autoconf magic would have
+ * to be added here.
+ *
+ * If it fails creating the `pipe', it aborts by calling fatal.
+ */
+
+static void
+pipe_a_like (int fd[2])
+{
+ if (socketpair (AF_UNIX, SOCK_STREAM, 0, fd) < 0)
+ fatal (STDOUT_FILENO, "socketpair: %m");
+}
+
+/*
+ * Start a child process and leave the parent copying data to and from it. */
+
+static void
+setup_copier (void)
+{
+ int p0[2], p1[2], p2[2];
+ pid_t pid;
+
+ pipe_a_like(p0);
+ pipe_a_like(p1);
+ pipe_a_like(p2);
+ pid = fork ();
+ if (pid < 0)
+ fatal (STDOUT_FILENO, "fork: %m");
+ if (pid == 0) { /* child */
+ close (p0[1]);
+ close (p1[0]);
+ close (p2[0]);
+ dup2 (p0[0], STDIN_FILENO);
+ dup2 (p1[1], STDOUT_FILENO);
+ dup2 (p2[1], STDERR_FILENO);
+ close (p0[0]);
+ close (p1[1]);
+ close (p2[1]);
+ } else { /* parent */
+ close (p0[0]);
+ close (p1[1]);
+ close (p2[1]);
+
+ if (net_write (STDOUT_FILENO, "", 1) != 1)
+ fatal (STDOUT_FILENO, "write failed");
+
+ loop (STDIN_FILENO, p0[1],
+ STDOUT_FILENO, p1[0],
+ STDERR_FILENO, p2[0]);
+ }
+}
+
+/*
+ * Is `port' a ``reserverd'' port?
+ */
+
+static int
+is_reserved(u_short port)
+{
+ return ntohs(port) < IPPORT_RESERVED;
+}
+
+/*
+ * Set the necessary part of the environment in `env'.
+ */
+
+static void
+setup_environment (char *env[7], struct passwd *pwd)
+{
+ asprintf (&env[0], "USER=%s", pwd->pw_name);
+ asprintf (&env[1], "HOME=%s", pwd->pw_dir);
+ asprintf (&env[2], "SHELL=%s", pwd->pw_shell);
+ asprintf (&env[3], "PATH=%s", _PATH_DEFPATH);
+ asprintf (&env[4], "SSH_CLIENT=only_to_make_bash_happy");
+ if (do_unique_tkfile)
+ asprintf (&env[5], "KRB5CCNAME=%s", tkfile);
+ else env[5] = NULL;
+ env[6] = NULL;
+}
+
+static void
+doit (int do_kerberos, int check_rhosts)
+{
+ u_char buf[BUFSIZ];
+ u_char *p;
+ struct sockaddr_storage thisaddr_ss;
+ struct sockaddr *thisaddr = (struct sockaddr *)&thisaddr_ss;
+ struct sockaddr_storage thataddr_ss;
+ struct sockaddr *thataddr = (struct sockaddr *)&thataddr_ss;
+ struct sockaddr_storage erraddr_ss;
+ struct sockaddr *erraddr = (struct sockaddr *)&erraddr_ss;
+ int addrlen;
+ int port;
+ int errsock = -1;
+ char client_user[COMMAND_SZ], server_user[USERNAME_SZ];
+ char cmd[COMMAND_SZ];
+ struct passwd *pwd;
+ int s = STDIN_FILENO;
+ char *env[7];
+
+ addrlen = sizeof(thisaddr_ss);
+ if (getsockname (s, thisaddr, &addrlen) < 0)
+ syslog_and_die("getsockname: %m");
+ addrlen = sizeof(thataddr_ss);
+ if (getpeername (s, thataddr, &addrlen) < 0)
+ syslog_and_die ("getpeername: %m");
+
+ if (!do_kerberos && !is_reserved(socket_get_port(thataddr)))
+ fatal(s, "Permission denied");
+
+ p = buf;
+ port = 0;
+ for(;;) {
+ if (net_read (s, p, 1) != 1)
+ syslog_and_die ("reading port number: %m");
+ if (*p == '\0')
+ break;
+ else if (isdigit(*p))
+ port = port * 10 + *p - '0';
+ else
+ syslog_and_die ("non-digit in port number: %c", *p);
+ }
+
+ if (!do_kerberos && !is_reserved(htons(port)))
+ fatal(s, "Permission denied");
+
+ if (port) {
+ int priv_port = IPPORT_RESERVED - 1;
+
+ /*
+ * There's no reason to require a ``privileged'' port number
+ * here, but for some reason the brain dead rsh clients
+ * do... :-(
+ */
+
+ erraddr->sa_family = thataddr->sa_family;
+ socket_set_address_and_port (erraddr,
+ socket_get_address (thataddr),
+ htons(port));
+
+ /*
+ * we only do reserved port for IPv4
+ */
+
+ if (erraddr->sa_family == AF_INET)
+ errsock = rresvport (&priv_port);
+ else
+ errsock = socket (erraddr->sa_family, SOCK_STREAM, 0);
+ if (errsock < 0)
+ syslog_and_die ("socket: %m");
+ if (connect (errsock,
+ erraddr,
+ socket_sockaddr_size (erraddr)) < 0)
+ syslog_and_die ("connect: %m");
+ }
+
+ if(do_kerberos) {
+ if (net_read (s, buf, 4) != 4)
+ syslog_and_die ("reading auth info: %m");
+
+#ifdef KRB4
+ if (recv_krb4_auth (s, buf, thisaddr, thataddr,
+ client_user,
+ server_user,
+ cmd) == 0)
+ auth_method = AUTH_KRB4;
+ else
+#endif /* KRB4 */
+ if(recv_krb5_auth (s, buf, thisaddr, thataddr,
+ client_user,
+ server_user,
+ cmd) == 0)
+ auth_method = AUTH_KRB5;
+ else
+ syslog_and_die ("unrecognized auth protocol: %x %x %x %x",
+ buf[0], buf[1], buf[2], buf[3]);
+ } else {
+ if(recv_bsd_auth (s, buf,
+ (struct sockaddr_in *)thisaddr,
+ (struct sockaddr_in *)thataddr,
+ client_user,
+ server_user,
+ cmd) == 0) {
+ auth_method = AUTH_BROKEN;
+ if(do_vacuous) {
+ printf("Remote host requires Kerberos authentication\n");
+ exit(0);
+ }
+ } else
+ syslog_and_die("recv_bsd_auth failed");
+ }
+
+ pwd = getpwnam (server_user);
+ if (pwd == NULL)
+ fatal (s, "Login incorrect.");
+
+ if (*pwd->pw_shell == '\0')
+ pwd->pw_shell = _PATH_BSHELL;
+
+ if (pwd->pw_uid != 0 && access (_PATH_NOLOGIN, F_OK) == 0)
+ fatal (s, "Login disabled.");
+
+#ifdef HAVE_GETSPNAM
+ {
+ struct spwd *sp;
+ long today;
+
+ sp = getspnam(server_user);
+ today = time(0)/(24L * 60 * 60);
+ if (sp->sp_expire > 0)
+ if (today > sp->sp_expire)
+ fatal(s, "Account has expired.");
+ }
+#endif
+
+#ifdef HAVE_SETLOGIN
+ if (setlogin(pwd->pw_name) < 0)
+ syslog(LOG_ERR, "setlogin() failed: %m");
+#endif
+
+#ifdef HAVE_SETPCRED
+ if (setpcred (pwd->pw_name, NULL) == -1)
+ syslog(LOG_ERR, "setpcred() failure: %m");
+#endif /* HAVE_SETPCRED */
+ if (initgroups (pwd->pw_name, pwd->pw_gid) < 0)
+ fatal (s, "Login incorrect.");
+
+ if (setgid(pwd->pw_gid) < 0)
+ fatal (s, "Login incorrect.");
+
+ if (setuid (pwd->pw_uid) < 0)
+ fatal (s, "Login incorrect.");
+
+#ifdef KRB5
+ {
+ int fd;
+
+ if (!do_unique_tkfile)
+ snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_%u",pwd->pw_uid);
+ else if (*tkfile=='\0') {
+ snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_XXXXXX");
+ fd = mkstemp(tkfile+5);
+ close(fd);
+ unlink(tkfile+5);
+ }
+
+ if (kerberos_status)
+ krb5_start_session();
+ }
+#endif
+
+ if (chdir (pwd->pw_dir) < 0)
+ fatal (s, "Remote directory.");
+
+ if (errsock >= 0) {
+ if (dup2 (errsock, STDERR_FILENO) < 0)
+ fatal (s, "Dup2 failed.");
+ close (errsock);
+ }
+
+ setup_environment (env, pwd);
+
+ if (do_encrypt) {
+ setup_copier ();
+ } else {
+ if (net_write (s, "", 1) != 1)
+ fatal (s, "write failed");
+ }
+
+#ifdef KRB4
+ if(k_hasafs()) {
+ char cell[64];
+
+ if(do_newpag)
+ k_setpag();
+ if (k_afs_cell_of_file (pwd->pw_dir, cell, sizeof(cell)) == 0)
+ krb_afslog_uid_home (cell, NULL, pwd->pw_uid, pwd->pw_dir);
+
+ krb_afslog_uid_home(NULL, NULL, pwd->pw_uid, pwd->pw_dir);
+
+#ifdef KRB5
+ /* XXX */
+ {
+ krb5_ccache ccache;
+ krb5_error_code status;
+
+ status = krb5_cc_resolve (context, tkfile, &ccache);
+ if (!status) {
+ krb5_afslog_uid_home(context,ccache,NULL,NULL,
+ pwd->pw_uid, pwd->pw_dir);
+ krb5_cc_close (context, ccache);
+ }
+ }
+#endif /* KRB5 */
+ }
+#endif /* KRB4 */
+ execle (pwd->pw_shell, pwd->pw_shell, "-c", cmd, NULL, env);
+ err(1, "exec %s", pwd->pw_shell);
+}
+
+struct getargs args[] = {
+ { "inetd", 'i', arg_negative_flag, &do_inetd,
+ "Not started from inetd" },
+ { "kerberos", 'k', arg_flag, &do_kerberos,
+ "Implement kerberised services" },
+ { "encrypt", 'x', arg_flag, &do_encrypt,
+ "Implement encrypted service" },
+ { "rhosts", 'l', arg_flag, &do_rhosts,
+ "Check users .rhosts" },
+ { "port", 'p', arg_string, &port_str, "Use this port",
+ "port" },
+ { "vacuous", 'v', arg_flag, &do_vacuous,
+ "Don't accept non-kerberised connections" },
+ { NULL, 'P', arg_negative_flag, &do_newpag,
+ "Don't put process in new PAG" },
+ /* compatibility flag: */
+ { NULL, 'L', arg_flag, &do_log },
+ { "version", 0, arg_flag, &do_version },
+ { "help", 0, arg_flag, &do_help }
+};
+
+static void
+usage (int ret)
+{
+ if(isatty(STDIN_FILENO))
+ arg_printusage (args,
+ sizeof(args) / sizeof(args[0]),
+ NULL,
+ "");
+ else
+ syslog (LOG_ERR, "Usage: %s [-ikxlvPL] [-p port]", __progname);
+ exit (ret);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+ int port = 0;
+
+ set_progname (argv[0]);
+ roken_openlog ("rshd", LOG_ODELAY | LOG_PID, LOG_AUTH);
+
+ if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv,
+ &optind))
+ usage(1);
+
+ if(do_help)
+ usage (0);
+
+ if (do_version) {
+ print_version(NULL);
+ exit(0);
+ }
+
+#ifdef KRB5
+ krb5_init_context (&context);
+#endif
+
+ if(port_str) {
+ struct servent *s = roken_getservbyname (port_str, "tcp");
+
+ if (s)
+ port = s->s_port;
+ else {
+ char *ptr;
+
+ port = strtol (port_str, &ptr, 10);
+ if (port == 0 && ptr == port_str)
+ syslog_and_die("Bad port `%s'", port_str);
+ port = htons(port);
+ }
+ }
+
+ if (do_encrypt)
+ do_kerberos = 1;
+
+ if (!do_inetd) {
+ if (port == 0) {
+ if (do_kerberos) {
+ if (do_encrypt)
+ port = krb5_getportbyname (context, "ekshell", "tcp", 545);
+ else
+ port = krb5_getportbyname (context, "kshell", "tcp", 544);
+ } else {
+ port = krb5_getportbyname(context, "shell", "tcp", 514);
+ }
+ }
+ mini_inetd (port);
+ }
+
+ signal (SIGPIPE, SIG_IGN);
+
+ doit (do_kerberos, do_rhosts);
+ return 0;
+}
diff --git a/crypto/heimdal/appl/su/ChangeLog b/crypto/heimdal/appl/su/ChangeLog
new file mode 100644
index 000000000000..030808d7e9b3
--- /dev/null
+++ b/crypto/heimdal/appl/su/ChangeLog
@@ -0,0 +1,39 @@
+1999-10-20 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: use LIB_roken
+
+1999-09-28 Assar Westerlund <assar@sics.se>
+
+ * su.c (krb5_verify): use krb5_verify_user_lrealm
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * su.c: add support for shadow passwords and rewrite some logic.
+ From Miroslav Ruda <ruda@ics.muni.cz>
+
+ * Makefile.am: add libkafs
+
+1999-06-15 Assar Westerlund <assar@sics.se>
+
+ * su.c (main): conditionalize `getlogin'
+
+1999-05-11 Assar Westerlund <assar@sics.se>
+
+ * su.c (verfiy_krb5): get the name out of the ccache before
+ closing it
+
+1999-05-05 Assar Westerlund <assar@sics.se>
+
+ * su.c: some more error checking
+
+Wed Apr 21 21:04:36 1999 Assar Westerlund <assar@sics.se>
+
+ * su.c (-f): implement
+
+ * su.c: implement -i
+ (verify_krb5): correct the ownership on the credential cache
+
+Tue Apr 20 13:26:13 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * su.c: don't depend on paths.h
+
diff --git a/crypto/heimdal/appl/su/Makefile.am b/crypto/heimdal/appl/su/Makefile.am
new file mode 100644
index 000000000000..b0fe379e11d4
--- /dev/null
+++ b/crypto/heimdal/appl/su/Makefile.am
@@ -0,0 +1,16 @@
+# $Id: Makefile.am,v 1.3 1999/10/19 23:00:37 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+noinst_PROGRAMS = su
+#bin_SUIDS = su
+su_SOURCES = su.c
+
+LDADD = $(LIB_kafs) \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
diff --git a/crypto/heimdal/appl/su/Makefile.in b/crypto/heimdal/appl/su/Makefile.in
new file mode 100644
index 000000000000..72b8198fa8b0
--- /dev/null
+++ b/crypto/heimdal/appl/su/Makefile.in
@@ -0,0 +1,620 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.3 1999/10/19 23:00:37 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+noinst_PROGRAMS = su
+#bin_SUIDS = su
+su_SOURCES = su.c
+
+LDADD = $(LIB_kafs) $(top_builddir)/lib/krb5/libkrb5.la $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+noinst_PROGRAMS = su$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+su_OBJECTS = su.$(OBJEXT)
+su_LDADD = $(LDADD)
+@KRB4_TRUE@su_DEPENDENCIES = $(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@su_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+su_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(su_SOURCES)
+OBJECTS = $(su_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/su/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+su$(EXEEXT): $(su_OBJECTS) $(su_DEPENDENCIES)
+ @rm -f su$(EXEEXT)
+ $(LINK) $(su_LDFLAGS) $(su_OBJECTS) $(su_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/su
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-noinstPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstPROGRAMS distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/su/su.c b/crypto/heimdal/appl/su/su.c
new file mode 100644
index 000000000000..049a4d74dbf2
--- /dev/null
+++ b/crypto/heimdal/appl/su/su.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include <config.h>
+
+RCSID("$Id: su.c,v 1.10 1999/09/28 02:34:17 assar Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <syslog.h>
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+
+#include <pwd.h>
+
+#include <krb5.h>
+#include <kafs.h>
+#include <err.h>
+#include <roken.h>
+#include <getarg.h>
+#include <kafs.h>
+
+#ifndef _PATH_DEFPATH
+#define _PATH_DEFPATH "/usr/bin:/bin"
+#endif
+
+#ifndef _PATH_BSHELL
+#define _PATH_BSHELL "/bin/sh"
+#endif
+
+int kerberos_flag = 1;
+int csh_f_flag;
+int full_login;
+int env_flag;
+char *kerberos_instance = "root";
+int help_flag;
+int version_flag;
+char *cmd;
+
+struct getargs args[] = {
+ { "kerberos", 'K', arg_negative_flag, &kerberos_flag,
+ "don't use kerberos" },
+ { NULL, 'f', arg_flag, &csh_f_flag,
+ "don't read .cshrc" },
+ { "full", 'l', arg_flag, &full_login,
+ "simulate full login" },
+ { NULL, 'm', arg_flag, &env_flag,
+ "leave environment unmodified" },
+ { "instance", 'i', arg_string, &kerberos_instance,
+ "root instance to use" },
+ { "command", 'c', arg_string, &cmd,
+ "command to execute" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 0, arg_flag, &version_flag },
+};
+
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "[login [shell arguments]]");
+ exit (ret);
+}
+
+static struct passwd*
+make_info(struct passwd *pwd)
+{
+ struct passwd *info;
+ info = malloc(sizeof(*info));
+ if(info == NULL)
+ return NULL;
+ info->pw_name = strdup(pwd->pw_name);
+ info->pw_passwd = strdup(pwd->pw_passwd);
+ info->pw_uid = pwd->pw_uid;
+ info->pw_gid = pwd->pw_gid;
+ info->pw_dir = strdup(pwd->pw_dir);
+ info->pw_shell = strdup(pwd->pw_shell);
+ if(info->pw_name == NULL || info->pw_passwd == NULL ||
+ info->pw_dir == NULL || info->pw_shell == NULL)
+ return NULL;
+ return info;
+}
+
+#ifdef KRB5
+static krb5_context context;
+static krb5_ccache ccache;
+#endif
+
+static int
+krb5_verify(struct passwd *login_info, struct passwd *su_info,
+ const char *kerberos_instance)
+{
+#ifdef KRB5
+ krb5_error_code ret;
+ krb5_principal p;
+
+ ret = krb5_init_context (&context);
+ if (ret) {
+#if 0
+ warnx("krb5_init_context failed: %u", ret);
+#endif
+ return 1;
+ }
+
+ if (strcmp (su_info->pw_name, "root") == 0)
+ ret = krb5_make_principal(context, &p, NULL,
+ login_info->pw_name,
+ kerberos_instance,
+ NULL);
+ else
+ ret = krb5_make_principal(context, &p, NULL,
+ su_info->pw_name,
+ NULL);
+ if(ret)
+ return 1;
+
+ if(su_info->pw_uid != 0 || krb5_kuserok(context, p, su_info->pw_name)) {
+ ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache);
+ if(ret) {
+#if 1
+ krb5_warn(context, ret, "krb5_cc_gen_new");
+#endif
+ return 1;
+ }
+ ret = krb5_verify_user_lrealm(context, p, ccache, NULL, TRUE, NULL);
+ if(ret) {
+ krb5_free_principal (context, p);
+ krb5_cc_destroy(context, ccache);
+ switch (ret) {
+ case KRB5KRB_AP_ERR_BAD_INTEGRITY:
+ case KRB5KRB_AP_ERR_MODIFIED:
+ krb5_warnx(context, "Password incorrect");
+ break;
+ default :
+ krb5_warn(context, ret, "krb5_verify_user");
+ break;
+ }
+ return 1;
+ }
+ return 0;
+ }
+#endif
+ return 1;
+}
+
+#ifdef KRB5
+static int
+krb5_start_session(void)
+{
+ krb5_ccache ccache2;
+ char *cc_name;
+ int ret;
+
+ ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &ccache2);
+ if (ret) {
+ krb5_cc_destroy(context, ccache);
+ return 1;
+ }
+
+ ret = krb5_cc_copy_cache(context, ccache, ccache2);
+
+ asprintf(&cc_name, "%s:%s", krb5_cc_get_type(context, ccache2),
+ krb5_cc_get_name(context, ccache2));
+ setenv("KRB5CCNAME", cc_name, 1);
+
+#ifdef KRB4
+ if(k_hasafs()) {
+ if (k_setpag() == 0)
+ krb5_afslog(context, ccache2, NULL, NULL);
+ }
+#endif
+
+ krb5_cc_close(context, ccache2);
+ krb5_cc_destroy(context, ccache);
+ return 0;
+}
+#endif
+
+static int
+verify_unix(struct passwd *su)
+{
+ char prompt[128];
+ char pw_buf[1024];
+ char *pw;
+ int r;
+ if(su->pw_passwd != NULL && *su->pw_passwd != '\0') {
+ sprintf(prompt, "%s's password: ", su->pw_name);
+ r = des_read_pw_string(pw_buf, sizeof(pw_buf), prompt, 0);
+ if(r != 0)
+ exit(0);
+ pw = crypt(pw_buf, su->pw_passwd);
+ memset(pw_buf, 0, sizeof(pw_buf));
+ if(strcmp(pw, su->pw_passwd) != 0)
+ return 1;
+ }
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int i, optind = 0;
+ char *su_user;
+ struct passwd *su_info;
+ char *login_user = NULL;
+ struct passwd *login_info;
+
+ struct passwd *pwd;
+
+ char *shell;
+
+ int ok = 0;
+ int kerberos_error=1;
+
+ set_progname (argv[0]);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
+ usage(1);
+
+ for (i=0; i < optind; i++)
+ if (strcmp(argv[i], "-") == 0) {
+ full_login = 1;
+ break;
+ }
+
+ if(help_flag)
+ usage(0);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+ if(optind >= argc)
+ su_user = "root";
+ else
+ su_user = argv[optind++];
+
+ pwd = k_getpwnam(su_user);
+ if(pwd == NULL)
+ errx (1, "unknown login %s", su_user);
+ if (pwd->pw_uid == 0 && strcmp ("root", su_user) != 0) {
+ syslog (LOG_ALERT, "NIS attack, user %s has uid 0", su_user);
+ errx (1, "unknown login %s", su_user);
+ }
+ su_info = make_info(pwd);
+
+#if defined(HAVE_GETLOGIN) && !defined(POSIX_GETLOGIN)
+ login_user = getlogin();
+#endif
+ if(login_user == NULL || (pwd = getpwnam(login_user)) == NULL)
+ pwd = getpwuid(getuid());
+ if(pwd == NULL)
+ errx(1, "who are you?");
+ login_info = make_info(pwd);
+ if(env_flag)
+ shell = login_info->pw_shell;
+ else
+ shell = su_info->pw_shell;
+ if(shell == NULL || *shell == '\0')
+ shell = _PATH_BSHELL;
+
+ if(kerberos_flag && ok == 0 &&
+ (kerberos_error=krb5_verify(login_info, su_info, kerberos_instance)) == 0)
+ ok++;
+
+ if(ok == 0 && login_info->pw_uid && verify_unix(su_info) != 0) {
+ printf("Sorry!\n");
+ exit(1);
+ }
+
+#ifdef HAVE_GETSPNAM
+ { struct spwd *sp;
+ long today;
+
+ sp=getspnam(su_info->pw_name);
+ if (sp==NULL)
+ errx(1,"Have not rights to read shadow passwords!");
+ today = time(0)/(24L * 60 * 60);
+ if (sp->sp_expire > 0) {
+ if (today >= sp->sp_expire) {
+ if (login_info->pw_uid)
+ errx(1,"Your account has expired.");
+ else
+ printf("Your account has expired.");
+ }
+ else if (sp->sp_expire - today < 14)
+ printf("Your account will expire in %d days.\n",
+ (int)(sp->sp_expire - today));
+ }
+ if (sp->sp_max > 0) {
+ if (today >= sp->sp_lstchg + sp->sp_max) {
+ if (login_info->pw_uid)
+ errx(1,"Your password has expired. Choose a new one.");
+ else
+ printf("Your password has expired. Choose a new one.");
+ }
+ else if (today >= sp->sp_lstchg + sp->sp_max - sp->sp_warn)
+ printf("Your account will expire in %d days.\n",
+ (int)(sp->sp_lstchg + sp->sp_max -today));
+ }
+ }
+#endif
+ {
+ char *tty = ttyname (STDERR_FILENO);
+ syslog (LOG_NOTICE | LOG_AUTH, tty ? "%s to %s" : "%s to %s on %s",
+ login_info->pw_name, su_info->pw_name, tty);
+ }
+
+
+ if(!env_flag) {
+ if(full_login) {
+ char *t = getenv ("TERM");
+
+ environ = malloc (10 * sizeof (char *));
+ if (environ == NULL)
+ err (1, "malloc");
+ environ[0] = NULL;
+ setenv ("PATH", _PATH_DEFPATH, 1);
+ if (t)
+ setenv ("TERM", t, 1);
+ if (chdir (su_info->pw_dir) < 0)
+ errx (1, "no directory");
+ }
+ if (full_login || su_info->pw_uid)
+ setenv ("USER", su_info->pw_name, 1);
+ setenv("HOME", su_info->pw_dir, 1);
+ setenv("SHELL", shell, 1);
+ }
+
+ {
+ int i;
+ char **args;
+ char *p;
+
+ p = strrchr(shell, '/');
+ if(p)
+ p++;
+ else
+ p = shell;
+
+ if (strcmp(p, "csh") != 0)
+ csh_f_flag = 0;
+
+ args = malloc(((cmd ? 2 : 0) + 1 + argc - optind + 1 + csh_f_flag) * sizeof(*args));
+ if (args == NULL)
+ err (1, "malloc");
+ i = 0;
+ if(full_login)
+ asprintf(&args[i++], "-%s", p);
+ else
+ args[i++] = p;
+ if (cmd) {
+ args[i++] = "-c";
+ args[i++] = cmd;
+ }
+
+ if (csh_f_flag)
+ args[i++] = "-f";
+
+ for (argv += optind; *argv; ++argv)
+ args[i++] = *argv;
+ args[i] = NULL;
+
+ if(setgid(su_info->pw_gid) < 0)
+ err(1, "setgid");
+ if (initgroups (su_info->pw_name, su_info->pw_gid) < 0)
+ err (1, "initgroups");
+ if(setuid(su_info->pw_uid) < 0)
+ err(1, "setuid");
+
+#ifdef KRB5
+ if (!kerberos_error)
+ krb5_start_session();
+#endif
+ execv(shell, args);
+ }
+
+ exit(1);
+}
diff --git a/crypto/heimdal/appl/test/Makefile.am b/crypto/heimdal/appl/test/Makefile.am
new file mode 100644
index 000000000000..9ae5cba38126
--- /dev/null
+++ b/crypto/heimdal/appl/test/Makefile.am
@@ -0,0 +1,37 @@
+# $Id: Makefile.am,v 1.13 1999/09/21 05:06:19 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+noinst_PROGRAMS = tcp_client tcp_server gssapi_server gssapi_client \
+ uu_server uu_client nt_gss_server nt_gss_client
+
+tcp_client_SOURCES = tcp_client.c common.c test_locl.h
+
+tcp_server_SOURCES = tcp_server.c common.c test_locl.h
+
+gssapi_server_SOURCES = gssapi_server.c gss_common.c common.c \
+ gss_common.h test_locl.h
+
+gssapi_client_SOURCES = gssapi_client.c gss_common.c common.c \
+ gss_common.h test_locl.h
+
+uu_server_SOURCES = uu_server.c common.c test_locl.h
+
+uu_client_SOURCES = uu_client.c common.c test_locl.h
+
+gssapi_server_LDADD = $(top_builddir)/lib/gssapi/libgssapi.la $(LDADD)
+
+gssapi_client_LDADD = $(gssapi_server_LDADD)
+
+nt_gss_client_SOURCES = nt_gss_client.c nt_gss_common.c common.c
+
+nt_gss_server_SOURCES = nt_gss_server.c nt_gss_common.c
+
+nt_gss_client_LDADD = $(gssapi_server_LDADD)
+
+nt_gss_server_LDADD = $(nt_gss_client_LDADD)
+
+LDADD = $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
diff --git a/crypto/heimdal/appl/test/Makefile.in b/crypto/heimdal/appl/test/Makefile.in
new file mode 100644
index 000000000000..acada8218e72
--- /dev/null
+++ b/crypto/heimdal/appl/test/Makefile.in
@@ -0,0 +1,708 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.13 1999/09/21 05:06:19 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+noinst_PROGRAMS = tcp_client tcp_server gssapi_server gssapi_client uu_server uu_client nt_gss_server nt_gss_client
+
+
+tcp_client_SOURCES = tcp_client.c common.c test_locl.h
+
+tcp_server_SOURCES = tcp_server.c common.c test_locl.h
+
+gssapi_server_SOURCES = gssapi_server.c gss_common.c common.c gss_common.h test_locl.h
+
+
+gssapi_client_SOURCES = gssapi_client.c gss_common.c common.c gss_common.h test_locl.h
+
+
+uu_server_SOURCES = uu_server.c common.c test_locl.h
+
+uu_client_SOURCES = uu_client.c common.c test_locl.h
+
+gssapi_server_LDADD = $(top_builddir)/lib/gssapi/libgssapi.la $(LDADD)
+
+gssapi_client_LDADD = $(gssapi_server_LDADD)
+
+nt_gss_client_SOURCES = nt_gss_client.c nt_gss_common.c common.c
+
+nt_gss_server_SOURCES = nt_gss_server.c nt_gss_common.c
+
+nt_gss_client_LDADD = $(gssapi_server_LDADD)
+
+nt_gss_server_LDADD = $(nt_gss_client_LDADD)
+
+LDADD = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+noinst_PROGRAMS = tcp_client$(EXEEXT) tcp_server$(EXEEXT) \
+gssapi_server$(EXEEXT) gssapi_client$(EXEEXT) uu_server$(EXEEXT) \
+uu_client$(EXEEXT) nt_gss_server$(EXEEXT) nt_gss_client$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+tcp_client_OBJECTS = tcp_client.$(OBJEXT) common.$(OBJEXT)
+tcp_client_LDADD = $(LDADD)
+tcp_client_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+tcp_client_LDFLAGS =
+tcp_server_OBJECTS = tcp_server.$(OBJEXT) common.$(OBJEXT)
+tcp_server_LDADD = $(LDADD)
+tcp_server_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+tcp_server_LDFLAGS =
+gssapi_server_OBJECTS = gssapi_server.$(OBJEXT) gss_common.$(OBJEXT) \
+common.$(OBJEXT)
+gssapi_server_DEPENDENCIES = $(top_builddir)/lib/gssapi/libgssapi.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+gssapi_server_LDFLAGS =
+gssapi_client_OBJECTS = gssapi_client.$(OBJEXT) gss_common.$(OBJEXT) \
+common.$(OBJEXT)
+gssapi_client_DEPENDENCIES = $(top_builddir)/lib/gssapi/libgssapi.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+gssapi_client_LDFLAGS =
+uu_server_OBJECTS = uu_server.$(OBJEXT) common.$(OBJEXT)
+uu_server_LDADD = $(LDADD)
+uu_server_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+uu_server_LDFLAGS =
+uu_client_OBJECTS = uu_client.$(OBJEXT) common.$(OBJEXT)
+uu_client_LDADD = $(LDADD)
+uu_client_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+uu_client_LDFLAGS =
+nt_gss_server_OBJECTS = nt_gss_server.$(OBJEXT) nt_gss_common.$(OBJEXT)
+nt_gss_server_DEPENDENCIES = $(top_builddir)/lib/gssapi/libgssapi.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+nt_gss_server_LDFLAGS =
+nt_gss_client_OBJECTS = nt_gss_client.$(OBJEXT) nt_gss_common.$(OBJEXT) \
+common.$(OBJEXT)
+nt_gss_client_DEPENDENCIES = $(top_builddir)/lib/gssapi/libgssapi.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+nt_gss_client_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(tcp_client_SOURCES) $(tcp_server_SOURCES) $(gssapi_server_SOURCES) $(gssapi_client_SOURCES) $(uu_server_SOURCES) $(uu_client_SOURCES) $(nt_gss_server_SOURCES) $(nt_gss_client_SOURCES)
+OBJECTS = $(tcp_client_OBJECTS) $(tcp_server_OBJECTS) $(gssapi_server_OBJECTS) $(gssapi_client_OBJECTS) $(uu_server_OBJECTS) $(uu_client_OBJECTS) $(nt_gss_server_OBJECTS) $(nt_gss_client_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/test/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+tcp_client$(EXEEXT): $(tcp_client_OBJECTS) $(tcp_client_DEPENDENCIES)
+ @rm -f tcp_client$(EXEEXT)
+ $(LINK) $(tcp_client_LDFLAGS) $(tcp_client_OBJECTS) $(tcp_client_LDADD) $(LIBS)
+
+tcp_server$(EXEEXT): $(tcp_server_OBJECTS) $(tcp_server_DEPENDENCIES)
+ @rm -f tcp_server$(EXEEXT)
+ $(LINK) $(tcp_server_LDFLAGS) $(tcp_server_OBJECTS) $(tcp_server_LDADD) $(LIBS)
+
+gssapi_server$(EXEEXT): $(gssapi_server_OBJECTS) $(gssapi_server_DEPENDENCIES)
+ @rm -f gssapi_server$(EXEEXT)
+ $(LINK) $(gssapi_server_LDFLAGS) $(gssapi_server_OBJECTS) $(gssapi_server_LDADD) $(LIBS)
+
+gssapi_client$(EXEEXT): $(gssapi_client_OBJECTS) $(gssapi_client_DEPENDENCIES)
+ @rm -f gssapi_client$(EXEEXT)
+ $(LINK) $(gssapi_client_LDFLAGS) $(gssapi_client_OBJECTS) $(gssapi_client_LDADD) $(LIBS)
+
+uu_server$(EXEEXT): $(uu_server_OBJECTS) $(uu_server_DEPENDENCIES)
+ @rm -f uu_server$(EXEEXT)
+ $(LINK) $(uu_server_LDFLAGS) $(uu_server_OBJECTS) $(uu_server_LDADD) $(LIBS)
+
+uu_client$(EXEEXT): $(uu_client_OBJECTS) $(uu_client_DEPENDENCIES)
+ @rm -f uu_client$(EXEEXT)
+ $(LINK) $(uu_client_LDFLAGS) $(uu_client_OBJECTS) $(uu_client_LDADD) $(LIBS)
+
+nt_gss_server$(EXEEXT): $(nt_gss_server_OBJECTS) $(nt_gss_server_DEPENDENCIES)
+ @rm -f nt_gss_server$(EXEEXT)
+ $(LINK) $(nt_gss_server_LDFLAGS) $(nt_gss_server_OBJECTS) $(nt_gss_server_LDADD) $(LIBS)
+
+nt_gss_client$(EXEEXT): $(nt_gss_client_OBJECTS) $(nt_gss_client_DEPENDENCIES)
+ @rm -f nt_gss_client$(EXEEXT)
+ $(LINK) $(nt_gss_client_LDFLAGS) $(nt_gss_client_OBJECTS) $(nt_gss_client_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/test
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-noinstPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstPROGRAMS distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/appl/test/common.c b/crypto/heimdal/appl/test/common.c
new file mode 100644
index 000000000000..5cd4e853e3e2
--- /dev/null
+++ b/crypto/heimdal/appl/test/common.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+
+RCSID("$Id: common.c,v 1.9 1999/12/16 10:29:18 assar Exp $");
+
+static int help_flag;
+static int version_flag;
+static char *port_str;
+char *service = SERVICE;
+
+static struct getargs args[] = {
+ { "port", 'p', arg_string, &port_str, "port to listen to", "port" },
+ { "service", 's', arg_string, &service, "service to use", "service" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 0, arg_flag, &version_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+server_usage(int code, struct getargs *args, int num_args)
+{
+ arg_printusage(args, num_args, NULL, "");
+ exit(code);
+}
+
+static void
+client_usage(int code, struct getargs *args, int num_args)
+{
+ arg_printusage(args, num_args, NULL, "host");
+ exit(code);
+}
+
+
+static int
+common_setup(krb5_context *context, int *argc, char **argv,
+ void (*usage)(int, struct getargs*, int))
+{
+ int port = 0;
+ *argc = krb5_program_setup(context, *argc, argv, args, num_args, usage);
+
+ if(help_flag)
+ (*usage)(0, args, num_args);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ if(port_str){
+ struct servent *s = roken_getservbyname(port_str, "tcp");
+ if(s)
+ port = s->s_port;
+ else {
+ char *ptr;
+
+ port = strtol (port_str, &ptr, 10);
+ if (port == 0 && ptr == port_str)
+ errx (1, "Bad port `%s'", port_str);
+ port = htons(port);
+ }
+ }
+
+ if (port == 0)
+ port = krb5_getportbyname (*context, PORT, "tcp", 4711);
+
+ return port;
+}
+
+int
+server_setup(krb5_context *context, int argc, char **argv)
+{
+ int port = common_setup(context, &argc, argv, server_usage);
+ if(argv[argc] != NULL)
+ server_usage(1, args, num_args);
+ return port;
+}
+
+int
+client_setup(krb5_context *context, int *argc, char **argv)
+{
+ int optind = *argc;
+ int port = common_setup(context, &optind, argv, client_usage);
+ if(*argc - optind != 1)
+ client_usage(1, args, num_args);
+ *argc = optind;
+ return port;
+}
+
+int
+client_doit (const char *hostname, int port, const char *service,
+ int (*func)(int, const char *hostname, const char *service))
+{
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char portstr[NI_MAXSERV];
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(port));
+
+ error = getaddrinfo (hostname, portstr, &hints, &ai);
+ if (error) {
+ errx (1, "%s: %s", hostname, gai_strerror(error));
+ return -1;
+ }
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ int s;
+
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0)
+ continue;
+ if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
+ warn ("connect(%s)", hostname);
+ close (s);
+ continue;
+ }
+ freeaddrinfo (ai);
+ return (*func) (s, hostname, service);
+ }
+ warnx ("failed to contact %s", hostname);
+ freeaddrinfo (ai);
+ return 1;
+}
diff --git a/crypto/heimdal/appl/test/gss_common.c b/crypto/heimdal/appl/test/gss_common.c
new file mode 100644
index 000000000000..c82ba133db5c
--- /dev/null
+++ b/crypto/heimdal/appl/test/gss_common.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+#include <gssapi.h>
+#include "gss_common.h"
+RCSID("$Id: gss_common.c,v 1.6 1999/12/02 17:04:56 joda Exp $");
+
+void
+write_token (int sock, gss_buffer_t buf)
+{
+ u_int32_t len, net_len;
+ OM_uint32 min_stat;
+
+ len = buf->length;
+
+ net_len = htonl(len);
+
+ if (write (sock, &net_len, 4) != 4)
+ err (1, "write");
+ if (write (sock, buf->value, len) != len)
+ err (1, "write");
+
+ gss_release_buffer (&min_stat, buf);
+}
+
+void
+read_token (int sock, gss_buffer_t buf)
+{
+ u_int32_t len, net_len;
+
+ if (read(sock, &net_len, 4) != 4)
+ err (1, "read");
+ len = ntohl(net_len);
+ buf->length = len;
+ buf->value = malloc(len);
+ if (read (sock, buf->value, len) != len)
+ err (1, "read");
+}
+
+void
+gss_print_errors (int min_stat)
+{
+ OM_uint32 new_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ OM_uint32 ret;
+
+ do {
+ ret = gss_display_status (&new_stat,
+ min_stat,
+ GSS_C_MECH_CODE,
+ GSS_C_NO_OID,
+ &msg_ctx,
+ &status_string);
+ fprintf (stderr, "%s\n", (char *)status_string.value);
+ gss_release_buffer (&new_stat, &status_string);
+ } while (!GSS_ERROR(ret) && msg_ctx != 0);
+}
+
+void
+gss_verr(int exitval, int status, const char *fmt, va_list ap)
+{
+ vwarnx (fmt, ap);
+ gss_print_errors (status);
+ exit (exitval);
+}
+
+void
+gss_err(int exitval, int status, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ gss_verr (exitval, status, fmt, args);
+ va_end(args);
+}
+
diff --git a/crypto/heimdal/appl/test/gss_common.h b/crypto/heimdal/appl/test/gss_common.h
new file mode 100644
index 000000000000..775126b91b1c
--- /dev/null
+++ b/crypto/heimdal/appl/test/gss_common.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: gss_common.h,v 1.5 1999/12/02 17:04:56 joda Exp $ */
+
+void write_token (int sock, gss_buffer_t buf);
+void read_token (int sock, gss_buffer_t buf);
+
+void gss_print_errors (int min_stat);
+
+void gss_verr(int exitval, int status, const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 3, 0)));
+
+void gss_err(int exitval, int status, const char *fmt, ...)
+ __attribute__ ((format (printf, 3, 4)));
diff --git a/crypto/heimdal/appl/test/gssapi_client.c b/crypto/heimdal/appl/test/gssapi_client.c
new file mode 100644
index 000000000000..7d15b996bb02
--- /dev/null
+++ b/crypto/heimdal/appl/test/gssapi_client.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+#include <gssapi.h>
+#include "gss_common.h"
+RCSID("$Id: gssapi_client.c,v 1.10 1999/12/04 18:15:50 assar Exp $");
+
+static int
+proto (int sock, const char *hostname, const char *service)
+{
+ struct sockaddr_in remote, local;
+ int addrlen;
+
+ int context_established = 0;
+ gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
+ gss_buffer_t input_token, output_token;
+ gss_buffer_desc real_input_token, real_output_token;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t server;
+ gss_buffer_desc name_token;
+
+ name_token.length = asprintf ((char **)&name_token.value,
+ "%s@%s", service, hostname);
+
+ maj_stat = gss_import_name (&min_stat,
+ &name_token,
+ GSS_C_NT_HOSTBASED_SERVICE,
+ &server);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat,
+ "Error importing name `%s@%s':\n", service, hostname);
+
+ addrlen = sizeof(local);
+ if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
+ || addrlen != sizeof(local))
+ err (1, "getsockname(%s)", hostname);
+
+ addrlen = sizeof(remote);
+ if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
+ || addrlen != sizeof(remote))
+ err (1, "getpeername(%s)", hostname);
+
+ input_token = &real_input_token;
+ output_token = &real_output_token;
+
+ input_token->length = 0;
+ output_token->length = 0;
+
+ while(!context_established) {
+ maj_stat =
+ gss_init_sec_context(&min_stat,
+ GSS_C_NO_CREDENTIAL,
+ &context_hdl,
+ server,
+ GSS_C_NO_OID,
+ GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG,
+ 0,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ input_token,
+ NULL,
+ output_token,
+ NULL,
+ NULL);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_init_sec_context");
+ if (output_token->length != 0)
+ write_token (sock, output_token);
+ if (GSS_ERROR(maj_stat)) {
+ if (context_hdl != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context (&min_stat,
+ &context_hdl,
+ GSS_C_NO_BUFFER);
+ break;
+ }
+ if (maj_stat & GSS_S_CONTINUE_NEEDED) {
+ read_token (sock, input_token);
+ } else {
+ context_established = 1;
+ }
+
+ }
+
+ /* get_mic */
+
+ input_token->length = 3;
+ input_token->value = strdup("hej");
+
+ maj_stat = gss_get_mic(&min_stat,
+ context_hdl,
+ GSS_C_QOP_DEFAULT,
+ input_token,
+ output_token);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_get_mic");
+
+ write_token (sock, input_token);
+ write_token (sock, output_token);
+
+ /* wrap */
+
+ input_token->length = 7;
+ input_token->value = "hemligt";
+
+
+ maj_stat = gss_wrap (&min_stat,
+ context_hdl,
+ 1,
+ GSS_C_QOP_DEFAULT,
+ input_token,
+ NULL,
+ output_token);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_wrap");
+
+ write_token (sock, output_token);
+
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context; /* XXX */
+ int port = client_setup(&context, &argc, argv);
+ return client_doit (argv[argc], port, service, proto);
+}
diff --git a/crypto/heimdal/appl/test/gssapi_server.c b/crypto/heimdal/appl/test/gssapi_server.c
new file mode 100644
index 000000000000..a17ce3e8739a
--- /dev/null
+++ b/crypto/heimdal/appl/test/gssapi_server.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+#include <gssapi.h>
+#include "gss_common.h"
+RCSID("$Id: gssapi_server.c,v 1.10 1999/12/16 10:29:41 assar Exp $");
+
+static int
+proto (int sock, const char *service)
+{
+ struct sockaddr_in remote, local;
+ int addrlen;
+ gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
+ gss_buffer_t input_token, output_token;
+ gss_buffer_desc real_input_token, real_output_token;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t client_name;
+ gss_buffer_desc name_token;
+
+ addrlen = sizeof(local);
+ if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
+ || addrlen != sizeof(local))
+ err (1, "getsockname)");
+
+ addrlen = sizeof(remote);
+ if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
+ || addrlen != sizeof(remote))
+ err (1, "getpeername");
+
+ input_token = &real_input_token;
+ output_token = &real_output_token;
+
+ do {
+ read_token (sock, input_token);
+ maj_stat =
+ gss_accept_sec_context (&min_stat,
+ &context_hdl,
+ GSS_C_NO_CREDENTIAL,
+ input_token,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &client_name,
+ NULL,
+ output_token,
+ NULL,
+ NULL,
+ NULL);
+ if(GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_accept_sec_context");
+ if (output_token->length != 0)
+ write_token (sock, output_token);
+ if (GSS_ERROR(maj_stat)) {
+ if (context_hdl != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context (&min_stat,
+ &context_hdl,
+ GSS_C_NO_BUFFER);
+ break;
+ }
+ } while(maj_stat & GSS_S_CONTINUE_NEEDED);
+
+ maj_stat = gss_display_name (&min_stat,
+ client_name,
+ &name_token,
+ NULL);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_display_name");
+
+ fprintf (stderr, "User is `%.*s'\n", (int)name_token.length,
+ (char *)name_token.value);
+
+ /* gss_verify_mic */
+
+ read_token (sock, input_token);
+ read_token (sock, output_token);
+
+ maj_stat = gss_verify_mic (&min_stat,
+ context_hdl,
+ input_token,
+ output_token,
+ NULL);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_verify_mic");
+
+ fprintf (stderr, "gss_verify_mic: %.*s\n", (int)input_token->length,
+ (char *)input_token->value);
+
+ /* gss_unwrap */
+
+ read_token (sock, input_token);
+
+ maj_stat = gss_unwrap (&min_stat,
+ context_hdl,
+ input_token,
+ output_token,
+ NULL,
+ NULL);
+ if(GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_unwrap");
+
+ fprintf (stderr, "gss_unwrap: %.*s\n", (int)output_token->length,
+ (char *)output_token->value);
+
+ return 0;
+}
+
+static int
+doit (int port, const char *service)
+{
+ int sock, sock2;
+ struct sockaddr_in my_addr;
+ int one = 1;
+
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ err (1, "socket");
+
+ memset (&my_addr, 0, sizeof(my_addr));
+ my_addr.sin_family = AF_INET;
+ my_addr.sin_port = port;
+ my_addr.sin_addr.s_addr = INADDR_ANY;
+
+ if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&one, sizeof(one)) < 0)
+ warn ("setsockopt SO_REUSEADDR");
+
+ if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0)
+ err (1, "bind");
+
+ if (listen (sock, 1) < 0)
+ err (1, "listen");
+
+ sock2 = accept (sock, NULL, NULL);
+ if (sock2 < 0)
+ err (1, "accept");
+
+ return proto (sock2, service);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context = NULL; /* XXX */
+ int port = server_setup(&context, argc, argv);
+ return doit (port, service);
+}
diff --git a/crypto/heimdal/appl/test/nt_gss_client.c b/crypto/heimdal/appl/test/nt_gss_client.c
new file mode 100644
index 000000000000..e77f9f222599
--- /dev/null
+++ b/crypto/heimdal/appl/test/nt_gss_client.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+#include <gssapi.h>
+#include "nt_gss_common.h"
+
+RCSID("$Id: nt_gss_client.c,v 1.3 1999/12/04 18:16:19 assar Exp $");
+
+/*
+ * This program tries to act as a client for the sample in `Sample
+ * SSPI Code' in Windows 2000 RC1 SDK.
+ */
+
+static int
+proto (int sock, const char *hostname, const char *service)
+{
+ struct sockaddr_in remote, local;
+ int addrlen;
+
+ int context_established = 0;
+ gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
+ gss_buffer_t input_token, output_token;
+ gss_buffer_desc real_input_token, real_output_token;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t server;
+ gss_buffer_desc name_token;
+
+ name_token.length = asprintf ((char **)&name_token.value,
+ "%s@%s", service, hostname);
+
+ maj_stat = gss_import_name (&min_stat,
+ &name_token,
+ GSS_C_NT_HOSTBASED_SERVICE,
+ &server);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat,
+ "Error importing name `%s@%s':\n", service, hostname);
+
+ addrlen = sizeof(local);
+ if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
+ || addrlen != sizeof(local))
+ err (1, "getsockname(%s)", hostname);
+
+ addrlen = sizeof(remote);
+ if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
+ || addrlen != sizeof(remote))
+ err (1, "getpeername(%s)", hostname);
+
+ input_token = &real_input_token;
+ output_token = &real_output_token;
+
+ input_token->length = 0;
+ output_token->length = 0;
+
+ while(!context_established) {
+ maj_stat =
+ gss_init_sec_context(&min_stat,
+ GSS_C_NO_CREDENTIAL,
+ &context_hdl,
+ server,
+ GSS_C_NO_OID,
+ GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG,
+ 0,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ input_token,
+ NULL,
+ output_token,
+ NULL,
+ NULL);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_init_sec_context");
+ if (output_token->length != 0)
+ nt_write_token (sock, output_token);
+ if (GSS_ERROR(maj_stat)) {
+ if (context_hdl != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context (&min_stat,
+ &context_hdl,
+ GSS_C_NO_BUFFER);
+ break;
+ }
+ if (maj_stat & GSS_S_CONTINUE_NEEDED) {
+ nt_read_token (sock, input_token);
+ } else {
+ context_established = 1;
+ }
+
+ }
+
+ /* get_mic */
+
+ input_token->length = 3;
+ input_token->value = strdup("hej");
+
+ maj_stat = gss_get_mic(&min_stat,
+ context_hdl,
+ GSS_C_QOP_DEFAULT,
+ input_token,
+ output_token);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_get_mic");
+
+ nt_write_token (sock, input_token);
+ nt_write_token (sock, output_token);
+
+ /* wrap */
+
+ input_token->length = 7;
+ input_token->value = "hemligt";
+
+
+ maj_stat = gss_wrap (&min_stat,
+ context_hdl,
+ 1,
+ GSS_C_QOP_DEFAULT,
+ input_token,
+ NULL,
+ output_token);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_wrap");
+
+ nt_write_token (sock, output_token);
+
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context; /* XXX */
+ int port = client_setup(&context, &argc, argv);
+ return client_doit (argv[argc], port, service, proto);
+}
diff --git a/crypto/heimdal/appl/test/nt_gss_common.c b/crypto/heimdal/appl/test/nt_gss_common.c
new file mode 100644
index 000000000000..ab10355a054d
--- /dev/null
+++ b/crypto/heimdal/appl/test/nt_gss_common.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+#include <gssapi.h>
+#include "nt_gss_common.h"
+
+RCSID("$Id: nt_gss_common.c,v 1.3 1999/12/02 17:04:57 joda Exp $");
+
+/*
+ * These are functions that are needed to interoperate with the
+ * `Sample SSPI Code' in Windows 2000 RC1 SDK.
+ */
+
+/*
+ * Write the `gss_buffer_t' in `buf' onto the fd `sock', but remember that
+ * the length is written in little-endian-order.
+ */
+
+void
+nt_write_token (int sock, gss_buffer_t buf)
+{
+ unsigned char net_len[4];
+ u_int32_t len;
+ OM_uint32 min_stat;
+
+ len = buf->length;
+
+ net_len[0] = (len >> 0) & 0xFF;
+ net_len[1] = (len >> 8) & 0xFF;
+ net_len[2] = (len >> 16) & 0xFF;
+ net_len[3] = (len >> 24) & 0xFF;
+
+ if (write (sock, net_len, 4) != 4)
+ err (1, "write");
+ if (write (sock, buf->value, len) != len)
+ err (1, "write");
+
+ gss_release_buffer (&min_stat, buf);
+}
+
+/*
+ *
+ */
+
+void
+nt_read_token (int sock, gss_buffer_t buf)
+{
+ unsigned char net_len[4];
+ u_int32_t len;
+
+ if (read(sock, net_len, 4) != 4)
+ err (1, "read");
+ len = (net_len[0] << 0)
+ | (net_len[1] << 8)
+ | (net_len[2] << 16)
+ | (net_len[3] << 24);
+
+ buf->length = len;
+ buf->value = malloc(len);
+ if (read (sock, buf->value, len) != len)
+ err (1, "read");
+}
+
+void
+gss_print_errors (int min_stat)
+{
+ OM_uint32 new_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ OM_uint32 ret;
+
+ do {
+ ret = gss_display_status (&new_stat,
+ min_stat,
+ GSS_C_MECH_CODE,
+ GSS_C_NO_OID,
+ &msg_ctx,
+ &status_string);
+ fprintf (stderr, "%s\n", (char *)status_string.value);
+ gss_release_buffer (&new_stat, &status_string);
+ } while (!GSS_ERROR(ret) && msg_ctx != 0);
+}
+
+void
+gss_verr(int exitval, int status, const char *fmt, va_list ap)
+{
+ vwarnx (fmt, ap);
+ gss_print_errors (status);
+ exit (exitval);
+}
+
+void
+gss_err(int exitval, int status, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ gss_verr (exitval, status, fmt, args);
+ va_end(args);
+}
diff --git a/crypto/heimdal/appl/test/nt_gss_common.h b/crypto/heimdal/appl/test/nt_gss_common.h
new file mode 100644
index 000000000000..07428ddcd912
--- /dev/null
+++ b/crypto/heimdal/appl/test/nt_gss_common.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: nt_gss_common.h,v 1.2 1999/12/02 17:04:57 joda Exp $ */
+
+void nt_write_token (int sock, gss_buffer_t buf);
+void nt_read_token (int sock, gss_buffer_t buf);
+
+void gss_print_errors (int min_stat);
+
+void gss_verr(int exitval, int status, const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 3, 0)));
+
+void gss_err(int exitval, int status, const char *fmt, ...)
+ __attribute__ ((format (printf, 3, 4)));
diff --git a/crypto/heimdal/appl/test/nt_gss_server.c b/crypto/heimdal/appl/test/nt_gss_server.c
new file mode 100644
index 000000000000..9781ed19b768
--- /dev/null
+++ b/crypto/heimdal/appl/test/nt_gss_server.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+#include <gssapi.h>
+#include <krb5.h>
+#include "nt_gss_common.h"
+
+RCSID("$Id: nt_gss_server.c,v 1.3 1999/12/16 10:29:58 assar Exp $");
+
+/*
+ * This program tries to act as a server for the sample in `Sample
+ * SSPI Code' in Windows 2000 RC1 SDK.
+ *
+ * use --dump-add to get a binary dump of the authorization data in the ticket
+ */
+
+static int help_flag;
+static int version_flag;
+static char *port_str;
+char *service = SERVICE;
+static char *auth_file;
+
+static struct getargs args[] = {
+ { "port", 'p', arg_string, &port_str, "port to listen to", "port" },
+ { "service", 's', arg_string, &service, "service to use", "service" },
+ { "dump-auth", 0, arg_string, &auth_file, "dump authorization data",
+ "file" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 0, arg_flag, &version_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static int
+proto (int sock, const char *service)
+{
+ struct sockaddr_in remote, local;
+ int addrlen;
+ gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
+ gss_buffer_t input_token, output_token;
+ gss_buffer_desc real_input_token, real_output_token;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t client_name;
+ gss_buffer_desc name_token;
+
+ addrlen = sizeof(local);
+ if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
+ || addrlen != sizeof(local))
+ err (1, "getsockname)");
+
+ addrlen = sizeof(remote);
+ if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
+ || addrlen != sizeof(remote))
+ err (1, "getpeername");
+
+ input_token = &real_input_token;
+ output_token = &real_output_token;
+
+ do {
+ nt_read_token (sock, input_token);
+ maj_stat =
+ gss_accept_sec_context (&min_stat,
+ &context_hdl,
+ GSS_C_NO_CREDENTIAL,
+ input_token,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &client_name,
+ NULL,
+ output_token,
+ NULL,
+ NULL,
+ NULL);
+ if(GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_accept_sec_context");
+ if (output_token->length != 0)
+ nt_write_token (sock, output_token);
+ if (GSS_ERROR(maj_stat)) {
+ if (context_hdl != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context (&min_stat,
+ &context_hdl,
+ GSS_C_NO_BUFFER);
+ break;
+ }
+ } while(maj_stat & GSS_S_CONTINUE_NEEDED);
+
+ if (auth_file != NULL) {
+ int fd = open (auth_file, O_WRONLY | O_CREAT, 0666);
+ krb5_ticket *ticket = context_hdl->ticket;
+ krb5_data *data = &ticket->ticket.authorization_data->val[0].ad_data;
+
+ if(fd < 0)
+ err (1, "open %s", auth_file);
+ if (write (fd, data->data, data->length) != data->length)
+ errx (1, "write to %s failed", auth_file);
+ if (close (fd))
+ err (1, "close %s", auth_file);
+ }
+
+ maj_stat = gss_display_name (&min_stat,
+ client_name,
+ &name_token,
+ NULL);
+ if (GSS_ERROR(maj_stat))
+ gss_err (1, min_stat, "gss_display_name");
+
+ fprintf (stderr, "User is `%.*s'\n", (int)name_token.length,
+ (char *)name_token.value);
+
+ /* write something back */
+
+ output_token->value = strdup ("hejsan");
+ output_token->length = strlen (output_token->value) + 1;
+ nt_write_token (sock, output_token);
+
+ output_token->value = strdup ("hoppsan");
+ output_token->length = strlen (output_token->value) + 1;
+ nt_write_token (sock, output_token);
+
+ return 0;
+}
+
+static int
+doit (int port, const char *service)
+{
+ int sock, sock2;
+ struct sockaddr_in my_addr;
+ int one = 1;
+
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ err (1, "socket");
+
+ memset (&my_addr, 0, sizeof(my_addr));
+ my_addr.sin_family = AF_INET;
+ my_addr.sin_port = port;
+ my_addr.sin_addr.s_addr = INADDR_ANY;
+
+ if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&one, sizeof(one)) < 0)
+ warn ("setsockopt SO_REUSEADDR");
+
+ if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0)
+ err (1, "bind");
+
+ if (listen (sock, 1) < 0)
+ err (1, "listen");
+
+ sock2 = accept (sock, NULL, NULL);
+ if (sock2 < 0)
+ err (1, "accept");
+
+ return proto (sock2, service);
+}
+
+static void
+usage(int code, struct getargs *args, int num_args)
+{
+ arg_printusage(args, num_args, NULL, "");
+ exit(code);
+}
+
+static int
+common_setup(krb5_context *context, int *argc, char **argv,
+ void (*usage)(int, struct getargs*, int))
+{
+ int port = 0;
+ *argc = krb5_program_setup(context, *argc, argv, args, num_args, usage);
+
+ if(help_flag)
+ (*usage)(0, args, num_args);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ if(port_str){
+ struct servent *s = roken_getservbyname(port_str, "tcp");
+ if(s)
+ port = s->s_port;
+ else {
+ char *ptr;
+
+ port = strtol (port_str, &ptr, 10);
+ if (port == 0 && ptr == port_str)
+ errx (1, "Bad port `%s'", port_str);
+ port = htons(port);
+ }
+ }
+
+ if (port == 0)
+ port = krb5_getportbyname (*context, PORT, "tcp", 4711);
+
+ return port;
+}
+
+static int
+setup(krb5_context *context, int argc, char **argv)
+{
+ int port = common_setup(context, &argc, argv, usage);
+ if(argv[argc] != NULL)
+ usage(1, args, num_args);
+ return port;
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context = NULL; /* XXX */
+ int port = setup(&context, argc, argv);
+ return doit (port, service);
+}
diff --git a/crypto/heimdal/appl/test/tcp_client.c b/crypto/heimdal/appl/test/tcp_client.c
new file mode 100644
index 000000000000..7affc432a194
--- /dev/null
+++ b/crypto/heimdal/appl/test/tcp_client.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+RCSID("$Id: tcp_client.c,v 1.15 1999/12/16 10:30:17 assar Exp $");
+
+krb5_context context;
+
+static int
+proto (int sock, const char *hostname, const char *service)
+{
+ krb5_auth_context auth_context;
+ krb5_error_code status;
+ krb5_principal server;
+ krb5_data data;
+ krb5_data packet;
+ u_int32_t len, net_len;
+
+ status = krb5_auth_con_init (context, &auth_context);
+ if (status)
+ krb5_err (context, 1, status, "krb5_auth_con_init");
+
+ status = krb5_auth_con_setaddrs_from_fd (context,
+ auth_context,
+ &sock);
+ if (status)
+ krb5_err (context, 1, status, "krb5_auth_con_setaddrs_from_fd");
+
+ status = krb5_sname_to_principal (context,
+ hostname,
+ service,
+ KRB5_NT_SRV_HST,
+ &server);
+ if (status)
+ krb5_err (context, 1, status, "krb5_sname_to_principal");
+
+ status = krb5_sendauth (context,
+ &auth_context,
+ &sock,
+ VERSION,
+ NULL,
+ server,
+ AP_OPTS_MUTUAL_REQUIRED,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (status)
+ krb5_err (context, 1, status, "krb5_sendauth");
+
+ data.data = "hej";
+ data.length = 3;
+
+ krb5_data_zero (&packet);
+
+ status = krb5_mk_safe (context,
+ auth_context,
+ &data,
+ &packet,
+ NULL);
+ if (status)
+ krb5_err (context, 1, status, "krb5_mk_safe");
+
+ len = packet.length;
+ net_len = htonl(len);
+
+ if (krb5_net_write (context, &sock, &net_len, 4) != 4)
+ err (1, "krb5_net_write");
+ if (krb5_net_write (context, &sock, packet.data, len) != len)
+ err (1, "krb5_net_write");
+
+ data.data = "hemligt";
+ data.length = 7;
+
+ krb5_data_free (&packet);
+
+ status = krb5_mk_priv (context,
+ auth_context,
+ &data,
+ &packet,
+ NULL);
+ if (status)
+ krb5_err (context, 1, status, "krb5_mk_priv");
+
+ len = packet.length;
+ net_len = htonl(len);
+
+ if (krb5_net_write (context, &sock, &net_len, 4) != 4)
+ err (1, "krb5_net_write");
+ if (krb5_net_write (context, &sock, packet.data, len) != len)
+ err (1, "krb5_net_write");
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int port = client_setup(&context, &argc, argv);
+ return client_doit (argv[argc], port, service, proto);
+}
diff --git a/crypto/heimdal/appl/test/tcp_server.c b/crypto/heimdal/appl/test/tcp_server.c
new file mode 100644
index 000000000000..4469c5850e1e
--- /dev/null
+++ b/crypto/heimdal/appl/test/tcp_server.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+RCSID("$Id: tcp_server.c,v 1.16 1999/12/16 10:31:08 assar Exp $");
+
+krb5_context context;
+
+static int
+proto (int sock, const char *service)
+{
+ krb5_auth_context auth_context;
+ krb5_error_code status;
+ krb5_principal server;
+ krb5_ticket *ticket;
+ char *name;
+ char hostname[MAXHOSTNAMELEN];
+ krb5_data packet;
+ krb5_data data;
+ u_int32_t len, net_len;
+ ssize_t n;
+
+ status = krb5_auth_con_init (context, &auth_context);
+ if (status)
+ krb5_err (context, 1, status, "krb5_auth_con_init");
+
+ status = krb5_auth_con_setaddrs_from_fd (context,
+ auth_context,
+ &sock);
+
+ if (status)
+ krb5_err (context, 1, status, "krb5_auth_con_setaddrs_from_fd");
+
+ if(gethostname (hostname, sizeof(hostname)) < 0)
+ krb5_err (context, 1, errno, "gethostname");
+
+ status = krb5_sname_to_principal (context,
+ hostname,
+ service,
+ KRB5_NT_SRV_HST,
+ &server);
+ if (status)
+ krb5_err (context, 1, status, "krb5_sname_to_principal");
+
+ status = krb5_recvauth (context,
+ &auth_context,
+ &sock,
+ VERSION,
+ server,
+ 0,
+ NULL,
+ &ticket);
+ if (status)
+ krb5_err (context, 1, status, "krb5_recvauth");
+
+ status = krb5_unparse_name (context,
+ ticket->client,
+ &name);
+ if (status)
+ krb5_err (context, 1, status, "krb5_unparse_name");
+
+ fprintf (stderr, "User is `%s'\n", name);
+ free (name);
+
+ krb5_data_zero (&data);
+ krb5_data_zero (&packet);
+
+ n = krb5_net_read (context, &sock, &net_len, 4);
+ if (n == 0)
+ krb5_errx (context, 1, "EOF in krb5_net_read");
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+
+ len = ntohl(net_len);
+
+ krb5_data_alloc (&packet, len);
+
+ n = krb5_net_read (context, &sock, packet.data, len);
+ if (n == 0)
+ krb5_errx (context, 1, "EOF in krb5_net_read");
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+
+ status = krb5_rd_safe (context,
+ auth_context,
+ &packet,
+ &data,
+ NULL);
+ if (status)
+ krb5_err (context, 1, status, "krb5_rd_safe");
+
+ fprintf (stderr, "safe packet: %.*s\n", (int)data.length,
+ (char *)data.data);
+
+ n = krb5_net_read (context, &sock, &net_len, 4);
+ if (n == 0)
+ krb5_errx (context, 1, "EOF in krb5_net_read");
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+
+ len = ntohl(net_len);
+
+ krb5_data_alloc (&packet, len);
+
+ n = krb5_net_read (context, &sock, packet.data, len);
+ if (n == 0)
+ krb5_errx (context, 1, "EOF in krb5_net_read");
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+
+ status = krb5_rd_priv (context,
+ auth_context,
+ &packet,
+ &data,
+ NULL);
+ if (status)
+ krb5_err (context, 1, status, "krb5_rd_priv");
+
+ fprintf (stderr, "priv packet: %.*s\n", (int)data.length,
+ (char *)data.data);
+
+ return 0;
+}
+
+static int
+doit (int port, const char *service)
+{
+ mini_inetd (port);
+
+ return proto (STDIN_FILENO, service);
+}
+
+int
+main(int argc, char **argv)
+{
+ int port = server_setup(&context, argc, argv);
+ return doit (port, service);
+}
diff --git a/crypto/heimdal/appl/test/test_locl.h b/crypto/heimdal/appl/test/test_locl.h
new file mode 100644
index 000000000000..045d060d8922
--- /dev/null
+++ b/crypto/heimdal/appl/test/test_locl.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: test_locl.h,v 1.7 1999/12/04 18:17:07 assar Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <errno.h>
+#include <roken.h>
+#include <getarg.h>
+#include <err.h>
+#include <krb5.h>
+
+#define SERVICE "test"
+
+#define PORT "test"
+
+extern char *service;
+int server_setup(krb5_context*, int, char**);
+int client_setup(krb5_context*, int*, char**);
+int client_doit (const char *hostname, int port, const char *service,
+ int (*func)(int, const char *hostname, const char *service));
diff --git a/crypto/heimdal/appl/test/uu_client.c b/crypto/heimdal/appl/test/uu_client.c
new file mode 100644
index 000000000000..204f9197883f
--- /dev/null
+++ b/crypto/heimdal/appl/test/uu_client.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+RCSID("$Id: uu_client.c,v 1.5 1999/12/04 18:17:26 assar Exp $");
+
+krb5_context context;
+
+static int
+proto (int sock, const char *hostname, const char *service)
+{
+ struct sockaddr_in remote, local;
+ int addrlen;
+ krb5_address remote_addr, local_addr;
+ krb5_context context;
+ krb5_ccache ccache;
+ krb5_auth_context auth_context;
+ krb5_error_code status;
+ krb5_principal client;
+ krb5_data data;
+ krb5_data packet;
+ krb5_creds mcred, cred;
+
+ addrlen = sizeof(local);
+ if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
+ || addrlen != sizeof(local))
+ err (1, "getsockname(%s)", hostname);
+
+ addrlen = sizeof(remote);
+ if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
+ || addrlen != sizeof(remote))
+ err (1, "getpeername(%s)", hostname);
+
+ status = krb5_init_context(&context);
+ if (status)
+ krb5_err(context, 1, status, "krb5_init_context");
+
+ status = krb5_cc_default (context, &ccache);
+ if (status)
+ krb5_err(context, 1, status, "krb5_cc_default");
+
+ status = krb5_auth_con_init (context, &auth_context);
+ if (status)
+ krb5_err(context, 1, status, "krb5_auth_con_init");
+
+ local_addr.addr_type = AF_INET;
+ local_addr.address.length = sizeof(local.sin_addr);
+ local_addr.address.data = &local.sin_addr;
+
+ remote_addr.addr_type = AF_INET;
+ remote_addr.address.length = sizeof(remote.sin_addr);
+ remote_addr.address.data = &remote.sin_addr;
+
+ status = krb5_auth_con_setaddrs (context,
+ auth_context,
+ &local_addr,
+ &remote_addr);
+ if (status)
+ krb5_err(context, 1, status, "krb5_auth_con_setaddr");
+
+ status = krb5_cc_get_principal(context, ccache, &client);
+ if(status)
+ krb5_err(context, 1, status, "krb5_cc_get_principal");
+ status = krb5_make_principal(context, &mcred.server,
+ *krb5_princ_realm(context, client),
+ "krbtgt",
+ *krb5_princ_realm(context, client),
+ NULL);
+ if(status)
+ krb5_err(context, 1, status, "krb5_make_principal");
+
+ status = krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
+ if(status)
+ krb5_err(context, 1, status, "krb5_cc_retrieve_cred");
+
+ {
+ char *client_name;
+ krb5_data data;
+ status = krb5_unparse_name(context, cred.client, &client_name);
+ if(status)
+ krb5_err(context, 1, status, "krb5_unparse_name");
+ data.data = client_name;
+ data.length = strlen(client_name) + 1;
+ status = krb5_write_message(context, &sock, &data);
+ if(status)
+ krb5_err(context, 1, status, "krb5_write_message");
+ free(client_name);
+ }
+
+ status = krb5_write_message(context, &sock, &cred.ticket);
+ if(status)
+ krb5_err(context, 1, status, "krb5_write_message");
+
+ status = krb5_auth_con_setuserkey(context, auth_context, &cred.session);
+ if(status)
+ krb5_err(context, 1, status, "krb5_auth_con_setuserkey");
+
+ status = krb5_recvauth(context, &auth_context, &sock,
+ VERSION, client, 0, NULL, NULL);
+
+ if (status)
+ krb5_err(context, 1, status, "krb5_recvauth");
+
+ data.data = "hej";
+ data.length = 3;
+
+ krb5_data_zero (&packet);
+
+ status = krb5_mk_safe (context,
+ auth_context,
+ &data,
+ &packet,
+ NULL);
+ if (status)
+ krb5_err(context, 1, status, "krb5_mk_safe");
+
+ status = krb5_write_message(context, &sock, &packet);
+ if(status)
+ krb5_err(context, 1, status, "krb5_write_message");
+
+ data.data = "hemligt";
+ data.length = 7;
+
+ krb5_data_free (&packet);
+
+ status = krb5_mk_priv (context,
+ auth_context,
+ &data,
+ &packet,
+ NULL);
+ if (status)
+ krb5_err(context, 1, status, "krb5_mk_priv");
+
+ status = krb5_write_message(context, &sock, &packet);
+ if(status)
+ krb5_err(context, 1, status, "krb5_write_message");
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int port = client_setup(&context, &argc, argv);
+ return client_doit (argv[argc], port, service, proto);
+}
diff --git a/crypto/heimdal/appl/test/uu_server.c b/crypto/heimdal/appl/test/uu_server.c
new file mode 100644
index 000000000000..fabfea252a6b
--- /dev/null
+++ b/crypto/heimdal/appl/test/uu_server.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "test_locl.h"
+RCSID("$Id: uu_server.c,v 1.6 1999/12/16 10:32:44 assar Exp $");
+
+krb5_context context;
+
+static int
+proto (int sock, const char *service)
+{
+ struct sockaddr_in remote, local;
+ int addrlen;
+ krb5_address remote_addr, local_addr;
+ krb5_ccache ccache;
+ krb5_auth_context auth_context;
+ krb5_error_code status;
+ krb5_data packet;
+ krb5_data data;
+ krb5_data client_name;
+ krb5_creds in_creds, *out_creds;
+
+ addrlen = sizeof(local);
+ if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
+ || addrlen != sizeof(local))
+ err (1, "getsockname)");
+
+ addrlen = sizeof(remote);
+ if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
+ || addrlen != sizeof(remote))
+ err (1, "getpeername");
+
+ status = krb5_auth_con_init (context, &auth_context);
+ if (status)
+ errx (1, "krb5_auth_con_init: %s",
+ krb5_get_err_text(context, status));
+
+ local_addr.addr_type = AF_INET;
+ local_addr.address.length = sizeof(local.sin_addr);
+ local_addr.address.data = &local.sin_addr;
+
+ remote_addr.addr_type = AF_INET;
+ remote_addr.address.length = sizeof(remote.sin_addr);
+ remote_addr.address.data = &remote.sin_addr;
+
+ status = krb5_auth_con_setaddrs (context,
+ auth_context,
+ &local_addr,
+ &remote_addr);
+ if (status)
+ errx (1, "krb5_auth_con_setaddr: %s",
+ krb5_get_err_text(context, status));
+
+ status = krb5_read_message(context, &sock, &client_name);
+ if(status)
+ krb5_err(context, 1, status, "krb5_read_message");
+
+ memset(&in_creds, 0, sizeof(in_creds));
+ status = krb5_cc_default(context, &ccache);
+ status = krb5_cc_get_principal(context, ccache, &in_creds.client);
+
+ status = krb5_read_message(context, &sock, &in_creds.second_ticket);
+ if(status)
+ krb5_err(context, 1, status, "krb5_read_message");
+
+ status = krb5_parse_name(context, client_name.data, &in_creds.server);
+ if(status)
+ krb5_err(context, 1, status, "krb5_parse_name");
+
+ status = krb5_get_credentials(context, KRB5_GC_USER_USER, ccache,
+ &in_creds, &out_creds);
+ if(status)
+ krb5_err(context, 1, status, "krb5_get_credentials");
+
+ status = krb5_cc_default(context, &ccache);
+
+ status = krb5_sendauth(context,
+ &auth_context,
+ &sock,
+ VERSION,
+ in_creds.client,
+ in_creds.server,
+ AP_OPTS_USE_SESSION_KEY,
+ NULL,
+ out_creds,
+ ccache,
+ NULL,
+ NULL,
+ NULL);
+
+ if (status)
+ krb5_err(context, 1, status, "krb5_sendauth");
+
+ fprintf (stderr, "User is `%.*s'\n", (int)client_name.length,
+ (char *)client_name.data);
+
+ krb5_data_zero (&data);
+ krb5_data_zero (&packet);
+
+ status = krb5_read_message(context, &sock, &packet);
+ if(status)
+ krb5_err(context, 1, status, "krb5_read_message");
+
+ status = krb5_rd_safe (context,
+ auth_context,
+ &packet,
+ &data,
+ NULL);
+ if (status)
+ errx (1, "krb5_rd_safe: %s",
+ krb5_get_err_text(context, status));
+
+ fprintf (stderr, "safe packet: %.*s\n", (int)data.length,
+ (char *)data.data);
+
+ status = krb5_read_message(context, &sock, &packet);
+ if(status)
+ krb5_err(context, 1, status, "krb5_read_message");
+
+ status = krb5_rd_priv (context,
+ auth_context,
+ &packet,
+ &data,
+ NULL);
+ if (status)
+ errx (1, "krb5_rd_priv: %s",
+ krb5_get_err_text(context, status));
+
+ fprintf (stderr, "priv packet: %.*s\n", (int)data.length,
+ (char *)data.data);
+
+ return 0;
+}
+
+static int
+doit (int port, const char *service)
+{
+ int sock, sock2;
+ struct sockaddr_in my_addr;
+ int one = 1;
+
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ err (1, "socket");
+
+ memset (&my_addr, 0, sizeof(my_addr));
+ my_addr.sin_family = AF_INET;
+ my_addr.sin_port = port;
+ my_addr.sin_addr.s_addr = INADDR_ANY;
+
+ if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&one, sizeof(one)) < 0)
+ warn ("setsockopt SO_REUSEADDR");
+
+ if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0)
+ err (1, "bind");
+
+ if (listen (sock, 1) < 0)
+ err (1, "listen");
+
+ sock2 = accept (sock, NULL, NULL);
+ if (sock2 < 0)
+ err (1, "accept");
+
+ return proto (sock2, service);
+}
+
+int
+main(int argc, char **argv)
+{
+ int port = server_setup(&context, argc, argv);
+ return doit (port, service);
+}
diff --git a/crypto/heimdal/cf/ChangeLog b/crypto/heimdal/cf/ChangeLog
new file mode 100644
index 000000000000..2c21ce2fad8c
--- /dev/null
+++ b/crypto/heimdal/cf/ChangeLog
@@ -0,0 +1,235 @@
+2000-01-08 Assar Westerlund <assar@sics.se>
+
+ * krb-bigendian.m4: new file, replacement for ac_c_bigendian
+
+2000-01-01 Assar Westerlund <assar@sics.se>
+
+ * krb-ipv6.m4: re-organize: test for type of stack first so that
+ we can find the libraries that we might have to link the test
+ program against. not linking the test program means we don't know
+ if the right stuff is in the libraries. also cosmetic changes to
+ make sure we print the checking for... nicely
+
+1999-12-21 Assar Westerlund <assar@sics.se>
+
+ * krb-ipv6.m4: try linking, not only compiling
+ * krb-ipv6.m4: add --without-ipv6 make sure we have `in6addr_any'
+ which we use in the code. This test avoids false positives on
+ OpenBSD
+
+1999-11-05 Assar Westerlund <assar@sics.se>
+
+ * check-x.m4: include X_PRE_LIBS and X_EXTRA_LIBS when testing
+
+1999-11-01 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am.common (install-build-headers): use `cp' instead of
+ INSTALL_DATA for copying header files inside the build tree. The
+ user might have redefined INSTALL_DATA to specify owners and other
+ information.
+
+1999-10-30 Assar Westerlund <assar@sics.se>
+
+ * find-func-no-libs2.m4: add yet another argument to allow specify
+ linker flags that will be added _before_ the library when trying
+ to link
+
+ * find-func-no-libs.m4: add yet another argument to allow specify
+ linker flags that will be added _before_ the library when trying
+ to link
+
+1999-10-12 Assar Westerlund <assar@sics.se>
+
+ * find-func-no-libs2.m4 (AC_FIND_FUNC_NO_LIBS2): new argument
+ `extra libs'
+
+ * find-func-no-libs.m4 (AC_FIND_FUNC_NO_LIBS): new argument `extra
+ libs'
+
+1999-09-01 Johan Danielsson <joda@pdc.kth.se>
+
+ * capabilities.m4: sgi capabilities
+
+1999-07-29 Assar Westerlund <assar@sics.se>
+
+ * have-struct-field.m4: quote macros when undefining
+
+1999-07-28 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am.common (install-build-headers): add dependencies
+
+1999-07-24 Assar Westerlund <assar@sics.se>
+
+ * have-type.m4: try to get autoheader to co-operate
+
+ * have-type.m4: stolen from Arla
+
+ * krb-struct-sockaddr-sa-len.m4: not used any longer. removed.
+
+1999-06-13 Assar Westerlund <assar@sics.se>
+
+ * krb-struct-spwd.m4: consequent name of cache variables
+
+ * krb-func-getlogin.m4: new file for testing for posix (broken)
+ getlogin
+
+ * shared-libs.m4 (freebsd[34]): don't use ld -Bshareable
+
+1999-06-02 Johan Danielsson <joda@pdc.kth.se>
+
+ * check-x.m4: extended test for X
+
+1999-05-14 Assar Westerlund <assar@sics.se>
+
+ * check-netinet-ip-and-tcp.m4: proper autoheader tricks
+
+ * check-netinet-ip-and-tcp.m4: new file for checking for
+ netinet/{ip,tcp}.h. These are special as they on Irix 6.5.3
+ require <standards.h> to be included in advance.
+
+ * check-xau.m4: we also need to check for XauFilename since it's
+ used by appl/kx. And on Irix 6.5 that function requires linking
+ with -lX11.
+
+1999-05-08 Assar Westerlund <assar@sics.se>
+
+ * krb-find-db.m4: try with more header files than ndbm.h
+
+1999-04-19 Assar Westerlund <assar@sics.se>
+
+ * test-package.m4: try to handle the case of --without-package
+ correctly
+
+1999-04-17 Assar Westerlund <assar@sics.se>
+
+ * make-aclocal: removed. Not used anymore, being replaced by
+ aclocal from automake.
+
+Thu Apr 15 14:17:26 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * make-proto.pl: handle __attribute__
+
+Fri Apr 9 20:37:18 1999 Assar Westerlund <assar@sics.se>
+
+ * shared-libs.m4: quote $@
+ (freebsd3): add install_symlink_command2
+
+Wed Apr 7 20:40:22 1999 Assar Westerlund <assar@sics.se>
+
+ * shared-libs.m4 (hpux): no library dependencies
+
+Mon Apr 5 16:13:08 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * test-package.m4: compile and link, rather than looking for
+ files; also export more information, so it's possible to add rpath
+ information
+
+Tue Mar 30 13:49:54 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am.common: CFLAGS -> AM_CFLAGS
+
+Mon Mar 29 16:51:12 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * check-xau.m4: check for XauWriteAuth before checking for
+ XauReadAuth to catch -lX11:s not containing XauWriteAuth, and IRIX
+ 6.5 that doesn't work with -lXau
+
+Sat Mar 27 18:03:58 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * osfc2.m4: --enable-osfc2
+
+Fri Mar 19 15:34:52 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * shared-libs.m4: move shared lib stuff here
+
+Wed Mar 24 23:24:51 1999 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am.common (install-build-headers): simplify loop
+
+Tue Mar 23 17:31:23 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * check-getpwnam_r-posix.m4: check for getpwnam_r, and if it's
+ posix or not
+
+Tue Mar 23 00:00:13 1999 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am.common (install_build_headers): try to make it work
+ better when list of headers is empty. handle make rewriting the
+ filenames.
+
+ * Makefile.am.common: hesoid -> hesiod
+
+Sun Mar 21 14:48:03 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * grok-type.m4: <bind/bitypes.h>
+
+ * Makefile.am.common: fix for automake bug/feature; add more LIB_*
+
+ * test-package.m4: fix typo
+
+ * check-man.m4: fix some typos
+
+ * auth-modules.m4: tests for authentication modules
+
+Thu Mar 18 11:02:55 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am.common: make install-build-headers a multi
+ dependency target
+
+ * Makefile.am.common: remove include_dir hack
+
+ * Makefile.am.common: define LIB_kafs and LIB_gssapi
+
+ * krb-find-db.m4: subst DBLIB also
+
+ * check-xau.m4: test for Xau{Read,Write}Auth
+
+Wed Mar 10 19:29:20 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * wflags.m4: AC_WFLAGS
+
+Mon Mar 1 11:23:41 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * have-struct-field.m4: remove extra AC_MSG_RESULT
+
+ * proto-compat.m4: typo
+
+ * krb-func-getcwd-broken.m4: update to autoconf 2.13
+
+ * krb-find-db.m4: update to autoconf 2.13
+
+ * check-declaration.m4: typo
+
+ * have-pragma-weak.m4: update to autoconf 2.13
+
+ * have-struct-field.m4: better handling of types with spaces
+
+Mon Feb 22 20:05:06 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * broken-glob.m4: check for broken glob
+
+Sun Jan 31 06:50:33 1999 Assar Westerlund <assar@sics.se>
+
+ * krb-ipv6.m4: more magic for different v6 implementations. From
+ Jun-ichiro itojun Hagino <itojun@kame.net>
+
+Sun Nov 22 12:16:06 1998 Assar Westerlund <assar@sics.se>
+
+ * krb-struct-spwd.m4: new file
+
+Thu Jun 4 04:07:41 1998 Assar Westerlund <assar@sics.se>
+
+ * find-func-no-libs2.m4: new file
+
+Fri May 1 23:31:28 1998 Assar Westerlund <assar@sics.se>
+
+ * c-attribute.m4, c-function.m4: new files (from arla)
+
+Wed Mar 18 23:11:29 1998 Assar Westerlund <assar@sics.se>
+
+ * krb-ipv6.m4: rename HAVE_STRUCT_SOCKADDR_IN6 to HAVE_IPV6
+
+Thu Feb 26 02:37:49 1998 Assar Westerlund <assar@sics.se>
+
+ * make-proto.pl: should work with perl4
+
diff --git a/crypto/heimdal/cf/Makefile.am.common b/crypto/heimdal/cf/Makefile.am.common
new file mode 100644
index 000000000000..e7d747b269dc
--- /dev/null
+++ b/crypto/heimdal/cf/Makefile.am.common
@@ -0,0 +1,255 @@
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS += $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+## set build_HEADERZ to headers that should just be installed in build tree
+
+buildinclude = $(top_builddir)/include
+
+## these aren't detected by automake
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+LIB_readline = @LIB_readline@
+
+LEXLIB = @LEXLIB@
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+SUFFIXES += .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8
+
+NROFF_MAN = groff -mandoc -Tascii
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+## MAINTAINERCLEANFILES +=
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+if KRB4
+LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+endif
+
+if KRB5
+LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/asn1/libasn1.la
+LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+endif
+
diff --git a/crypto/heimdal/cf/auth-modules.m4 b/crypto/heimdal/cf/auth-modules.m4
new file mode 100644
index 000000000000..2f11c7354cde
--- /dev/null
+++ b/crypto/heimdal/cf/auth-modules.m4
@@ -0,0 +1,27 @@
+dnl $Id: auth-modules.m4,v 1.1 1999/03/21 13:48:00 joda Exp $
+dnl
+dnl Figure what authentication modules should be built
+
+AC_DEFUN(AC_AUTH_MODULES,[
+AC_MSG_CHECKING(which authentication modules should be built)
+
+LIB_AUTH_SUBDIRS=
+
+if test "$ac_cv_header_siad_h" = yes; then
+ LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS sia"
+fi
+
+if test "$ac_cv_header_security_pam_modules_h" = yes -a "$enable_shared" = yes; then
+ LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS pam"
+fi
+
+case "${host}" in
+changequote(,)dnl
+*-*-irix[56]*) LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS afskauthlib" ;;
+changequote([,])dnl
+esac
+
+AC_MSG_RESULT($LIB_AUTH_SUBDIRS)
+
+AC_SUBST(LIB_AUTH_SUBDIRS)dnl
+])
diff --git a/crypto/heimdal/cf/broken-glob.m4 b/crypto/heimdal/cf/broken-glob.m4
new file mode 100644
index 000000000000..8d5279275006
--- /dev/null
+++ b/crypto/heimdal/cf/broken-glob.m4
@@ -0,0 +1,22 @@
+dnl $Id: broken-glob.m4,v 1.2 1999/03/01 09:52:15 joda Exp $
+dnl
+dnl check for glob(3)
+dnl
+AC_DEFUN(AC_BROKEN_GLOB,[
+AC_CACHE_CHECK(for working glob, ac_cv_func_glob_working,
+ac_cv_func_glob_working=yes
+AC_TRY_LINK([
+#include <stdio.h>
+#include <glob.h>],[
+glob(NULL, GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE, NULL, NULL);
+],:,ac_cv_func_glob_working=no,:))
+
+if test "$ac_cv_func_glob_working" = yes; then
+ AC_DEFINE(HAVE_GLOB, 1, [define if you have a glob() that groks
+ GLOB_BRACE, GLOB_NOCHECK, GLOB_QUOTE, and GLOB_TILDE])
+fi
+if test "$ac_cv_func_glob_working" = yes; then
+AC_NEED_PROTO([#include <stdio.h>
+#include <glob.h>],glob)
+fi
+])
diff --git a/crypto/heimdal/cf/broken-snprintf.m4 b/crypto/heimdal/cf/broken-snprintf.m4
new file mode 100644
index 000000000000..efd69f0aa53d
--- /dev/null
+++ b/crypto/heimdal/cf/broken-snprintf.m4
@@ -0,0 +1,58 @@
+dnl $Id: broken-snprintf.m4,v 1.3 1999/03/01 09:52:22 joda Exp $
+dnl
+AC_DEFUN(AC_BROKEN_SNPRINTF, [
+AC_CACHE_CHECK(for working snprintf,ac_cv_func_snprintf_working,
+ac_cv_func_snprintf_working=yes
+AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+int main()
+{
+changequote(`,')dnl
+ char foo[3];
+changequote([,])dnl
+ snprintf(foo, 2, "12");
+ return strcmp(foo, "1");
+}],:,ac_cv_func_snprintf_working=no,:))
+
+if test "$ac_cv_func_snprintf_working" = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_SNPRINTF, 1, [define if you have a working snprintf])
+fi
+if test "$ac_cv_func_snprintf_working" = yes; then
+AC_NEED_PROTO([#include <stdio.h>],snprintf)
+fi
+])
+
+AC_DEFUN(AC_BROKEN_VSNPRINTF,[
+AC_CACHE_CHECK(for working vsnprintf,ac_cv_func_vsnprintf_working,
+ac_cv_func_vsnprintf_working=yes
+AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+int foo(int num, ...)
+{
+changequote(`,')dnl
+ char bar[3];
+changequote([,])dnl
+ va_list arg;
+ va_start(arg, num);
+ vsnprintf(bar, 2, "%s", arg);
+ va_end(arg);
+ return strcmp(bar, "1");
+}
+
+
+int main()
+{
+ return foo(0, "12");
+}],:,ac_cv_func_vsnprintf_working=no,:))
+
+if test "$ac_cv_func_vsnprintf_working" = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_VSNPRINTF, 1, [define if you have a working vsnprintf])
+fi
+if test "$ac_cv_func_vsnprintf_working" = yes; then
+AC_NEED_PROTO([#include <stdio.h>],vsnprintf)
+fi
+])
diff --git a/crypto/heimdal/cf/broken.m4 b/crypto/heimdal/cf/broken.m4
new file mode 100644
index 000000000000..404406470476
--- /dev/null
+++ b/crypto/heimdal/cf/broken.m4
@@ -0,0 +1,19 @@
+dnl $Id: broken.m4,v 1.3 1998/03/16 22:16:19 joda Exp $
+dnl
+dnl
+dnl Same as AC _REPLACE_FUNCS, just define HAVE_func if found in normal
+dnl libraries
+
+AC_DEFUN(AC_BROKEN,
+[for ac_func in $1
+do
+AC_CHECK_FUNC($ac_func, [
+ac_tr_func=HAVE_[]upcase($ac_func)
+AC_DEFINE_UNQUOTED($ac_tr_func)],[LIBOBJS[]="$LIBOBJS ${ac_func}.o"])
+dnl autoheader tricks *sigh*
+: << END
+@@@funcs="$funcs $1"@@@
+END
+done
+AC_SUBST(LIBOBJS)dnl
+])
diff --git a/crypto/heimdal/cf/c-attribute.m4 b/crypto/heimdal/cf/c-attribute.m4
new file mode 100644
index 000000000000..87cea037b173
--- /dev/null
+++ b/crypto/heimdal/cf/c-attribute.m4
@@ -0,0 +1,31 @@
+dnl
+dnl $Id: c-attribute.m4,v 1.2 1999/03/01 09:52:23 joda Exp $
+dnl
+
+dnl
+dnl Test for __attribute__
+dnl
+
+AC_DEFUN(AC_C___ATTRIBUTE__, [
+AC_MSG_CHECKING(for __attribute__)
+AC_CACHE_VAL(ac_cv___attribute__, [
+AC_TRY_COMPILE([
+#include <stdlib.h>
+],
+[
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+ exit(1);
+}
+],
+ac_cv___attribute__=yes,
+ac_cv___attribute__=no)])
+if test "$ac_cv___attribute__" = "yes"; then
+ AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
+fi
+AC_MSG_RESULT($ac_cv___attribute__)
+])
+
diff --git a/crypto/heimdal/cf/c-function.m4 b/crypto/heimdal/cf/c-function.m4
new file mode 100644
index 000000000000..b16d5562bb0a
--- /dev/null
+++ b/crypto/heimdal/cf/c-function.m4
@@ -0,0 +1,33 @@
+dnl
+dnl $Id: c-function.m4,v 1.2 1999/03/01 09:52:23 joda Exp $
+dnl
+
+dnl
+dnl Test for __FUNCTION__
+dnl
+
+AC_DEFUN(AC_C___FUNCTION__, [
+AC_MSG_CHECKING(for __FUNCTION__)
+AC_CACHE_VAL(ac_cv___function__, [
+AC_TRY_RUN([
+#include <string.h>
+
+static char *foo()
+{
+ return __FUNCTION__;
+}
+
+int main()
+{
+ return strcmp(foo(), "foo") != 0;
+}
+],
+ac_cv___function__=yes,
+ac_cv___function__=no,
+ac_cv___function__=no)])
+if test "$ac_cv___function__" = "yes"; then
+ AC_DEFINE(HAVE___FUNCTION__, 1, [define if your compiler has __FUNCTION__])
+fi
+AC_MSG_RESULT($ac_cv___function__)
+])
+
diff --git a/crypto/heimdal/cf/capabilities.m4 b/crypto/heimdal/cf/capabilities.m4
new file mode 100644
index 000000000000..6d2669bfe130
--- /dev/null
+++ b/crypto/heimdal/cf/capabilities.m4
@@ -0,0 +1,14 @@
+dnl
+dnl $Id: capabilities.m4,v 1.2 1999/09/01 11:02:26 joda Exp $
+dnl
+
+dnl
+dnl Test SGI capabilities
+dnl
+
+AC_DEFUN(KRB_CAPABILITIES,[
+
+AC_CHECK_HEADERS(capability.h sys/capability.h)
+
+AC_CHECK_FUNCS(sgi_getcapabilitybyname cap_set_proc)
+])
diff --git a/crypto/heimdal/cf/check-declaration.m4 b/crypto/heimdal/cf/check-declaration.m4
new file mode 100644
index 000000000000..5f584e5c38f3
--- /dev/null
+++ b/crypto/heimdal/cf/check-declaration.m4
@@ -0,0 +1,25 @@
+dnl $Id: check-declaration.m4,v 1.3 1999/03/01 13:03:08 joda Exp $
+dnl
+dnl
+dnl Check if we need the declaration of a variable
+dnl
+
+dnl AC_HAVE_DECLARATION(includes, variable)
+AC_DEFUN(AC_CHECK_DECLARATION, [
+AC_MSG_CHECKING([if $2 is properly declared])
+AC_CACHE_VAL(ac_cv_var_$2_declaration, [
+AC_TRY_COMPILE([$1
+extern struct { int foo; } $2;],
+[$2.foo = 1;],
+eval "ac_cv_var_$2_declaration=no",
+eval "ac_cv_var_$2_declaration=yes")
+])
+
+define(foo, [HAVE_]translit($2, [a-z], [A-Z])[_DECLARATION])
+
+AC_MSG_RESULT($ac_cv_var_$2_declaration)
+if eval "test \"\$ac_cv_var_$2_declaration\" = yes"; then
+ AC_DEFINE(foo, 1, [define if your system declares $2])
+fi
+undefine([foo])
+])
diff --git a/crypto/heimdal/cf/check-getpwnam_r-posix.m4 b/crypto/heimdal/cf/check-getpwnam_r-posix.m4
new file mode 100644
index 000000000000..cc75666a6daf
--- /dev/null
+++ b/crypto/heimdal/cf/check-getpwnam_r-posix.m4
@@ -0,0 +1,24 @@
+dnl $Id: check-getpwnam_r-posix.m4,v 1.2 1999/03/23 16:47:31 joda Exp $
+dnl
+dnl check for getpwnam_r, and if it's posix or not
+
+AC_DEFUN(AC_CHECK_GETPWNAM_R_POSIX,[
+AC_FIND_FUNC_NO_LIBS(getpwnam_r,c_r)
+if test "$ac_cv_func_getpwnam_r" = yes; then
+ AC_CACHE_CHECK(if getpwnam_r is posix,ac_cv_func_getpwnam_r_posix,
+ ac_libs="$LIBS"
+ LIBS="$LIBS $LIB_getpwnam_r"
+ AC_TRY_RUN([
+#include <pwd.h>
+int main()
+{
+ struct passwd pw, *pwd;
+ return getpwnam_r("", &pw, NULL, 0, &pwd) < 0;
+}
+],ac_cv_func_getpwnam_r_posix=yes,ac_cv_func_getpwnam_r_posix=no,:)
+LIBS="$ac_libs")
+if test "$ac_cv_func_getpwnam_r_posix" = yes; then
+ AC_DEFINE(POSIX_GETPWNAM_R, 1, [Define if getpwnam_r has POSIX flavour.])
+fi
+fi
+]) \ No newline at end of file
diff --git a/crypto/heimdal/cf/check-man.m4 b/crypto/heimdal/cf/check-man.m4
new file mode 100644
index 000000000000..21330697d499
--- /dev/null
+++ b/crypto/heimdal/cf/check-man.m4
@@ -0,0 +1,59 @@
+dnl $Id: check-man.m4,v 1.2 1999/03/21 14:30:50 joda Exp $
+dnl check how to format manual pages
+dnl
+
+AC_DEFUN(AC_CHECK_MAN,
+[AC_PATH_PROG(NROFF, nroff)
+AC_PATH_PROG(GROFF, groff)
+AC_CACHE_CHECK(how to format man pages,ac_cv_sys_man_format,
+[cat > conftest.1 << END
+.Dd January 1, 1970
+.Dt CONFTEST 1
+.Sh NAME
+.Nm conftest
+.Nd
+foobar
+END
+
+if test "$NROFF" ; then
+ for i in "-mdoc" "-mandoc"; do
+ if "$NROFF" $i conftest.1 2> /dev/null | \
+ grep Jan > /dev/null 2>&1 ; then
+ ac_cv_sys_man_format="$NROFF $i"
+ break
+ fi
+ done
+fi
+if test "$ac_cv_sys_man_format" = "" -a "$GROFF" ; then
+ for i in "-mdoc" "-mandoc"; do
+ if "$GROFF" -Tascii $i conftest.1 2> /dev/null | \
+ grep Jan > /dev/null 2>&1 ; then
+ ac_cv_sys_man_format="$GROFF -Tascii $i"
+ break
+ fi
+ done
+fi
+if test "$ac_cv_sys_man_format"; then
+ ac_cv_sys_man_format="$ac_cv_sys_man_format \[$]< > \[$]@"
+fi
+])
+if test "$ac_cv_sys_man_format"; then
+ CATMAN="$ac_cv_sys_man_format"
+ AC_SUBST(CATMAN)
+fi
+AM_CONDITIONAL(CATMAN, test "$CATMAN")
+AC_CACHE_CHECK(extension of pre-formatted manual pages,ac_cv_sys_catman_ext,
+[if grep _suffix /etc/man.conf > /dev/null 2>&1; then
+ ac_cv_sys_catman_ext=0
+else
+ ac_cv_sys_catman_ext=number
+fi
+])
+if test "$ac_cv_sys_catman_ext" = number; then
+ CATMANEXT='$$ext'
+else
+ CATMANEXT=0
+fi
+AC_SUBST(CATMANEXT)
+
+]) \ No newline at end of file
diff --git a/crypto/heimdal/cf/check-netinet-ip-and-tcp.m4 b/crypto/heimdal/cf/check-netinet-ip-and-tcp.m4
new file mode 100644
index 000000000000..8cb529de2379
--- /dev/null
+++ b/crypto/heimdal/cf/check-netinet-ip-and-tcp.m4
@@ -0,0 +1,38 @@
+dnl
+dnl $Id: check-netinet-ip-and-tcp.m4,v 1.2 1999/05/14 13:15:40 assar Exp $
+dnl
+
+dnl extra magic check for netinet/{ip.h,tcp.h} because on irix 6.5.3
+dnl you have to include standards.h before including these files
+
+AC_DEFUN(CHECK_NETINET_IP_AND_TCP,
+[
+AC_CHECK_HEADERS(standards.h)
+for i in netinet/ip.h netinet/tcp.h; do
+
+cv=`echo "$i" | sed 'y%./+-%__p_%'`
+
+AC_MSG_CHECKING([for $i])
+AC_CACHE_VAL([ac_cv_header_$cv],
+[AC_TRY_CPP([\
+#ifdef HAVE_STANDARDS_H
+#include <standards.h>
+#endif
+#include <$i>
+],
+eval "ac_cv_header_$cv=yes",
+eval "ac_cv_header_$cv=no")])
+AC_MSG_RESULT(`eval echo \\$ac_cv_header_$cv`)
+changequote(, )dnl
+if test `eval echo \\$ac_cv_header_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo $i | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+changequote([, ])dnl
+ AC_DEFINE_UNQUOTED($ac_tr_hdr, 1)
+fi
+done
+dnl autoheader tricks *sigh*
+: << END
+@@@headers="$headers netinet/ip.h netinet/tcp.h"@@@
+END
+
+])
diff --git a/crypto/heimdal/cf/check-type-extra.m4 b/crypto/heimdal/cf/check-type-extra.m4
new file mode 100644
index 000000000000..e6af4bd51377
--- /dev/null
+++ b/crypto/heimdal/cf/check-type-extra.m4
@@ -0,0 +1,23 @@
+dnl $Id: check-type-extra.m4,v 1.2 1999/03/01 09:52:23 joda Exp $
+dnl
+dnl ac_check_type + extra headers
+
+dnl AC_CHECK_TYPE_EXTRA(TYPE, DEFAULT, HEADERS)
+AC_DEFUN(AC_CHECK_TYPE_EXTRA,
+[AC_REQUIRE([AC_HEADER_STDC])dnl
+AC_MSG_CHECKING(for $1)
+AC_CACHE_VAL(ac_cv_type_$1,
+[AC_EGREP_CPP(dnl
+changequote(<<,>>)dnl
+<<$1[^a-zA-Z_0-9]>>dnl
+changequote([,]), [#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+$3], ac_cv_type_$1=yes, ac_cv_type_$1=no)])dnl
+AC_MSG_RESULT($ac_cv_type_$1)
+if test $ac_cv_type_$1 = no; then
+ AC_DEFINE($1, $2, [Define this to what the type $1 should be.])
+fi
+])
diff --git a/crypto/heimdal/cf/check-var.m4 b/crypto/heimdal/cf/check-var.m4
new file mode 100644
index 000000000000..9f37366d73e7
--- /dev/null
+++ b/crypto/heimdal/cf/check-var.m4
@@ -0,0 +1,20 @@
+dnl $Id: check-var.m4,v 1.2 1999/03/01 09:52:23 joda Exp $
+dnl
+dnl AC_CHECK_VAR(includes, variable)
+AC_DEFUN(AC_CHECK_VAR, [
+AC_MSG_CHECKING(for $2)
+AC_CACHE_VAL(ac_cv_var_$2, [
+AC_TRY_LINK([extern int $2;
+int foo() { return $2; }],
+ [foo()],
+ ac_cv_var_$2=yes, ac_cv_var_$2=no)
+])
+define([foo], [HAVE_]translit($2, [a-z], [A-Z]))
+
+AC_MSG_RESULT(`eval echo \\$ac_cv_var_$2`)
+if test `eval echo \\$ac_cv_var_$2` = yes; then
+ AC_DEFINE_UNQUOTED(foo, 1, [define if you have $2])
+ AC_CHECK_DECLARATION([$1],[$2])
+fi
+undefine([foo])
+])
diff --git a/crypto/heimdal/cf/check-x.m4 b/crypto/heimdal/cf/check-x.m4
new file mode 100644
index 000000000000..1791e5aaf95b
--- /dev/null
+++ b/crypto/heimdal/cf/check-x.m4
@@ -0,0 +1,52 @@
+dnl
+dnl See if there is any X11 present
+dnl
+dnl $Id: check-x.m4,v 1.2 1999/11/05 04:25:23 assar Exp $
+
+AC_DEFUN(KRB_CHECK_X,[
+AC_PATH_XTRA
+
+# try to figure out if we need any additional ld flags, like -R
+# and yes, the autoconf X test is utterly broken
+if test "$no_x" != yes; then
+ AC_CACHE_CHECK(for special X linker flags,krb_cv_sys_x_libs_rpath,[
+ ac_save_libs="$LIBS"
+ ac_save_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS $X_CFLAGS"
+ krb_cv_sys_x_libs_rpath=""
+ krb_cv_sys_x_libs=""
+ for rflag in "" "-R" "-R " "-rpath "; do
+ if test "$rflag" = ""; then
+ foo="$X_LIBS"
+ else
+ foo=""
+ for flag in $X_LIBS; do
+ case $flag in
+ -L*)
+ foo="$foo $flag `echo $flag | sed \"s/-L/$rflag/\"`"
+ ;;
+ *)
+ foo="$foo $flag"
+ ;;
+ esac
+ done
+ fi
+ LIBS="$ac_save_libs $foo $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+ AC_TRY_RUN([
+ #include <X11/Xlib.h>
+ foo()
+ {
+ XOpenDisplay(NULL);
+ }
+ main()
+ {
+ return 0;
+ }
+ ], krb_cv_sys_x_libs_rpath="$rflag"; krb_cv_sys_x_libs="$foo"; break,:)
+ done
+ LIBS="$ac_save_libs"
+ CFLAGS="$ac_save_cflags"
+ ])
+ X_LIBS="$krb_cv_sys_x_libs"
+fi
+])
diff --git a/crypto/heimdal/cf/check-xau.m4 b/crypto/heimdal/cf/check-xau.m4
new file mode 100644
index 000000000000..bad2a6023be5
--- /dev/null
+++ b/crypto/heimdal/cf/check-xau.m4
@@ -0,0 +1,64 @@
+dnl $Id: check-xau.m4,v 1.3 1999/05/14 01:17:06 assar Exp $
+dnl
+dnl check for Xau{Read,Write}Auth and XauFileName
+dnl
+AC_DEFUN(AC_CHECK_XAU,[
+save_CFLAGS="$CFLAGS"
+CFLAGS="$X_CFLAGS $CFLAGS"
+save_LIBS="$LIBS"
+dnl LIBS="$X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS $LIBS"
+LIBS="$X_PRE_LIBS $X_EXTRA_LIBS $LIBS"
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $X_LIBS"
+
+## check for XauWriteAuth first, so we detect the case where
+## XauReadAuth is in -lX11, but XauWriteAuth is only in -lXau this
+## could be done by checking for XauReadAuth in -lXau first, but this
+## breaks in IRIX 6.5
+
+AC_FIND_FUNC_NO_LIBS(XauWriteAuth, X11 Xau)
+ac_xxx="$LIBS"
+LIBS="$LIB_XauWriteAuth $LIBS"
+AC_FIND_FUNC_NO_LIBS(XauReadAuth, X11 Xau)
+LIBS="$LIB_XauReadAauth $LIBS"
+AC_FIND_FUNC_NO_LIBS(XauFileName, X11 Xau)
+LIBS="$ac_xxx"
+
+## set LIB_XauReadAuth to union of these tests, since this is what the
+## Makefiles are using
+case "$ac_cv_funclib_XauWriteAuth" in
+yes) ;;
+no) ;;
+*) if test "$ac_cv_funclib_XauReadAuth" = yes; then
+ if test "$ac_cv_funclib_XauFileName" = yes; then
+ LIB_XauReadAuth="$LIB_XauWriteAuth"
+ else
+ LIB_XauReadAuth="$LIB_XauWriteAuth $LIB_XauFileName"
+ fi
+ else
+ if test "$ac_cv_funclib_XauFileName" = yes; then
+ LIB_XauReadAuth="$LIB_XauReadAuth $LIB_XauWriteAuth"
+ else
+ LIB_XauReadAuth="$LIB_XauReadAuth $LIB_XauWriteAuth $LIB_XauFileName"
+ fi
+ fi
+ ;;
+esac
+
+if test "$AUTOMAKE" != ""; then
+ AM_CONDITIONAL(NEED_WRITEAUTH, test "$ac_cv_func_XauWriteAuth" != "yes")
+else
+ AC_SUBST(NEED_WRITEAUTH_TRUE)
+ AC_SUBST(NEED_WRITEAUTH_FALSE)
+ if test "$ac_cv_func_XauWriteAuth" != "yes"; then
+ NEED_WRITEAUTH_TRUE=
+ NEED_WRITEAUTH_FALSE='#'
+ else
+ NEED_WRITEAUTH_TRUE='#'
+ NEED_WRITEAUTH_FALSE=
+ fi
+fi
+CFLAGS=$save_CFLAGS
+LIBS=$save_LIBS
+LDFLAGS=$save_LDFLAGS
+])
diff --git a/crypto/heimdal/cf/find-func-no-libs.m4 b/crypto/heimdal/cf/find-func-no-libs.m4
new file mode 100644
index 000000000000..3deab02b9d9d
--- /dev/null
+++ b/crypto/heimdal/cf/find-func-no-libs.m4
@@ -0,0 +1,9 @@
+dnl $Id: find-func-no-libs.m4,v 1.5 1999/10/30 21:08:18 assar Exp $
+dnl
+dnl
+dnl Look for function in any of the specified libraries
+dnl
+
+dnl AC_FIND_FUNC_NO_LIBS(func, libraries, includes, arguments, extra libs, extra args)
+AC_DEFUN(AC_FIND_FUNC_NO_LIBS, [
+AC_FIND_FUNC_NO_LIBS2([$1], ["" $2], [$3], [$4], [$5], [$6])])
diff --git a/crypto/heimdal/cf/find-func-no-libs2.m4 b/crypto/heimdal/cf/find-func-no-libs2.m4
new file mode 100644
index 000000000000..c404a7c1b476
--- /dev/null
+++ b/crypto/heimdal/cf/find-func-no-libs2.m4
@@ -0,0 +1,63 @@
+dnl $Id: find-func-no-libs2.m4,v 1.3 1999/10/30 21:09:53 assar Exp $
+dnl
+dnl
+dnl Look for function in any of the specified libraries
+dnl
+
+dnl AC_FIND_FUNC_NO_LIBS2(func, libraries, includes, arguments, extra libs, extra args)
+AC_DEFUN(AC_FIND_FUNC_NO_LIBS2, [
+
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(ac_cv_funclib_$1,
+[
+if eval "test \"\$ac_cv_func_$1\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in $2; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS="$6 $ac_lib $5 $ac_save_LIBS"
+ AC_TRY_LINK([$3],[$1($4)],eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break)
+ done
+ eval "ac_cv_funclib_$1=\${ac_cv_funclib_$1-no}"
+ LIBS="$ac_save_LIBS"
+fi
+])
+
+eval "ac_res=\$ac_cv_funclib_$1"
+
+dnl autoheader tricks *sigh*
+: << END
+@@@funcs="$funcs $1"@@@
+@@@libs="$libs $2"@@@
+END
+
+# $1
+eval "ac_tr_func=HAVE_[]upcase($1)"
+eval "ac_tr_lib=HAVE_LIB[]upcase($ac_res | sed -e 's/-l//')"
+eval "LIB_$1=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_$1=yes"
+ eval "LIB_$1="
+ AC_DEFINE_UNQUOTED($ac_tr_func)
+ AC_MSG_RESULT([yes])
+ ;;
+ no)
+ eval "ac_cv_func_$1=no"
+ eval "LIB_$1="
+ AC_MSG_RESULT([no])
+ ;;
+ *)
+ eval "ac_cv_func_$1=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ AC_DEFINE_UNQUOTED($ac_tr_func)
+ AC_DEFINE_UNQUOTED($ac_tr_lib)
+ AC_MSG_RESULT([yes, in $ac_res])
+ ;;
+esac
+AC_SUBST(LIB_$1)
+])
diff --git a/crypto/heimdal/cf/find-func.m4 b/crypto/heimdal/cf/find-func.m4
new file mode 100644
index 000000000000..bb2b3ac70966
--- /dev/null
+++ b/crypto/heimdal/cf/find-func.m4
@@ -0,0 +1,9 @@
+dnl $Id: find-func.m4,v 1.1 1997/12/14 15:58:58 joda Exp $
+dnl
+dnl AC_FIND_FUNC(func, libraries, includes, arguments)
+AC_DEFUN(AC_FIND_FUNC, [
+AC_FIND_FUNC_NO_LIBS([$1], [$2], [$3], [$4])
+if test -n "$LIB_$1"; then
+ LIBS="$LIB_$1 $LIBS"
+fi
+])
diff --git a/crypto/heimdal/cf/find-if-not-broken.m4 b/crypto/heimdal/cf/find-if-not-broken.m4
new file mode 100644
index 000000000000..e855ec7a6903
--- /dev/null
+++ b/crypto/heimdal/cf/find-if-not-broken.m4
@@ -0,0 +1,13 @@
+dnl $Id: find-if-not-broken.m4,v 1.2 1998/03/16 22:16:27 joda Exp $
+dnl
+dnl
+dnl Mix between AC_FIND_FUNC and AC_BROKEN
+dnl
+
+AC_DEFUN(AC_FIND_IF_NOT_BROKEN,
+[AC_FIND_FUNC([$1], [$2], [$3], [$4])
+if eval "test \"$ac_cv_func_$1\" != yes"; then
+LIBOBJS[]="$LIBOBJS $1.o"
+fi
+AC_SUBST(LIBOBJS)dnl
+])
diff --git a/crypto/heimdal/cf/grok-type.m4 b/crypto/heimdal/cf/grok-type.m4
new file mode 100644
index 000000000000..5bc6a66241fb
--- /dev/null
+++ b/crypto/heimdal/cf/grok-type.m4
@@ -0,0 +1,38 @@
+dnl $Id: grok-type.m4,v 1.4 1999/11/29 11:16:48 joda Exp $
+dnl
+AC_DEFUN(AC_GROK_TYPE, [
+AC_CACHE_VAL(ac_cv_type_$1,
+AC_TRY_COMPILE([
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#ifdef HAVE_BIND_BITYPES_H
+#include <bind/bitypes.h>
+#endif
+#ifdef HAVE_NETINET_IN6_MACHTYPES_H
+#include <netinet/in6_machtypes.h>
+#endif
+],
+$i x;
+,
+eval ac_cv_type_$1=yes,
+eval ac_cv_type_$1=no))])
+
+AC_DEFUN(AC_GROK_TYPES, [
+for i in $1; do
+ AC_MSG_CHECKING(for $i)
+ AC_GROK_TYPE($i)
+ eval ac_res=\$ac_cv_type_$i
+ if test "$ac_res" = yes; then
+ type=HAVE_[]upcase($i)
+ AC_DEFINE_UNQUOTED($type)
+ fi
+ AC_MSG_RESULT($ac_res)
+done
+])
diff --git a/crypto/heimdal/cf/have-pragma-weak.m4 b/crypto/heimdal/cf/have-pragma-weak.m4
new file mode 100644
index 000000000000..330e6012c8f2
--- /dev/null
+++ b/crypto/heimdal/cf/have-pragma-weak.m4
@@ -0,0 +1,37 @@
+dnl $Id: have-pragma-weak.m4,v 1.3 1999/03/01 11:55:25 joda Exp $
+dnl
+AC_DEFUN(AC_HAVE_PRAGMA_WEAK, [
+if test "${enable_shared}" = "yes"; then
+AC_MSG_CHECKING(for pragma weak)
+AC_CACHE_VAL(ac_have_pragma_weak, [
+ac_have_pragma_weak=no
+cat > conftest_foo.$ac_ext <<'EOF'
+[#]line __oline__ "configure"
+#include "confdefs.h"
+#pragma weak foo = _foo
+int _foo = 17;
+EOF
+cat > conftest_bar.$ac_ext <<'EOF'
+[#]line __oline__ "configure"
+#include "confdefs.h"
+extern int foo;
+
+int t() {
+ return foo;
+}
+
+int main() {
+ return t();
+}
+EOF
+if AC_TRY_EVAL('CC -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest_foo.$ac_ext conftest_bar.$ac_ext 1>&AC_FD_CC'); then
+ac_have_pragma_weak=yes
+fi
+rm -rf conftest*
+])
+if test "$ac_have_pragma_weak" = "yes"; then
+ AC_DEFINE(HAVE_PRAGMA_WEAK, 1, [Define this if your compiler supports \`#pragma weak.'])dnl
+fi
+AC_MSG_RESULT($ac_have_pragma_weak)
+fi
+])
diff --git a/crypto/heimdal/cf/have-struct-field.m4 b/crypto/heimdal/cf/have-struct-field.m4
new file mode 100644
index 000000000000..88ad5c3b29ab
--- /dev/null
+++ b/crypto/heimdal/cf/have-struct-field.m4
@@ -0,0 +1,19 @@
+dnl $Id: have-struct-field.m4,v 1.6 1999/07/29 01:44:32 assar Exp $
+dnl
+dnl check for fields in a structure
+dnl
+dnl AC_HAVE_STRUCT_FIELD(struct, field, headers)
+
+AC_DEFUN(AC_HAVE_STRUCT_FIELD, [
+define(cache_val, translit(ac_cv_type_$1_$2, [A-Z ], [a-z_]))
+AC_CACHE_CHECK([for $2 in $1], cache_val,[
+AC_TRY_COMPILE([$3],[$1 x; x.$2;],
+cache_val=yes,
+cache_val=no)])
+if test "$cache_val" = yes; then
+ define(foo, translit(HAVE_$1_$2, [a-z ], [A-Z_]))
+ AC_DEFINE(foo, 1, [Define if $1 has field $2.])
+ undefine([foo])
+fi
+undefine([cache_val])
+])
diff --git a/crypto/heimdal/cf/have-type.m4 b/crypto/heimdal/cf/have-type.m4
new file mode 100644
index 000000000000..e882847c7d0b
--- /dev/null
+++ b/crypto/heimdal/cf/have-type.m4
@@ -0,0 +1,32 @@
+dnl $Id: have-type.m4,v 1.5 1999/12/31 03:10:22 assar Exp $
+dnl
+dnl check for existance of a type
+
+dnl AC_HAVE_TYPE(TYPE,INCLUDES)
+AC_DEFUN(AC_HAVE_TYPE, [
+AC_REQUIRE([AC_HEADER_STDC])
+cv=`echo "$1" | sed 'y%./+- %__p__%'`
+AC_MSG_CHECKING(for $1)
+AC_CACHE_VAL([ac_cv_type_$cv],
+AC_TRY_COMPILE(
+[#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+$2],
+[$1 foo;],
+eval "ac_cv_type_$cv=yes",
+eval "ac_cv_type_$cv=no"))dnl
+AC_MSG_RESULT(`eval echo \\$ac_cv_type_$cv`)
+if test `eval echo \\$ac_cv_type_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
+dnl autoheader tricks *sigh*
+define(foo,translit($1, [ ], [_]))
+: << END
+@@@funcs="$funcs foo"@@@
+END
+undefine([foo])
+ AC_DEFINE_UNQUOTED($ac_tr_hdr, 1)
+fi
+])
diff --git a/crypto/heimdal/cf/have-types.m4 b/crypto/heimdal/cf/have-types.m4
new file mode 100644
index 000000000000..7c85c5ddddba
--- /dev/null
+++ b/crypto/heimdal/cf/have-types.m4
@@ -0,0 +1,14 @@
+dnl
+dnl $Id: have-types.m4,v 1.1 1999/07/24 18:38:58 assar Exp $
+dnl
+
+AC_DEFUN(AC_HAVE_TYPES, [
+for i in $1; do
+ AC_HAVE_TYPE($i)
+done
+: << END
+changequote(`,')dnl
+@@@funcs="$funcs $1"@@@
+changequote([,])dnl
+END
+])
diff --git a/crypto/heimdal/cf/krb-bigendian.m4 b/crypto/heimdal/cf/krb-bigendian.m4
new file mode 100644
index 000000000000..0efbbd03b69e
--- /dev/null
+++ b/crypto/heimdal/cf/krb-bigendian.m4
@@ -0,0 +1,57 @@
+dnl
+dnl $Id: krb-bigendian.m4,v 1.5 2000/01/08 10:34:44 assar Exp $
+dnl
+
+dnl check if this computer is little or big-endian
+dnl if we can figure it out at compile-time then don't define the cpp symbol
+dnl otherwise test for it and define it. also allow options for overriding
+dnl it when cross-compiling
+
+AC_DEFUN(KRB_C_BIGENDIAN, [
+AC_ARG_ENABLE(bigendian,
+[ --enable-bigendian the target is big endian],
+krb_cv_c_bigendian=yes)
+AC_ARG_ENABLE(littleendian,
+[ --enable-littleendian the target is little endian],
+krb_cv_c_bigendian=no)
+AC_CACHE_CHECK(whether byte order is known at compile time,
+krb_cv_c_bigendian_compile,
+[AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/param.h>],[
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif], krb_cv_c_bigendian_compile=yes, krb_cv_c_bigendian_compile=no)])
+if test "$krb_cv_c_bigendian_compile" = "no"; then
+ AC_CACHE_CHECK(whether byte ordering is bigendian, krb_cv_c_bigendian,[
+ if test "$krb_cv_c_bigendian" = ""; then
+ krb_cv_c_bigendian=unknown
+ fi
+ AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/param.h>],[
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif], krb_cv_c_bigendian=yes, krb_cv_c_bigendian=no)
+ if test "$krb_cv_c_bigendian" = "unknown"; then
+ AC_TRY_RUN([main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+ }], krb_cv_c_bigendian=no, krb_cv_c_bigendian=yes,
+ AC_MSG_ERROR([specify either --enable-bigendian or --enable-littleendian]))
+ fi
+ ])
+ if test "$krb_cv_c_bigendian" = "yes"; then
+ AC_DEFINE(WORDS_BIGENDIAN, 1, [define if target is big endian])dnl
+ fi
+fi
+if test "$krb_cv_c_bigendian_compile" = "yes"; then
+ AC_DEFINE(ENDIANESS_IN_SYS_PARAM_H, 1, [define if sys/param.h defines the endiness])dnl
+fi
+])
diff --git a/crypto/heimdal/cf/krb-find-db.m4 b/crypto/heimdal/cf/krb-find-db.m4
new file mode 100644
index 000000000000..50800497eb5c
--- /dev/null
+++ b/crypto/heimdal/cf/krb-find-db.m4
@@ -0,0 +1,98 @@
+dnl $Id: krb-find-db.m4,v 1.5 1999/05/08 02:24:04 assar Exp $
+dnl
+dnl find a suitable database library
+dnl
+dnl AC_FIND_DB(libraries)
+AC_DEFUN(KRB_FIND_DB, [
+
+lib_dbm=no
+lib_db=no
+
+for i in $1; do
+
+ if test "$i"; then
+ m="lib$i"
+ l="-l$i"
+ else
+ m="libc"
+ l=""
+ fi
+
+ AC_MSG_CHECKING(for dbm_open in $m)
+ AC_CACHE_VAL(ac_cv_krb_dbm_open_$m, [
+
+ save_LIBS="$LIBS"
+ LIBS="$l $LIBS"
+ AC_TRY_RUN([
+#include <unistd.h>
+#include <fcntl.h>
+#if defined(HAVE_NDBM_H)
+#include <ndbm.h>
+#elif defined(HAVE_DBM_H)
+#include <dbm.h>
+#elif defined(HAVE_RPCSVC_DBM_H)
+#include <rpcsvc/dbm.h>
+#elif defined(HAVE_DB_H)
+#define DB_DBM_HSEARCH 1
+#include <db.h>
+#endif
+int main()
+{
+ DBM *d;
+
+ d = dbm_open("conftest", O_RDWR | O_CREAT, 0666);
+ if(d == NULL)
+ return 1;
+ dbm_close(d);
+ return 0;
+}], [
+ if test -f conftest.db; then
+ ac_res=db
+ else
+ ac_res=dbm
+ fi], ac_res=no, ac_res=no)
+
+ LIBS="$save_LIBS"
+
+ eval ac_cv_krb_dbm_open_$m=$ac_res])
+ eval ac_res=\$ac_cv_krb_dbm_open_$m
+ AC_MSG_RESULT($ac_res)
+
+ if test "$lib_dbm" = no -a $ac_res = dbm; then
+ lib_dbm="$l"
+ elif test "$lib_db" = no -a $ac_res = db; then
+ lib_db="$l"
+ break
+ fi
+done
+
+AC_MSG_CHECKING(for NDBM library)
+ac_ndbm=no
+if test "$lib_db" != no; then
+ LIB_DBM="$lib_db"
+ ac_ndbm=yes
+ AC_DEFINE(HAVE_NEW_DB, 1, [Define if NDBM really is DB (creates files ending in .db).])
+ if test "$LIB_DBM"; then
+ ac_res="yes, $LIB_DBM"
+ else
+ ac_res=yes
+ fi
+elif test "$lib_dbm" != no; then
+ LIB_DBM="$lib_dbm"
+ ac_ndbm=yes
+ if test "$LIB_DBM"; then
+ ac_res="yes, $LIB_DBM"
+ else
+ ac_res=yes
+ fi
+else
+ LIB_DBM=""
+ ac_res=no
+fi
+test "$ac_ndbm" = yes && AC_DEFINE(NDBM, 1, [Define if you have NDBM (and not DBM)])dnl
+AC_SUBST(LIB_DBM)
+DBLIB="$LIB_DBM"
+AC_SUBST(DBLIB)
+AC_MSG_RESULT($ac_res)
+
+])
diff --git a/crypto/heimdal/cf/krb-func-getcwd-broken.m4 b/crypto/heimdal/cf/krb-func-getcwd-broken.m4
new file mode 100644
index 000000000000..d248922c9768
--- /dev/null
+++ b/crypto/heimdal/cf/krb-func-getcwd-broken.m4
@@ -0,0 +1,42 @@
+dnl $Id: krb-func-getcwd-broken.m4,v 1.2 1999/03/01 13:03:32 joda Exp $
+dnl
+dnl
+dnl test for broken getcwd in (SunOS braindamage)
+dnl
+
+AC_DEFUN(AC_KRB_FUNC_GETCWD_BROKEN, [
+if test "$ac_cv_func_getcwd" = yes; then
+AC_MSG_CHECKING(if getcwd is broken)
+AC_CACHE_VAL(ac_cv_func_getcwd_broken, [
+ac_cv_func_getcwd_broken=no
+
+AC_TRY_RUN([
+#include <errno.h>
+char *getcwd(char*, int);
+
+void *popen(char *cmd, char *mode)
+{
+ errno = ENOTTY;
+ return 0;
+}
+
+int main()
+{
+ char *ret;
+ ret = getcwd(0, 1024);
+ if(ret == 0 && errno == ENOTTY)
+ return 0;
+ return 1;
+}
+], ac_cv_func_getcwd_broken=yes,:,:)
+])
+if test "$ac_cv_func_getcwd_broken" = yes; then
+ AC_DEFINE(BROKEN_GETCWD, 1, [Define if getcwd is broken (like in SunOS 4).])dnl
+ LIBOBJS="$LIBOBJS getcwd.o"
+ AC_SUBST(LIBOBJS)dnl
+ AC_MSG_RESULT($ac_cv_func_getcwd_broken)
+else
+ AC_MSG_RESULT([seems ok])
+fi
+fi
+])
diff --git a/crypto/heimdal/cf/krb-func-getlogin.m4 b/crypto/heimdal/cf/krb-func-getlogin.m4
new file mode 100644
index 000000000000..921c5ab8dff0
--- /dev/null
+++ b/crypto/heimdal/cf/krb-func-getlogin.m4
@@ -0,0 +1,22 @@
+dnl
+dnl $Id: krb-func-getlogin.m4,v 1.1 1999/07/13 17:45:30 assar Exp $
+dnl
+dnl test for POSIX (broken) getlogin
+dnl
+
+
+AC_DEFUN(AC_FUNC_GETLOGIN, [
+AC_CHECK_FUNCS(getlogin setlogin)
+if test "$ac_cv_func_getlogin" = yes; then
+AC_CACHE_CHECK(if getlogin is posix, ac_cv_func_getlogin_posix, [
+if test "$ac_cv_func_getlogin" = yes -a "$ac_cv_func_setlogin" = yes; then
+ ac_cv_func_getlogin_posix=no
+else
+ ac_cv_func_getlogin_posix=yes
+fi
+])
+if test "$ac_cv_func_getlogin_posix" = yes; then
+ AC_DEFINE(POSIX_GETLOGIN, 1, [Define if getlogin has POSIX flavour (and not BSD).])
+fi
+fi
+])
diff --git a/crypto/heimdal/cf/krb-ipv6.m4 b/crypto/heimdal/cf/krb-ipv6.m4
new file mode 100644
index 000000000000..1644da397526
--- /dev/null
+++ b/crypto/heimdal/cf/krb-ipv6.m4
@@ -0,0 +1,122 @@
+dnl $Id: krb-ipv6.m4,v 1.8 2000/01/01 11:44:45 assar Exp $
+dnl
+dnl test for IPv6
+dnl
+AC_DEFUN(AC_KRB_IPV6, [
+AC_ARG_WITH(ipv6,
+[ --without-ipv6 do not enable IPv6 support],[
+if test "$withval" = "no"; then
+ ac_cv_lib_ipv6=no
+fi])
+AC_CACHE_VAL(ac_cv_lib_ipv6,
+[dnl check for different v6 implementations (by itojun)
+v6type=unknown
+v6lib=none
+
+AC_MSG_CHECKING([ipv6 stack type])
+for i in v6d toshiba kame inria zeta linux; do
+ case $i in
+ v6d)
+ AC_EGREP_CPP(yes, [dnl
+#include </usr/local/v6/include/sys/types.h>
+#ifdef __V6D__
+yes
+#endif],
+ [v6type=$i; v6lib=v6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-I/usr/local/v6/include $CFLAGS"])
+ ;;
+ toshiba)
+ AC_EGREP_CPP(yes, [dnl
+#include <sys/param.h>
+#ifdef _TOSHIBA_INET6
+yes
+#endif],
+ [v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ kame)
+ AC_EGREP_CPP(yes, [dnl
+#include <netinet/in.h>
+#ifdef __KAME__
+yes
+#endif],
+ [v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ inria)
+ AC_EGREP_CPP(yes, [dnl
+#include <netinet/in.h>
+#ifdef IPV6_INRIA_VERSION
+yes
+#endif],
+ [v6type=$i; CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ zeta)
+ AC_EGREP_CPP(yes, [dnl
+#include <sys/param.h>
+#ifdef _ZETA_MINAMI_INET6
+yes
+#endif],
+ [v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ linux)
+ if test -d /usr/inet6; then
+ v6type=$i
+ v6lib=inet6
+ v6libdir=/usr/inet6
+ CFLAGS="-DINET6 $CFLAGS"
+ fi
+ ;;
+ esac
+ if test "$v6type" != "unknown"; then
+ break
+ fi
+done
+AC_MSG_RESULT($v6type)
+
+if test "$v6lib" != "none"; then
+ for dir in $v6libdir /usr/local/v6/lib /usr/local/lib; do
+ if test -d $dir -a -f $dir/lib$v6lib.a; then
+ LIBS="-L$dir -l$v6lib $LIBS"
+ break
+ fi
+ done
+fi
+AC_TRY_LINK([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+],
+[
+ struct sockaddr_in6 sin6;
+ int s;
+
+ s = socket(AF_INET6, SOCK_DGRAM, 0);
+
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = htons(17);
+ sin6.sin6_addr = in6addr_any;
+ bind(s, (struct sockaddr *)&sin6, sizeof(sin6));
+],
+ac_cv_lib_ipv6=yes,
+ac_cv_lib_ipv6=no)])
+AC_MSG_CHECKING(for IPv6)
+AC_MSG_RESULT($ac_cv_lib_ipv6)
+if test "$ac_cv_lib_ipv6" = yes; then
+ AC_DEFINE(HAVE_IPV6, 1, [Define if you have IPv6.])
+fi
+])
diff --git a/crypto/heimdal/cf/krb-prog-ln-s.m4 b/crypto/heimdal/cf/krb-prog-ln-s.m4
new file mode 100644
index 000000000000..efb706ec2a68
--- /dev/null
+++ b/crypto/heimdal/cf/krb-prog-ln-s.m4
@@ -0,0 +1,28 @@
+dnl $Id: krb-prog-ln-s.m4,v 1.1 1997/12/14 15:59:01 joda Exp $
+dnl
+dnl
+dnl Better test for ln -s, ln or cp
+dnl
+
+AC_DEFUN(AC_KRB_PROG_LN_S,
+[AC_MSG_CHECKING(for ln -s or something else)
+AC_CACHE_VAL(ac_cv_prog_LN_S,
+[rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ touch conftestdata1
+ if ln conftestdata1 conftestdata2; then
+ rm -f conftestdata*
+ ac_cv_prog_LN_S=ln
+ else
+ ac_cv_prog_LN_S=cp
+ fi
+fi])dnl
+LN_S="$ac_cv_prog_LN_S"
+AC_MSG_RESULT($ac_cv_prog_LN_S)
+AC_SUBST(LN_S)dnl
+])
+
diff --git a/crypto/heimdal/cf/krb-prog-ranlib.m4 b/crypto/heimdal/cf/krb-prog-ranlib.m4
new file mode 100644
index 000000000000..fd1d3db2b9d7
--- /dev/null
+++ b/crypto/heimdal/cf/krb-prog-ranlib.m4
@@ -0,0 +1,8 @@
+dnl $Id: krb-prog-ranlib.m4,v 1.1 1997/12/14 15:59:01 joda Exp $
+dnl
+dnl
+dnl Also look for EMXOMF for OS/2
+dnl
+
+AC_DEFUN(AC_KRB_PROG_RANLIB,
+[AC_CHECK_PROGS(RANLIB, ranlib EMXOMF, :)])
diff --git a/crypto/heimdal/cf/krb-prog-yacc.m4 b/crypto/heimdal/cf/krb-prog-yacc.m4
new file mode 100644
index 000000000000..28ae59c7a378
--- /dev/null
+++ b/crypto/heimdal/cf/krb-prog-yacc.m4
@@ -0,0 +1,8 @@
+dnl $Id: krb-prog-yacc.m4,v 1.1 1997/12/14 15:59:02 joda Exp $
+dnl
+dnl
+dnl We prefer byacc or yacc because they do not use `alloca'
+dnl
+
+AC_DEFUN(AC_KRB_PROG_YACC,
+[AC_CHECK_PROGS(YACC, byacc yacc 'bison -y')])
diff --git a/crypto/heimdal/cf/krb-struct-spwd.m4 b/crypto/heimdal/cf/krb-struct-spwd.m4
new file mode 100644
index 000000000000..4ab81fd34f52
--- /dev/null
+++ b/crypto/heimdal/cf/krb-struct-spwd.m4
@@ -0,0 +1,22 @@
+dnl $Id: krb-struct-spwd.m4,v 1.3 1999/07/13 21:04:11 assar Exp $
+dnl
+dnl Test for `struct spwd'
+
+AC_DEFUN(AC_KRB_STRUCT_SPWD, [
+AC_MSG_CHECKING(for struct spwd)
+AC_CACHE_VAL(ac_cv_struct_spwd, [
+AC_TRY_COMPILE(
+[#include <pwd.h>
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif],
+[struct spwd foo;],
+ac_cv_struct_spwd=yes,
+ac_cv_struct_spwd=no)
+])
+AC_MSG_RESULT($ac_cv_struct_spwd)
+
+if test "$ac_cv_struct_spwd" = "yes"; then
+ AC_DEFINE(HAVE_STRUCT_SPWD, 1, [define if you have struct spwd])
+fi
+])
diff --git a/crypto/heimdal/cf/krb-struct-winsize.m4 b/crypto/heimdal/cf/krb-struct-winsize.m4
new file mode 100644
index 000000000000..f89f68337c3a
--- /dev/null
+++ b/crypto/heimdal/cf/krb-struct-winsize.m4
@@ -0,0 +1,27 @@
+dnl $Id: krb-struct-winsize.m4,v 1.2 1999/03/01 09:52:23 joda Exp $
+dnl
+dnl
+dnl Search for struct winsize
+dnl
+
+AC_DEFUN(AC_KRB_STRUCT_WINSIZE, [
+AC_MSG_CHECKING(for struct winsize)
+AC_CACHE_VAL(ac_cv_struct_winsize, [
+ac_cv_struct_winsize=no
+for i in sys/termios.h sys/ioctl.h; do
+AC_EGREP_HEADER(
+changequote(, )dnl
+struct[ ]*winsize,dnl
+changequote([,])dnl
+$i, ac_cv_struct_winsize=yes; break)dnl
+done
+])
+if test "$ac_cv_struct_winsize" = "yes"; then
+ AC_DEFINE(HAVE_STRUCT_WINSIZE, 1, [define if struct winsize is declared in sys/termios.h])
+fi
+AC_MSG_RESULT($ac_cv_struct_winsize)
+AC_EGREP_HEADER(ws_xpixel, termios.h,
+ AC_DEFINE(HAVE_WS_XPIXEL, 1, [define if struct winsize has ws_xpixel]))
+AC_EGREP_HEADER(ws_ypixel, termios.h,
+ AC_DEFINE(HAVE_WS_YPIXEL, 1, [define if struct winsize has ws_ypixel]))
+])
diff --git a/crypto/heimdal/cf/krb-sys-aix.m4 b/crypto/heimdal/cf/krb-sys-aix.m4
new file mode 100644
index 000000000000..a538005513a2
--- /dev/null
+++ b/crypto/heimdal/cf/krb-sys-aix.m4
@@ -0,0 +1,15 @@
+dnl $Id: krb-sys-aix.m4,v 1.1 1997/12/14 15:59:02 joda Exp $
+dnl
+dnl
+dnl AIX have a very different syscall convention
+dnl
+AC_DEFUN(AC_KRB_SYS_AIX, [
+AC_MSG_CHECKING(for AIX)
+AC_CACHE_VAL(krb_cv_sys_aix,
+AC_EGREP_CPP(yes,
+[#ifdef _AIX
+ yes
+#endif
+], krb_cv_sys_aix=yes, krb_cv_sys_aix=no) )
+AC_MSG_RESULT($krb_cv_sys_aix)
+])
diff --git a/crypto/heimdal/cf/krb-sys-nextstep.m4 b/crypto/heimdal/cf/krb-sys-nextstep.m4
new file mode 100644
index 000000000000..31dc907be4e1
--- /dev/null
+++ b/crypto/heimdal/cf/krb-sys-nextstep.m4
@@ -0,0 +1,21 @@
+dnl $Id: krb-sys-nextstep.m4,v 1.2 1998/06/03 23:48:40 joda Exp $
+dnl
+dnl
+dnl NEXTSTEP is not posix compliant by default,
+dnl you need a switch -posix to the compiler
+dnl
+
+AC_DEFUN(AC_KRB_SYS_NEXTSTEP, [
+AC_MSG_CHECKING(for NEXTSTEP)
+AC_CACHE_VAL(krb_cv_sys_nextstep,
+AC_EGREP_CPP(yes,
+[#if defined(NeXT) && !defined(__APPLE__)
+ yes
+#endif
+], krb_cv_sys_nextstep=yes, krb_cv_sys_nextstep=no) )
+if test "$krb_cv_sys_nextstep" = "yes"; then
+ CFLAGS="$CFLAGS -posix"
+ LIBS="$LIBS -posix"
+fi
+AC_MSG_RESULT($krb_cv_sys_nextstep)
+])
diff --git a/crypto/heimdal/cf/krb-version.m4 b/crypto/heimdal/cf/krb-version.m4
new file mode 100644
index 000000000000..a4a12211a6ea
--- /dev/null
+++ b/crypto/heimdal/cf/krb-version.m4
@@ -0,0 +1,25 @@
+dnl $Id: krb-version.m4,v 1.1 1997/12/14 15:59:03 joda Exp $
+dnl
+dnl
+dnl output a C header-file with some version strings
+dnl
+AC_DEFUN(AC_KRB_VERSION,[
+dnl AC_OUTPUT_COMMANDS([
+cat > include/newversion.h.in <<FOOBAR
+char *${PACKAGE}_long_version = "@(#)\$Version: $PACKAGE-$VERSION by @USER@ on @HOST@ ($host) @DATE@ \$";
+char *${PACKAGE}_version = "$PACKAGE-$VERSION";
+FOOBAR
+
+if test -f include/version.h && cmp -s include/newversion.h.in include/version.h.in; then
+ echo "include/version.h is unchanged"
+ rm -f include/newversion.h.in
+else
+ echo "creating include/version.h"
+ User=${USER-${LOGNAME}}
+ Host=`(hostname || uname -n) 2>/dev/null | sed 1q`
+ Date=`date`
+ mv -f include/newversion.h.in include/version.h.in
+ sed -e "s/@USER@/$User/" -e "s/@HOST@/$Host/" -e "s/@DATE@/$Date/" include/version.h.in > include/version.h
+fi
+dnl ],host=$host PACKAGE=$PACKAGE VERSION=$VERSION)
+])
diff --git a/crypto/heimdal/cf/make-proto.pl b/crypto/heimdal/cf/make-proto.pl
new file mode 100644
index 000000000000..9a47aedbed42
--- /dev/null
+++ b/crypto/heimdal/cf/make-proto.pl
@@ -0,0 +1,199 @@
+# Make prototypes from .c files
+# $Id: make-proto.pl,v 1.11 1999/04/15 12:37:54 joda Exp $
+
+##use Getopt::Std;
+require 'getopts.pl';
+
+$brace = 0;
+$line = "";
+$debug = 0;
+
+do Getopts('o:p:d') || die "foo";
+
+if($opt_d) {
+ $debug = 1;
+}
+
+while(<>) {
+ print $brace, " ", $_ if($debug);
+ if(/^\#if 0/) {
+ $if_0 = 1;
+ }
+ if($if_0 && /^\#endif/) {
+ $if_0 = 0;
+ }
+ if($if_0) { next }
+ if(/^\s*\#/) {
+ next;
+ }
+ if(/^\s*$/) {
+ $line = "";
+ next;
+ }
+ if(/\{/){
+ $_ = $line;
+ while(s/\*\//\ca/){
+ s/\/\*(.|\n)*\ca//;
+ }
+ s/^\s*//;
+ s/\s$//;
+ s/\s+/ /g;
+ if($line =~ /\)\s$/){
+ if(!/^static/ && !/^PRIVATE/){
+ if(/(.*)(__attribute__\s?\(.*\))/) {
+ $attr = $2;
+ $_ = $1;
+ } else {
+ $attr = "";
+ }
+ # remove outer ()
+ s/\s*\(/@/;
+ s/\)\s?$/@/;
+ # remove , within ()
+ while(s/\(([^()]*),(.*)\)/($1\$$2)/g){}
+ s/,\s*/,\n\t/g;
+ # fix removed ,
+ s/\$/,/g;
+ # match function name
+ /([a-zA-Z0-9_]+)\s*@/;
+ $f = $1;
+ # only add newline if more than one parameter
+ $LP = "(("; # XXX workaround for indentation bug in emacs
+ $RP = "))";
+ $P = "__P((";
+ if(/,/){
+ s/@/ __P$LP\n\t/;
+ }else{
+ s/@/ __P$LP/;
+ }
+ s/@/$RP/;
+ # insert newline before function name
+ s/(.*)\s([a-zA-Z0-9_]+ __P)/$1\n$2/;
+ if($attr ne "") {
+ $_ .= "\n $attr";
+ }
+ $_ = $_ . ";";
+ $funcs{$f} = $_;
+ }
+ }
+ $line = "";
+ $brace++;
+ }
+ if(/\}/){
+ $brace--;
+ }
+ if(/^\}/){
+ $brace = 0;
+ }
+ if($brace == 0) {
+ $line = $line . " " . $_;
+ }
+}
+
+sub foo {
+ local ($arg) = @_;
+ $_ = $arg;
+ s/.*\/([^\/]*)/$1/;
+ s/[^a-zA-Z0-9]/_/g;
+ "__" . $_ . "__";
+}
+
+if($opt_o) {
+ open(OUT, ">$opt_o");
+ $block = &foo($opt_o);
+} else {
+ $block = "__public_h__";
+}
+
+if($opt_p) {
+ open(PRIV, ">$opt_p");
+ $private = &foo($opt_p);
+} else {
+ $private = "__private_h__";
+}
+
+$public_h = "";
+$private_h = "";
+
+$public_h_header = "/* This is a generated file */
+#ifndef $block
+#define $block
+
+#ifdef __STDC__
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+";
+
+$private_h_header = "/* This is a generated file */
+#ifndef $private
+#define $private
+
+#ifdef __STDC__
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+";
+
+foreach(sort keys %funcs){
+ if(/^(main)$/) { next }
+ if(/^_/) {
+ $private_h .= $funcs{$_} . "\n\n";
+ if($funcs{$_} =~ /__attribute__/) {
+ $private_attribute_seen = 1;
+ }
+ } else {
+ $public_h .= $funcs{$_} . "\n\n";
+ if($funcs{$_} =~ /__attribute__/) {
+ $public_attribute_seen = 1;
+ }
+ }
+}
+
+if ($public_attribute_seen) {
+ $public_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(x)
+#endif
+
+";
+}
+
+if ($private_attribute_seen) {
+ $private_h_header .= "#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(x)
+#endif
+
+";
+}
+
+
+if ($public_h ne "") {
+ $public_h = $public_h_header . $public_h . "#endif /* $block */\n";
+}
+if ($private_h ne "") {
+ $private_h = $private_h_header . $private_h . "#endif /* $private */\n";
+}
+
+if($opt_o) {
+ print OUT $public_h;
+}
+if($opt_p) {
+ print PRIV $private_h;
+}
+
+close OUT;
+close PRIV;
diff --git a/crypto/heimdal/cf/mips-abi.m4 b/crypto/heimdal/cf/mips-abi.m4
new file mode 100644
index 000000000000..c7b88150ce25
--- /dev/null
+++ b/crypto/heimdal/cf/mips-abi.m4
@@ -0,0 +1,87 @@
+dnl $Id: mips-abi.m4,v 1.4 1998/05/16 20:44:15 joda Exp $
+dnl
+dnl
+dnl Check for MIPS/IRIX ABI flags. Sets $abi and $abilibdirext to some
+dnl value.
+
+AC_DEFUN(AC_MIPS_ABI, [
+AC_ARG_WITH(mips_abi,
+[ --with-mips-abi=abi ABI to use for IRIX (32, n32, or 64)])
+
+case "$host_os" in
+irix*)
+with_mips_abi="${with_mips_abi:-yes}"
+if test -n "$GCC"; then
+
+# GCC < 2.8 only supports the O32 ABI. GCC >= 2.8 has a flag to select
+# which ABI to use, but only supports (as of 2.8.1) the N32 and 64 ABIs.
+#
+# Default to N32, but if GCC doesn't grok -mabi=n32, we assume an old
+# GCC and revert back to O32. The same goes if O32 is asked for - old
+# GCCs doesn't like the -mabi option, and new GCCs can't output O32.
+#
+# Don't you just love *all* the different SGI ABIs?
+
+case "${with_mips_abi}" in
+ 32|o32) abi='-mabi=32'; abilibdirext='' ;;
+ n32|yes) abi='-mabi=n32'; abilibdirext='32' ;;
+ 64) abi='-mabi=64'; abilibdirext='64' ;;
+ no) abi=''; abilibdirext='';;
+ *) AC_ERROR("Invalid ABI specified") ;;
+esac
+if test -n "$abi" ; then
+ac_foo=krb_cv_gcc_`echo $abi | tr =- __`
+dnl
+dnl can't use AC_CACHE_CHECK here, since it doesn't quote CACHE-ID to
+dnl AC_MSG_RESULT
+dnl
+AC_MSG_CHECKING([if $CC supports the $abi option])
+AC_CACHE_VAL($ac_foo, [
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $abi"
+AC_TRY_COMPILE(,int x;, eval $ac_foo=yes, eval $ac_foo=no)
+CFLAGS="$save_CFLAGS"
+])
+ac_res=`eval echo \\\$$ac_foo`
+AC_MSG_RESULT($ac_res)
+if test $ac_res = no; then
+# Try to figure out why that failed...
+case $abi in
+ -mabi=32)
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mabi=n32"
+ AC_TRY_COMPILE(,int x;, ac_res=yes, ac_res=no)
+ CLAGS="$save_CFLAGS"
+ if test $ac_res = yes; then
+ # New GCC
+ AC_ERROR([$CC does not support the $with_mips_abi ABI])
+ fi
+ # Old GCC
+ abi=''
+ abilibdirext=''
+ ;;
+ -mabi=n32|-mabi=64)
+ if test $with_mips_abi = yes; then
+ # Old GCC, default to O32
+ abi=''
+ abilibdirext=''
+ else
+ # Some broken GCC
+ AC_ERROR([$CC does not support the $with_mips_abi ABI])
+ fi
+ ;;
+esac
+fi #if test $ac_res = no; then
+fi #if test -n "$abi" ; then
+else
+case "${with_mips_abi}" in
+ 32|o32) abi='-32'; abilibdirext='' ;;
+ n32|yes) abi='-n32'; abilibdirext='32' ;;
+ 64) abi='-64'; abilibdirext='64' ;;
+ no) abi=''; abilibdirext='';;
+ *) AC_ERROR("Invalid ABI specified") ;;
+esac
+fi #if test -n "$GCC"; then
+;;
+esac
+])
diff --git a/crypto/heimdal/cf/misc.m4 b/crypto/heimdal/cf/misc.m4
new file mode 100644
index 000000000000..0be97a4758d1
--- /dev/null
+++ b/crypto/heimdal/cf/misc.m4
@@ -0,0 +1,3 @@
+dnl $Id: misc.m4,v 1.1 1997/12/14 15:59:04 joda Exp $
+dnl
+define(upcase,`echo $1 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`)dnl
diff --git a/crypto/heimdal/cf/need-proto.m4 b/crypto/heimdal/cf/need-proto.m4
new file mode 100644
index 000000000000..8c8d1d349081
--- /dev/null
+++ b/crypto/heimdal/cf/need-proto.m4
@@ -0,0 +1,25 @@
+dnl $Id: need-proto.m4,v 1.2 1999/03/01 09:52:24 joda Exp $
+dnl
+dnl
+dnl Check if we need the prototype for a function
+dnl
+
+dnl AC_NEED_PROTO(includes, function)
+
+AC_DEFUN(AC_NEED_PROTO, [
+if test "$ac_cv_func_$2+set" != set -o "$ac_cv_func_$2" = yes; then
+AC_CACHE_CHECK([if $2 needs a prototype], ac_cv_func_$2_noproto,
+AC_TRY_COMPILE([$1],
+[struct foo { int foo; } xx;
+extern int $2 (struct foo*);
+$2(&xx);
+],
+eval "ac_cv_func_$2_noproto=yes",
+eval "ac_cv_func_$2_noproto=no"))
+define([foo], [NEED_]translit($2, [a-z], [A-Z])[_PROTO])
+if test "$ac_cv_func_$2_noproto" = yes; then
+ AC_DEFINE(foo, 1, [define if the system is missing a prototype for $2()])
+fi
+undefine([foo])
+fi
+])
diff --git a/crypto/heimdal/cf/osfc2.m4 b/crypto/heimdal/cf/osfc2.m4
new file mode 100644
index 000000000000..d8cb2e112210
--- /dev/null
+++ b/crypto/heimdal/cf/osfc2.m4
@@ -0,0 +1,14 @@
+dnl $Id: osfc2.m4,v 1.2 1999/03/27 17:28:16 joda Exp $
+dnl
+dnl enable OSF C2 stuff
+
+AC_DEFUN(AC_CHECK_OSFC2,[
+AC_ARG_ENABLE(osfc2,
+[ --enable-osfc2 enable some OSF C2 support])
+LIB_security=
+if test "$enable_osfc2" = yes; then
+ AC_DEFINE(HAVE_OSFC2, 1, [Define to enable basic OSF C2 support.])
+ LIB_security=-lsecurity
+fi
+AC_SUBST(LIB_security)
+])
diff --git a/crypto/heimdal/cf/proto-compat.m4 b/crypto/heimdal/cf/proto-compat.m4
new file mode 100644
index 000000000000..942f658889d2
--- /dev/null
+++ b/crypto/heimdal/cf/proto-compat.m4
@@ -0,0 +1,22 @@
+dnl $Id: proto-compat.m4,v 1.3 1999/03/01 13:03:48 joda Exp $
+dnl
+dnl
+dnl Check if the prototype of a function is compatible with another one
+dnl
+
+dnl AC_PROTO_COMPAT(includes, function, prototype)
+
+AC_DEFUN(AC_PROTO_COMPAT, [
+AC_CACHE_CHECK([if $2 is compatible with system prototype],
+ac_cv_func_$2_proto_compat,
+AC_TRY_COMPILE([$1],
+[$3;],
+eval "ac_cv_func_$2_proto_compat=yes",
+eval "ac_cv_func_$2_proto_compat=no"))
+define([foo], translit($2, [a-z], [A-Z])[_PROTO_COMPATIBLE])
+if test "$ac_cv_func_$2_proto_compat" = yes; then
+ AC_DEFINE(foo, 1, [define if prototype of $2 is compatible with
+ $3])
+fi
+undefine([foo])
+]) \ No newline at end of file
diff --git a/crypto/heimdal/cf/shared-libs.m4 b/crypto/heimdal/cf/shared-libs.m4
new file mode 100644
index 000000000000..9fe576ff8b39
--- /dev/null
+++ b/crypto/heimdal/cf/shared-libs.m4
@@ -0,0 +1,187 @@
+dnl
+dnl $Id: shared-libs.m4,v 1.4 1999/07/13 17:47:09 assar Exp $
+dnl
+dnl Shared library stuff has to be different everywhere
+dnl
+
+AC_DEFUN(AC_SHARED_LIBS, [
+
+dnl Check if we want to use shared libraries
+AC_ARG_ENABLE(shared,
+[ --enable-shared create shared libraries for Kerberos])
+
+AC_SUBST(CFLAGS)dnl
+AC_SUBST(LDFLAGS)dnl
+
+case ${enable_shared} in
+ yes ) enable_shared=yes;;
+ no ) enable_shared=no;;
+ * ) enable_shared=no;;
+esac
+
+# NOTE: Building shared libraries may not work if you do not use gcc!
+#
+# OS $SHLIBEXT
+# HP-UX sl
+# Linux so
+# NetBSD so
+# FreeBSD so
+# OSF so
+# SunOS5 so
+# SunOS4 so.0.5
+# Irix so
+#
+# LIBEXT is the extension we should build (.a or $SHLIBEXT)
+LINK='$(CC)'
+AC_SUBST(LINK)
+lib_deps=yes
+REAL_PICFLAGS="-fpic"
+LDSHARED='$(CC) $(PICFLAGS) -shared'
+LIBPREFIX=lib
+build_symlink_command=@true
+install_symlink_command=@true
+install_symlink_command2=@true
+REAL_SHLIBEXT=so
+changequote({,})dnl
+SHLIB_VERSION=`echo $VERSION | sed 's/\([0-9.]*\).*/\1/'`
+SHLIB_SONAME=`echo $VERSION | sed 's/\([0-9]*\).*/\1/'`
+changequote([,])dnl
+case "${host}" in
+*-*-hpux*)
+ REAL_SHLIBEXT=sl
+ REAL_LD_FLAGS='-Wl,+b$(libdir)'
+ if test -z "$GCC"; then
+ LDSHARED="ld -b"
+ REAL_PICFLAGS="+z"
+ fi
+ lib_deps=no
+ ;;
+*-*-linux*)
+ LDSHARED='$(CC) -shared -Wl,-soname,$(LIBNAME).so.'"${SHLIB_SONAME}"
+ REAL_LD_FLAGS='-Wl,-rpath,$(libdir)'
+ REAL_SHLIBEXT=so.$SHLIB_VERSION
+ build_symlink_command='$(LN_S) -f [$][@] $(LIBNAME).so'
+ install_symlink_command='$(LN_S) -f $(LIB) $(DESTDIR)$(libdir)/$(LIBNAME).so.'"${SHLIB_SONAME}"';$(LN_S) -f $(LIB) $(DESTDIR)$(libdir)/$(LIBNAME).so'
+ install_symlink_command2='$(LN_S) -f $(LIB2) $(DESTDIR)$(libdir)/$(LIBNAME2).so.'"${SHLIB_SONAME}"';$(LN_S) -f $(LIB2) $(DESTDIR)$(libdir)/$(LIBNAME2).so'
+ ;;
+changequote(,)dnl
+*-*-freebsd[34]*)
+changequote([,])dnl
+ REAL_SHLIBEXT=so.$SHLIB_VERSION
+ REAL_LD_FLAGS='-Wl,-R$(libdir)'
+ build_symlink_command='$(LN_S) -f [$][@] $(LIBNAME).so'
+ install_symlink_command='$(LN_S) -f $(LIB) $(DESTDIR)$(libdir)/$(LIBNAME).so'
+ install_symlink_command2='$(LN_S) -f $(LIB2) $(DESTDIR)$(libdir)/$(LIBNAME2).so'
+ ;;
+*-*-*bsd*)
+ REAL_SHLIBEXT=so.$SHLIB_VERSION
+ LDSHARED='ld -Bshareable'
+ REAL_LD_FLAGS='-Wl,-R$(libdir)'
+ ;;
+*-*-osf*)
+ REAL_LD_FLAGS='-Wl,-rpath,$(libdir)'
+ REAL_PICFLAGS=
+ LDSHARED='ld -shared -expect_unresolved \*'
+ ;;
+*-*-solaris2*)
+ REAL_LD_FLAGS='-Wl,-R$(libdir)'
+ if test -z "$GCC"; then
+ LDSHARED='$(CC) -G'
+ REAL_PICFLAGS="-Kpic"
+ fi
+ ;;
+*-fujitsu-uxpv*)
+ REAL_LD_FLAGS='' # really: LD_RUN_PATH=$(libdir) cc -o ...
+ REAL_LINK='LD_RUN_PATH=$(libdir) $(CC)'
+ LDSHARED='$(CC) -G'
+ REAL_PICFLAGS="-Kpic"
+ lib_deps=no # fails in mysterious ways
+ ;;
+*-*-sunos*)
+ REAL_SHLIBEXT=so.$SHLIB_VERSION
+ REAL_LD_FLAGS='-Wl,-L$(libdir)'
+ lib_deps=no
+ ;;
+*-*-irix*)
+ libdir="${libdir}${abilibdirext}"
+ REAL_LD_FLAGS="${abi} -Wl,-rpath,\$(libdir)"
+ LD_FLAGS="${abi} -Wl,-rpath,\$(libdir)"
+ LDSHARED="\$(CC) -shared ${abi}"
+ REAL_PICFLAGS=
+ CFLAGS="${abi} ${CFLAGS}"
+ ;;
+*-*-os2*)
+ LIBPREFIX=
+ EXECSUFFIX='.exe'
+ RANLIB=EMXOMF
+ LD_FLAGS=-Zcrtdll
+ REAL_SHLIBEXT=nobuild
+ ;;
+*-*-cygwin32*)
+ EXECSUFFIX='.exe'
+ REAL_SHLIBEXT=nobuild
+ ;;
+*) REAL_SHLIBEXT=nobuild
+ REAL_PICFLAGS=
+ ;;
+esac
+
+if test "${enable_shared}" != "yes" ; then
+ PICFLAGS=""
+ SHLIBEXT="nobuild"
+ LIBEXT="a"
+ build_symlink_command=@true
+ install_symlink_command=@true
+ install_symlink_command2=@true
+else
+ PICFLAGS="$REAL_PICFLAGS"
+ SHLIBEXT="$REAL_SHLIBEXT"
+ LIBEXT="$SHLIBEXT"
+ AC_MSG_CHECKING(whether to use -rpath)
+ case "$libdir" in
+ /lib | /usr/lib | /usr/local/lib)
+ AC_MSG_RESULT(no)
+ REAL_LD_FLAGS=
+ LD_FLAGS=
+ ;;
+ *)
+ LD_FLAGS="$REAL_LD_FLAGS"
+ test "$REAL_LINK" && LINK="$REAL_LINK"
+ AC_MSG_RESULT($LD_FLAGS)
+ ;;
+ esac
+fi
+
+if test "$lib_deps" = yes; then
+ lib_deps_yes=""
+ lib_deps_no="# "
+else
+ lib_deps_yes="# "
+ lib_deps_no=""
+fi
+AC_SUBST(lib_deps_yes)
+AC_SUBST(lib_deps_no)
+
+# use supplied ld-flags, or none if `no'
+if test "$with_ld_flags" = no; then
+ LD_FLAGS=
+elif test -n "$with_ld_flags"; then
+ LD_FLAGS="$with_ld_flags"
+fi
+
+AC_SUBST(REAL_PICFLAGS) dnl
+AC_SUBST(REAL_SHLIBEXT) dnl
+AC_SUBST(REAL_LD_FLAGS) dnl
+
+AC_SUBST(PICFLAGS) dnl
+AC_SUBST(SHLIBEXT) dnl
+AC_SUBST(LDSHARED) dnl
+AC_SUBST(LD_FLAGS) dnl
+AC_SUBST(LIBEXT) dnl
+AC_SUBST(LIBPREFIX) dnl
+AC_SUBST(EXECSUFFIX) dnl
+
+AC_SUBST(build_symlink_command)dnl
+AC_SUBST(install_symlink_command)dnl
+AC_SUBST(install_symlink_command2)dnl
+])
diff --git a/crypto/heimdal/cf/test-package.m4 b/crypto/heimdal/cf/test-package.m4
new file mode 100644
index 000000000000..6bae158da60a
--- /dev/null
+++ b/crypto/heimdal/cf/test-package.m4
@@ -0,0 +1,88 @@
+dnl $Id: test-package.m4,v 1.7 1999/04/19 13:33:05 assar Exp $
+dnl
+dnl AC_TEST_PACKAGE_NEW(package,headers,libraries,extra libs,default locations)
+
+AC_DEFUN(AC_TEST_PACKAGE,[AC_TEST_PACKAGE_NEW($1,[#include <$2>],$4,,$5)])
+
+AC_DEFUN(AC_TEST_PACKAGE_NEW,[
+AC_ARG_WITH($1,
+[ --with-$1=dir use $1 in dir])
+AC_ARG_WITH($1-lib,
+[ --with-$1-lib=dir use $1 libraries in dir],
+[if test "$withval" = "yes" -o "$withval" = "no"; then
+ AC_MSG_ERROR([No argument for --with-$1-lib])
+elif test "X$with_$1" = "X"; then
+ with_$1=yes
+fi])
+AC_ARG_WITH($1-include,
+[ --with-$1-include=dir use $1 headers in dir],
+[if test "$withval" = "yes" -o "$withval" = "no"; then
+ AC_MSG_ERROR([No argument for --with-$1-include])
+elif test "X$with_$1" = "X"; then
+ with_$1=yes
+fi])
+
+AC_MSG_CHECKING(for $1)
+
+case "$with_$1" in
+yes) ;;
+no) ;;
+"") ;;
+*) if test "$with_$1_include" = ""; then
+ with_$1_include="$with_$1/include"
+ fi
+ if test "$with_$1_lib" = ""; then
+ with_$1_lib="$with_$1/lib$abilibdirext"
+ fi
+ ;;
+esac
+header_dirs=
+lib_dirs=
+d='$5'
+for i in $d; do
+ header_dirs="$header_dirs $i/include"
+ lib_dirs="$lib_dirs $i/lib$abilibdirext"
+done
+
+case "$with_$1_include" in
+yes) ;;
+no) ;;
+*) header_dirs="$with_$1_include $header_dirs";;
+esac
+case "$with_$1_lib" in
+yes) ;;
+no) ;;
+*) lib_dirs="$with_$1_lib $lib_dirs";;
+esac
+
+save_CFLAGS="$CFLAGS"
+save_LIBS="$LIBS"
+ires= lres=
+for i in $header_dirs; do
+ CFLAGS="-I$i $save_CFLAGS"
+ AC_TRY_COMPILE([$2],,ires=$i;break)
+done
+for i in $lib_dirs; do
+ LIBS="-L$i $3 $4 $save_LIBS"
+ AC_TRY_LINK([$2],,lres=$i;break)
+done
+CFLAGS="$save_CFLAGS"
+LIBS="$save_LIBS"
+
+if test "$ires" -a "$lres" -a "$with_$1" != "no"; then
+ $1_includedir="$ires"
+ $1_libdir="$lres"
+ INCLUDE_$1="-I$$1_includedir"
+ LIB_$1="-L$$1_libdir $3"
+ AC_DEFINE_UNQUOTED(upcase($1),1,[Define if you have the $1 package.])
+ with_$1=yes
+ AC_MSG_RESULT([headers $ires, libraries $lres])
+else
+ INCLUDE_$1=
+ LIB_$1=
+ with_$1=no
+ AC_MSG_RESULT($with_$1)
+fi
+AC_SUBST(INCLUDE_$1)
+AC_SUBST(LIB_$1)
+])
diff --git a/crypto/heimdal/cf/wflags.m4 b/crypto/heimdal/cf/wflags.m4
new file mode 100644
index 000000000000..6d9e0736618b
--- /dev/null
+++ b/crypto/heimdal/cf/wflags.m4
@@ -0,0 +1,21 @@
+dnl $Id: wflags.m4,v 1.3 1999/03/11 12:11:41 joda Exp $
+dnl
+dnl set WFLAGS
+
+AC_DEFUN(AC_WFLAGS,[
+WFLAGS_NOUNUSED=""
+WFLAGS_NOIMPLICITINT=""
+if test -z "$WFLAGS" -a "$GCC" = "yes"; then
+ # -Wno-implicit-int for broken X11 headers
+ # leave these out for now:
+ # -Wcast-align doesn't work well on alpha osf/1
+ # -Wmissing-prototypes -Wpointer-arith -Wbad-function-cast
+ # -Wmissing-declarations -Wnested-externs
+ WFLAGS="ifelse($#, 0,-Wall, $1)"
+ WFLAGS_NOUNUSED="-Wno-unused"
+ WFLAGS_NOIMPLICITINT="-Wno-implicit-int"
+fi
+AC_SUBST(WFLAGS)dnl
+AC_SUBST(WFLAGS_NOUNUSED)dnl
+AC_SUBST(WFLAGS_NOIMPLICITINT)dnl
+])
diff --git a/crypto/heimdal/config.guess b/crypto/heimdal/config.guess
new file mode 100755
index 000000000000..4e5345fac2e4
--- /dev/null
+++ b/crypto/heimdal/config.guess
@@ -0,0 +1,973 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >$dummy.s
+ .globl main
+ .ent main
+main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ ${CC-cc} $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-cbm-sysv4
+ exit 0;;
+ amiga:NetBSD:*:*)
+ echo m68k-cbm-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ arm32:NetBSD:*:*)
+ echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:*|MIS*:OSx*:*:*|MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:NetBSD:*:*)
+ echo m68k-atari-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:NetBSD:*:*)
+ echo m68k-sun-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:NetBSD:*:*)
+ echo m68k-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:NetBSD:*:*)
+ echo powerpc-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >$dummy.c
+ int main (argc, argv) int argc; char **argv; {
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ ${CC-cc} $dummy.c -o $dummy \
+ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i?86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ ${CC-cc} $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:4)
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=4.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 )
+ sed 's/^ //' << EOF >$dummy.c
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (${CC-cc} $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+ rm -f $dummy.c $dummy
+ esac
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ ${CC-cc} $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo t3e-cray-unicosmk${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
+ hp3[0-9][05]:NetBSD:*:*)
+ echo m68k-hp-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | i?86:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:NetBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:Linux:*:*)
+ # uname on the ARM produces all sorts of strangeness, and we need to
+ # filter it out.
+ case "$UNAME_MACHINE" in
+ arm* | sa110*) UNAME_MACHINE="arm" ;;
+ esac
+
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us.
+ ld_help_string=`ld --help 2>&1`
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
+ i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
+ sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ sed 's/^ //' <<EOF >$dummy.s
+ .globl main
+ .ent main
+ main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ LIBC=""
+ ${CC-cc} $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+
+ objdump --private-headers $dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >$dummy.c <<EOF
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ else
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >$dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+ i?86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i?86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ i?86:UnixWare:*:*)
+ if /bin/uname -X 2>/dev/null >/dev/null ; then
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ fi
+ echo ${UNAME_MACHINE}-unixware-${UNAME_RELEASE}-${UNAME_VERSION}
+ exit 0 ;;
+ pc:*:*:*)
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i?86:LynxOS:2.*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+ printf ("vax-dec-bsd\n"); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/crypto/heimdal/config.sub b/crypto/heimdal/config.sub
new file mode 100755
index 000000000000..7a4049528f26
--- /dev/null
+++ b/crypto/heimdal/config.sub
@@ -0,0 +1,957 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+ echo Configuration name missing. 1>&2
+ echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+ echo "or $0 ALIAS" 1>&2
+ echo where ALIAS is a recognized configuration type. 1>&2
+ exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+ *local*)
+ echo $1
+ exit 0
+ ;;
+ *)
+ ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
+ os=
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+ | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
+ | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 \
+ | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
+ | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
+ | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+ | mipstx39 | mipstx39el \
+ | sparc | sparclet | sparclite | sparc64 | v850)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[34567]86)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+ | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* \
+ | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
+ | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
+ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+ | sparc64-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mipstx39-* | mipstx39el-* \
+ | f301-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-cbm
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-cbm
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-cbm
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [ctj]90-cray)
+ #basic_machine=c90-cray
+ os=`echo $os | sed -e 's/\(unicos[0-9]*\.[0-9]*\).*/\1/'`
+ #os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i[34567]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i[34567]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i[34567]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i[34567]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | nexen)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | k6 | 6x86)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | nexen-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | k6-* | 6x86-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=rs6000-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sparc)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -rhapsody* \
+ | -openstep*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f301-fujitsu)
+ os=-uxpv
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
diff --git a/crypto/heimdal/configure b/crypto/heimdal/configure
new file mode 100755
index 000000000000..a871362cc2b5
--- /dev/null
+++ b/crypto/heimdal/configure
@@ -0,0 +1,12371 @@
+#! /bin/sh
+
+# From configure.in Revision: 1.215
+
+
+
+
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+
+
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# serial 25 AM_PROG_LIBTOOL
+
+
+# AM_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AM_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+
+
+# AM_DISABLE_SHARED - set the default shared flag to --disable-shared
+
+
+# AM_DISABLE_STATIC - set the default static flag to --disable-static
+
+
+# AM_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AM_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+
+
+
+# AM_PROG_LD - find the path to the GNU or non-GNU linker
+
+
+
+
+# AM_PROG_NM - find the path to a BSD-compatible name lister
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Define a conditional.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_default_prefix=/usr/heimdal
+ac_help="$ac_help
+ --with-mips-abi=abi ABI to use for IRIX (32, n32, or 64)"
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=no]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --without-berkeley-db if you don't want berkeley db"
+ac_help="$ac_help
+ --with-krb4=dir use krb4 in dir"
+ac_help="$ac_help
+ --with-krb4-lib=dir use krb4 libraries in dir"
+ac_help="$ac_help
+ --with-krb4-include=dir use krb4 headers in dir"
+ac_help="$ac_help
+ --enable-kaserver if you want the KDC to try to emulate a kaserver"
+ac_help="$ac_help
+ --enable-kaserver-db if you want support for reading kaserver databases in hprop"
+ac_help="$ac_help
+ --disable-otp if you don't want OTP support"
+ac_help="$ac_help
+ --enable-osfc2 enable some OSF C2 support"
+ac_help="$ac_help
+ --with-readline=dir use readline in dir"
+ac_help="$ac_help
+ --with-readline-lib=dir use readline libraries in dir"
+ac_help="$ac_help
+ --with-readline-include=dir use readline headers in dir"
+ac_help="$ac_help
+ --with-hesiod=dir use hesiod in dir"
+ac_help="$ac_help
+ --with-hesiod-lib=dir use hesiod libraries in dir"
+ac_help="$ac_help
+ --with-hesiod-include=dir use hesiod headers in dir"
+ac_help="$ac_help
+ --enable-bigendian the target is big endian"
+ac_help="$ac_help
+ --enable-littleendian the target is little endian"
+ac_help="$ac_help
+ --with-x use the X Window System"
+ac_help="$ac_help
+ --enable-netinfo enable netinfo for configuration lookup"
+ac_help="$ac_help
+ --without-ipv6 do not enable IPv6 support"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=lib/krb5/send_to_kdc.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:776: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:829: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:886: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=heimdal
+
+VERSION=0.2m
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:932: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:945: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:958: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:971: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:984: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1007: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+CANONICAL_HOST=$host
+
+
+sunos=no
+case "$host" in
+*-*-sunos4*)
+ sunos=40
+ ;;
+*-*-solaris2.7)
+ sunos=57
+ ;;
+*-*-solaris2*)
+ sunos=50
+ ;;
+esac
+if test "$sunos" != no; then
+ cat >> confdefs.h <<EOF
+#define SunOS $sunos
+EOF
+
+fi
+
+aix=no
+case "$host" in
+*-*-aix3*)
+ aix=3
+ ;;
+*-*-aix4*)
+ aix=4
+ ;;
+esac
+
+#test -z "$CFLAGS" && CFLAGS="-g"
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1064: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1094: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1145: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1177: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1188 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1193: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1219: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1224: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1233: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1252: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:1285: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1290 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:1301: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for object suffix""... $ac_c" 1>&6
+echo "configure:1318: checking for object suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftest*
+echo 'int i = 1;' > conftest.$ac_ext
+if { (eval echo configure:1324: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+else
+ { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_objext" 1>&6
+OBJEXT=$ac_cv_objext
+ac_objext=$ac_cv_objext
+
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:1342: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1347 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:1354: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:1373: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:1383: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1409: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1440: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1455 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1461: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1472 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1478: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1489 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1495: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+missing_dir=`cd $ac_aux_dir && pwd`
+for ac_prog in flex lex
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1525: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=""$missing_dir/missing flex""
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1558: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="flex"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+ case "$LEX" in
+ flex*) ac_lib=fl ;;
+ *) ac_lib=l ;;
+ esac
+ echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:1592: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1600 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap();
+
+int main() {
+yywrap()
+; return 0; }
+EOF
+if { (eval echo configure:1611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LEXLIB="-l$ac_lib"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking lex output file root""... $ac_c" 1>&6
+echo "configure:1634: checking lex output file root" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # The minimal lex program is just a single line: %%. But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+echo '%%
+%%' | $LEX
+if test -f lex.yy.c; then
+ ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+ ac_cv_prog_lex_root=lexyy
+else
+ { echo "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; }
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_root" 1>&6
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6
+echo "configure:1655: checking whether yytext is a pointer" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS="$LIBS"
+LIBS="$LIBS $LEXLIB"
+cat > conftest.$ac_ext <<EOF
+#line 1667 "configure"
+#include "confdefs.h"
+`cat $LEX_OUTPUT_ROOT.c`
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_prog_lex_yytext_pointer=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+ cat >> confdefs.h <<\EOF
+#define YYTEXT_POINTER 1
+EOF
+
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1698: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+for ac_prog in mawk gawk nawk awk
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1730: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AWK="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AWK="$ac_cv_prog_AWK"
+if test -n "$AWK"; then
+ echo "$ac_t""$AWK" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AWK" && break
+done
+
+echo $ac_n "checking for ln -s or something else""... $ac_c" 1>&6
+echo "configure:1760: checking for ln -s or something else" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ touch conftestdata1
+ if ln conftestdata1 conftestdata2; then
+ rm -f conftestdata*
+ ac_cv_prog_LN_S=ln
+ else
+ ac_cv_prog_LN_S=cp
+ fi
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+echo "$ac_t""$ac_cv_prog_LN_S" 1>&6
+
+
+
+# Check whether --with-mips_abi or --without-mips_abi was given.
+if test "${with_mips_abi+set}" = set; then
+ withval="$with_mips_abi"
+ :
+fi
+
+
+case "$host_os" in
+irix*)
+with_mips_abi="${with_mips_abi:-yes}"
+if test -n "$GCC"; then
+
+# GCC < 2.8 only supports the O32 ABI. GCC >= 2.8 has a flag to select
+# which ABI to use, but only supports (as of 2.8.1) the N32 and 64 ABIs.
+#
+# Default to N32, but if GCC doesn't grok -mabi=n32, we assume an old
+# GCC and revert back to O32. The same goes if O32 is asked for - old
+# GCCs doesn't like the -mabi option, and new GCCs can't output O32.
+#
+# Don't you just love *all* the different SGI ABIs?
+
+case "${with_mips_abi}" in
+ 32|o32) abi='-mabi=32'; abilibdirext='' ;;
+ n32|yes) abi='-mabi=n32'; abilibdirext='32' ;;
+ 64) abi='-mabi=64'; abilibdirext='64' ;;
+ no) abi=''; abilibdirext='';;
+ *) { echo "configure: error: "Invalid ABI specified"" 1>&2; exit 1; } ;;
+esac
+if test -n "$abi" ; then
+ac_foo=krb_cv_gcc_`echo $abi | tr =- __`
+echo $ac_n "checking if $CC supports the $abi option""... $ac_c" 1>&6
+echo "configure:1815: checking if $CC supports the $abi option" >&5
+if eval "test \"`echo '$''{'$ac_foo'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $abi"
+cat > conftest.$ac_ext <<EOF
+#line 1823 "configure"
+#include "confdefs.h"
+
+int main() {
+int x;
+; return 0; }
+EOF
+if { (eval echo configure:1830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval $ac_foo=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval $ac_foo=no
+fi
+rm -f conftest*
+CFLAGS="$save_CFLAGS"
+
+fi
+
+ac_res=`eval echo \\\$$ac_foo`
+echo "$ac_t""$ac_res" 1>&6
+if test $ac_res = no; then
+# Try to figure out why that failed...
+case $abi in
+ -mabi=32)
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mabi=n32"
+ cat > conftest.$ac_ext <<EOF
+#line 1853 "configure"
+#include "confdefs.h"
+
+int main() {
+int x;
+; return 0; }
+EOF
+if { (eval echo configure:1860: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_res=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_res=no
+fi
+rm -f conftest*
+ CLAGS="$save_CFLAGS"
+ if test $ac_res = yes; then
+ # New GCC
+ { echo "configure: error: $CC does not support the $with_mips_abi ABI" 1>&2; exit 1; }
+ fi
+ # Old GCC
+ abi=''
+ abilibdirext=''
+ ;;
+ -mabi=n32|-mabi=64)
+ if test $with_mips_abi = yes; then
+ # Old GCC, default to O32
+ abi=''
+ abilibdirext=''
+ else
+ # Some broken GCC
+ { echo "configure: error: $CC does not support the $with_mips_abi ABI" 1>&2; exit 1; }
+ fi
+ ;;
+esac
+fi #if test $ac_res = no; then
+fi #if test -n "$abi" ; then
+else
+case "${with_mips_abi}" in
+ 32|o32) abi='-32'; abilibdirext='' ;;
+ n32|yes) abi='-n32'; abilibdirext='32' ;;
+ 64) abi='-64'; abilibdirext='64' ;;
+ no) abi=''; abilibdirext='';;
+ *) { echo "configure: error: "Invalid ABI specified"" 1>&2; exit 1; } ;;
+esac
+fi #if test -n "$GCC"; then
+;;
+esac
+
+CC="$CC $abi"
+libdir="$libdir$abilibdirext"
+
+
+echo $ac_n "checking for __attribute__""... $ac_c" 1>&6
+echo "configure:1909: checking for __attribute__" >&5
+if eval "test \"`echo '$''{'ac_cv___attribute__'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 1915 "configure"
+#include "confdefs.h"
+
+#include <stdlib.h>
+
+int main() {
+
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+ exit(1);
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1932: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv___attribute__=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv___attribute__=no
+fi
+rm -f conftest*
+fi
+
+if test "$ac_cv___attribute__" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE___ATTRIBUTE__ 1
+EOF
+
+fi
+echo "$ac_t""$ac_cv___attribute__" 1>&6
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=no
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:2012: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ /* | [A-Za-z]:\\*)
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:2030: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:2033: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:2069: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:2085: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ else
+ ac_cv_path_NM="$ac_dir/nm"
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:2120: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Always use our own libtool.
+LIBTOOL='$(top_builddir)/libtool'
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags=
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 2156 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:2157: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ CFLAGS="$CFLAGS -belf"
+ ;;
+esac
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
+WFLAGS_NOUNUSED=""
+WFLAGS_NOIMPLICITINT=""
+if test -z "$WFLAGS" -a "$GCC" = "yes"; then
+ # -Wno-implicit-int for broken X11 headers
+ # leave these out for now:
+ # -Wcast-align doesn't work well on alpha osf/1
+ # -Wmissing-prototypes -Wpointer-arith -Wbad-function-cast
+ # -Wmissing-declarations -Wnested-externs
+ WFLAGS="-Wall -Wmissing-prototypes -Wpointer-arith -Wbad-function-cast -Wmissing-declarations -Wnested-externs"
+ WFLAGS_NOUNUSED="-Wno-unused"
+ WFLAGS_NOIMPLICITINT="-Wno-implicit-int"
+fi
+
+
+berkeley_db=db
+# Check whether --with-berkeley-db or --without-berkeley-db was given.
+if test "${with_berkeley_db+set}" = set; then
+ withval="$with_berkeley_db"
+
+if test "$withval" = no; then
+ berkeley_db=""
+fi
+
+fi
+
+
+
+# Check whether --with-krb4 or --without-krb4 was given.
+if test "${with_krb4+set}" = set; then
+ withval="$with_krb4"
+ :
+fi
+
+# Check whether --with-krb4-lib or --without-krb4-lib was given.
+if test "${with_krb4_lib+set}" = set; then
+ withval="$with_krb4_lib"
+ if test "$withval" = "yes" -o "$withval" = "no"; then
+ { echo "configure: error: No argument for --with-krb4-lib" 1>&2; exit 1; }
+elif test "X$with_krb4" = "X"; then
+ with_krb4=yes
+fi
+fi
+
+# Check whether --with-krb4-include or --without-krb4-include was given.
+if test "${with_krb4_include+set}" = set; then
+ withval="$with_krb4_include"
+ if test "$withval" = "yes" -o "$withval" = "no"; then
+ { echo "configure: error: No argument for --with-krb4-include" 1>&2; exit 1; }
+elif test "X$with_krb4" = "X"; then
+ with_krb4=yes
+fi
+fi
+
+
+echo $ac_n "checking for krb4""... $ac_c" 1>&6
+echo "configure:2247: checking for krb4" >&5
+
+case "$with_krb4" in
+yes) ;;
+no) ;;
+"") ;;
+*) if test "$with_krb4_include" = ""; then
+ with_krb4_include="$with_krb4/include"
+ fi
+ if test "$with_krb4_lib" = ""; then
+ with_krb4_lib="$with_krb4/lib$abilibdirext"
+ fi
+ ;;
+esac
+header_dirs=
+lib_dirs=
+d='/usr/athena'
+for i in $d; do
+ header_dirs="$header_dirs $i/include"
+ lib_dirs="$lib_dirs $i/lib$abilibdirext"
+done
+
+case "$with_krb4_include" in
+yes) ;;
+no) ;;
+*) header_dirs="$with_krb4_include $header_dirs";;
+esac
+case "$with_krb4_lib" in
+yes) ;;
+no) ;;
+*) lib_dirs="$with_krb4_lib $lib_dirs";;
+esac
+
+save_CFLAGS="$CFLAGS"
+save_LIBS="$LIBS"
+ires= lres=
+for i in $header_dirs; do
+ CFLAGS="-I$i $save_CFLAGS"
+ cat > conftest.$ac_ext <<EOF
+#line 2286 "configure"
+#include "confdefs.h"
+#include <krb.h>
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2293: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ires=$i;break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+for i in $lib_dirs; do
+ LIBS="-L$i -lkrb -ldes $save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 2305 "configure"
+#include "confdefs.h"
+#include <krb.h>
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lres=$i;break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+CFLAGS="$save_CFLAGS"
+LIBS="$save_LIBS"
+
+if test "$ires" -a "$lres" -a "$with_krb4" != "no"; then
+ krb4_includedir="$ires"
+ krb4_libdir="$lres"
+ INCLUDE_krb4="-I$krb4_includedir"
+ LIB_krb4="-L$krb4_libdir -lkrb"
+ cat >> confdefs.h <<EOF
+#define `echo krb4 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` 1
+EOF
+
+ with_krb4=yes
+ echo "$ac_t""headers $ires, libraries $lres" 1>&6
+else
+ INCLUDE_krb4=
+ LIB_krb4=
+ with_krb4=no
+ echo "$ac_t""$with_krb4" 1>&6
+fi
+
+
+
+
+LIB_kdb=
+if test "$with_krb4" != "no"; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $INCLUDE_krb4"
+ save_LIBS="$LIBS"
+ LIBS="$LIB_krb4 -ldes $LIBS"
+ EXTRA_LIB45=lib45.a
+
+ echo $ac_n "checking for four valued krb_put_int""... $ac_c" 1>&6
+echo "configure:2354: checking for four valued krb_put_int" >&5
+if eval "test \"`echo '$''{'ac_cv_func_krb_put_int_four'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2359 "configure"
+#include "confdefs.h"
+#include <krb.h>
+int main() {
+
+ char tmp[4];
+ krb_put_int(17, tmp, 4, sizeof(tmp));
+; return 0; }
+EOF
+if { (eval echo configure:2368: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_func_krb_put_int_four=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_krb_put_int_four=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_func_krb_put_int_four" 1>&6
+ if test "$ac_cv_func_krb_put_int_four" = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_FOUR_VALUED_KRB_PUT_INT 1
+EOF
+
+ fi
+ echo $ac_n "checking for KRB_VERIFY_SECURE""... $ac_c" 1>&6
+echo "configure:2389: checking for KRB_VERIFY_SECURE" >&5
+if eval "test \"`echo '$''{'ac_cv_func_krb_verify_secure'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2394 "configure"
+#include "confdefs.h"
+#include <krb.h>
+int main() {
+
+ int x = KRB_VERIFY_SECURE
+; return 0; }
+EOF
+if { (eval echo configure:2402: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_func_krb_verify_secure=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_krb_verify_secure=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_func_krb_verify_secure" 1>&6
+ if test "$ac_cv_func_krb_verify_secure" != yes; then
+ cat >> confdefs.h <<\EOF
+#define KRB_VERIFY_SECURE 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define KRB_VERIFY_SECURE_FAIL 2
+EOF
+
+ fi
+ echo $ac_n "checking for KRB_VERIFY_NOT_SECURE""... $ac_c" 1>&6
+echo "configure:2427: checking for KRB_VERIFY_NOT_SECURE" >&5
+if eval "test \"`echo '$''{'ac_cv_func_krb_verify_not_secure'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2432 "configure"
+#include "confdefs.h"
+#include <krb.h>
+int main() {
+
+ int x = KRB_VERIFY_NOT_SECURE
+; return 0; }
+EOF
+if { (eval echo configure:2440: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_func_krb_verify_not_secure=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_krb_verify_not_secure=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_func_krb_verify_not_secure" 1>&6
+ if test "$ac_cv_func_krb_verify_not_secure" != yes; then
+ cat >> confdefs.h <<\EOF
+#define KRB_VERIFY_NOT_SECURE 0
+EOF
+
+ fi
+
+
+
+
+echo $ac_n "checking for krb_enable_debug""... $ac_c" 1>&6
+echo "configure:2465: checking for krb_enable_debug" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_krb_enable_debug'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_krb_enable_debug\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" ; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 2480 "configure"
+#include "confdefs.h"
+
+int main() {
+krb_enable_debug()
+; return 0; }
+EOF
+if { (eval echo configure:2487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_krb_enable_debug=$ac_lib; else ac_cv_funclib_krb_enable_debug=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_krb_enable_debug=\${ac_cv_funclib_krb_enable_debug-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_krb_enable_debug"
+
+: << END
+@@@funcs="$funcs krb_enable_debug"@@@
+@@@libs="$libs "" "@@@
+END
+
+# krb_enable_debug
+eval "ac_tr_func=HAVE_`echo krb_enable_debug | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_krb_enable_debug=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_krb_enable_debug=yes"
+ eval "LIB_krb_enable_debug="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_krb_enable_debug=no"
+ eval "LIB_krb_enable_debug="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_krb_enable_debug=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test -n "$LIB_krb_enable_debug"; then
+ LIBS="$LIB_krb_enable_debug $LIBS"
+fi
+
+
+
+
+
+echo $ac_n "checking for krb_disable_debug""... $ac_c" 1>&6
+echo "configure:2555: checking for krb_disable_debug" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_krb_disable_debug'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_krb_disable_debug\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" ; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 2570 "configure"
+#include "confdefs.h"
+
+int main() {
+krb_disable_debug()
+; return 0; }
+EOF
+if { (eval echo configure:2577: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_krb_disable_debug=$ac_lib; else ac_cv_funclib_krb_disable_debug=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_krb_disable_debug=\${ac_cv_funclib_krb_disable_debug-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_krb_disable_debug"
+
+: << END
+@@@funcs="$funcs krb_disable_debug"@@@
+@@@libs="$libs "" "@@@
+END
+
+# krb_disable_debug
+eval "ac_tr_func=HAVE_`echo krb_disable_debug | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_krb_disable_debug=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_krb_disable_debug=yes"
+ eval "LIB_krb_disable_debug="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_krb_disable_debug=no"
+ eval "LIB_krb_disable_debug="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_krb_disable_debug=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test -n "$LIB_krb_disable_debug"; then
+ LIBS="$LIB_krb_disable_debug $LIBS"
+fi
+
+
+
+
+
+echo $ac_n "checking for krb_get_our_ip_for_realm""... $ac_c" 1>&6
+echo "configure:2645: checking for krb_get_our_ip_for_realm" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_krb_get_our_ip_for_realm'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_krb_get_our_ip_for_realm\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" ; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 2660 "configure"
+#include "confdefs.h"
+
+int main() {
+krb_get_our_ip_for_realm()
+; return 0; }
+EOF
+if { (eval echo configure:2667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_krb_get_our_ip_for_realm=$ac_lib; else ac_cv_funclib_krb_get_our_ip_for_realm=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_krb_get_our_ip_for_realm=\${ac_cv_funclib_krb_get_our_ip_for_realm-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_krb_get_our_ip_for_realm"
+
+: << END
+@@@funcs="$funcs krb_get_our_ip_for_realm"@@@
+@@@libs="$libs "" "@@@
+END
+
+# krb_get_our_ip_for_realm
+eval "ac_tr_func=HAVE_`echo krb_get_our_ip_for_realm | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_krb_get_our_ip_for_realm=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_krb_get_our_ip_for_realm=yes"
+ eval "LIB_krb_get_our_ip_for_realm="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_krb_get_our_ip_for_realm=no"
+ eval "LIB_krb_get_our_ip_for_realm="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_krb_get_our_ip_for_realm=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test -n "$LIB_krb_get_our_ip_for_realm"; then
+ LIBS="$LIB_krb_get_our_ip_for_realm $LIBS"
+fi
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+ LIB_kdb="-lkdb -lkrb"
+ if test "$krb4_libdir"; then
+ LIB_krb4="-rpath $krb4_libdir $LIB_krb4"
+ LIB_kdb="-rpath $krb4_libdir -L$krb4_libdir $LIB_kdb"
+ fi
+fi
+
+
+if test "$with_krb4" != "no"; then
+ KRB4_TRUE=
+ KRB4_FALSE='#'
+else
+ KRB4_TRUE='#'
+ KRB4_FALSE=
+fi
+
+
+if true; then
+ KRB5_TRUE=
+ KRB5_FALSE='#'
+else
+ KRB5_TRUE='#'
+ KRB5_FALSE=
+fi
+cat >> confdefs.h <<\EOF
+#define KRB5 1
+EOF
+
+
+if test "$aix" != no; then
+ AIX_TRUE=
+ AIX_FALSE='#'
+else
+ AIX_TRUE='#'
+ AIX_FALSE=
+fi
+
+if test "$aix" = 4; then
+ AIX4_TRUE=
+ AIX4_FALSE='#'
+else
+ AIX4_TRUE='#'
+ AIX4_FALSE=
+fi
+aix_dynamic_afs=yes
+
+
+if test "$aix_dynamic_afs" = yes; then
+ AIX_DYNAMIC_AFS_TRUE=
+ AIX_DYNAMIC_AFS_FALSE='#'
+else
+ AIX_DYNAMIC_AFS_TRUE='#'
+ AIX_DYNAMIC_AFS_FALSE=
+fi
+
+
+
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "configure:2790: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_dlopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_dlopen\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" dl; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 2805 "configure"
+#include "confdefs.h"
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:2812: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_dlopen=$ac_lib; else ac_cv_funclib_dlopen=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_dlopen=\${ac_cv_funclib_dlopen-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_dlopen"
+
+: << END
+@@@funcs="$funcs dlopen"@@@
+@@@libs="$libs "" dl"@@@
+END
+
+# dlopen
+eval "ac_tr_func=HAVE_`echo dlopen | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_dlopen=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_dlopen=yes"
+ eval "LIB_dlopen="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_dlopen=no"
+ eval "LIB_dlopen="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_dlopen=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+
+if test "$aix" != no; then
+ if test "$aix_dynamic_afs" = yes; then
+ if test "$ac_cv_funclib_dlopen" = yes; then
+ AIX_EXTRA_KAFS=
+ elif test "$ac_cv_funclib_dlopen" != no; then
+ AIX_EXTRA_KAFS="$ac_cv_funclib_dlopen"
+ else
+ AIX_EXTRA_KAFS=-lld
+ fi
+ else
+ AIX_EXTRA_KAFS=
+ fi
+fi
+
+
+
+if test "$ac_cv_funclib_dlopen" != no; then
+ HAVE_DLOPEN_TRUE=
+ HAVE_DLOPEN_FALSE='#'
+else
+ HAVE_DLOPEN_TRUE='#'
+ HAVE_DLOPEN_FALSE=
+fi
+# Check whether --enable-kaserver or --disable-kaserver was given.
+if test "${enable_kaserver+set}" = set; then
+ enableval="$enable_kaserver"
+ :
+fi
+
+if test "$enable_kaserver" = yes; then
+ cat >> confdefs.h <<\EOF
+#define KASERVER 1
+EOF
+
+ if test "$with_krb4" = "no"; then
+ { echo "configure: error: kaserver requires krb4" 1>&2; exit 1; }
+ exit 1
+ fi
+fi
+
+# Check whether --enable-kaserver-db or --disable-kaserver-db was given.
+if test "${enable_kaserver_db+set}" = set; then
+ enableval="$enable_kaserver_db"
+ :
+fi
+
+if test "$enable_kaserver_db" = yes; then
+ cat >> confdefs.h <<\EOF
+#define KASERVER_DB 1
+EOF
+
+ if test "$with_krb4" = "no"; then
+ { echo "configure: error: kaserver-db requires krb4" 1>&2; exit 1; }
+ exit 1
+ fi
+fi
+
+otp=yes
+# Check whether --enable-otp or --disable-otp was given.
+if test "${enable_otp+set}" = set; then
+ enableval="$enable_otp"
+
+if test "$enableval" = "no"; then
+ otp=no
+fi
+
+fi
+
+if test "$otp" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define OTP 1
+EOF
+
+ LIB_otp='$(top_builddir)/lib/otp/libotp.la'
+fi
+
+
+
+if test "$otp" = yes; then
+ OTP_TRUE=
+ OTP_FALSE='#'
+else
+ OTP_TRUE='#'
+ OTP_FALSE=
+fi
+
+# Check whether --enable-osfc2 or --disable-osfc2 was given.
+if test "${enable_osfc2+set}" = set; then
+ enableval="$enable_osfc2"
+ :
+fi
+
+LIB_security=
+if test "$enable_osfc2" = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_OSFC2 1
+EOF
+
+ LIB_security=-lsecurity
+fi
+
+
+
+# Extract the first word of "nroff", so it can be a program name with args.
+set dummy nroff; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2978: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NROFF'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$NROFF" in
+ /*)
+ ac_cv_path_NROFF="$NROFF" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_NROFF="$NROFF" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_NROFF="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+NROFF="$ac_cv_path_NROFF"
+if test -n "$NROFF"; then
+ echo "$ac_t""$NROFF" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "groff", so it can be a program name with args.
+set dummy groff; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3013: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GROFF'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GROFF" in
+ /*)
+ ac_cv_path_GROFF="$GROFF" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GROFF="$GROFF" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GROFF="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+GROFF="$ac_cv_path_GROFF"
+if test -n "$GROFF"; then
+ echo "$ac_t""$GROFF" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking how to format man pages""... $ac_c" 1>&6
+echo "configure:3046: checking how to format man pages" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_man_format'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.1 << END
+.Dd January 1, 1970
+.Dt CONFTEST 1
+.Sh NAME
+.Nm conftest
+.Nd
+foobar
+END
+
+if test "$NROFF" ; then
+ for i in "-mdoc" "-mandoc"; do
+ if "$NROFF" $i conftest.1 2> /dev/null | \
+ grep Jan > /dev/null 2>&1 ; then
+ ac_cv_sys_man_format="$NROFF $i"
+ break
+ fi
+ done
+fi
+if test "$ac_cv_sys_man_format" = "" -a "$GROFF" ; then
+ for i in "-mdoc" "-mandoc"; do
+ if "$GROFF" -Tascii $i conftest.1 2> /dev/null | \
+ grep Jan > /dev/null 2>&1 ; then
+ ac_cv_sys_man_format="$GROFF -Tascii $i"
+ break
+ fi
+ done
+fi
+if test "$ac_cv_sys_man_format"; then
+ ac_cv_sys_man_format="$ac_cv_sys_man_format \$< > \$@"
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_sys_man_format" 1>&6
+if test "$ac_cv_sys_man_format"; then
+ CATMAN="$ac_cv_sys_man_format"
+
+fi
+
+
+if test "$CATMAN"; then
+ CATMAN_TRUE=
+ CATMAN_FALSE='#'
+else
+ CATMAN_TRUE='#'
+ CATMAN_FALSE=
+fi
+echo $ac_n "checking extension of pre-formatted manual pages""... $ac_c" 1>&6
+echo "configure:3098: checking extension of pre-formatted manual pages" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_catman_ext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if grep _suffix /etc/man.conf > /dev/null 2>&1; then
+ ac_cv_sys_catman_ext=0
+else
+ ac_cv_sys_catman_ext=number
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_sys_catman_ext" 1>&6
+if test "$ac_cv_sys_catman_ext" = number; then
+ CATMANEXT='$$ext'
+else
+ CATMANEXT=0
+fi
+
+
+
+
+
+# Check whether --with-readline or --without-readline was given.
+if test "${with_readline+set}" = set; then
+ withval="$with_readline"
+ :
+fi
+
+# Check whether --with-readline-lib or --without-readline-lib was given.
+if test "${with_readline_lib+set}" = set; then
+ withval="$with_readline_lib"
+ if test "$withval" = "yes" -o "$withval" = "no"; then
+ { echo "configure: error: No argument for --with-readline-lib" 1>&2; exit 1; }
+elif test "X$with_readline" = "X"; then
+ with_readline=yes
+fi
+fi
+
+# Check whether --with-readline-include or --without-readline-include was given.
+if test "${with_readline_include+set}" = set; then
+ withval="$with_readline_include"
+ if test "$withval" = "yes" -o "$withval" = "no"; then
+ { echo "configure: error: No argument for --with-readline-include" 1>&2; exit 1; }
+elif test "X$with_readline" = "X"; then
+ with_readline=yes
+fi
+fi
+
+
+echo $ac_n "checking for readline""... $ac_c" 1>&6
+echo "configure:3149: checking for readline" >&5
+
+case "$with_readline" in
+yes) ;;
+no) ;;
+"") ;;
+*) if test "$with_readline_include" = ""; then
+ with_readline_include="$with_readline/include"
+ fi
+ if test "$with_readline_lib" = ""; then
+ with_readline_lib="$with_readline/lib$abilibdirext"
+ fi
+ ;;
+esac
+header_dirs=
+lib_dirs=
+d=''
+for i in $d; do
+ header_dirs="$header_dirs $i/include"
+ lib_dirs="$lib_dirs $i/lib$abilibdirext"
+done
+
+case "$with_readline_include" in
+yes) ;;
+no) ;;
+*) header_dirs="$with_readline_include $header_dirs";;
+esac
+case "$with_readline_lib" in
+yes) ;;
+no) ;;
+*) lib_dirs="$with_readline_lib $lib_dirs";;
+esac
+
+save_CFLAGS="$CFLAGS"
+save_LIBS="$LIBS"
+ires= lres=
+for i in $header_dirs; do
+ CFLAGS="-I$i $save_CFLAGS"
+ cat > conftest.$ac_ext <<EOF
+#line 3188 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+ #include <readline.h>
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3196: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ires=$i;break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+for i in $lib_dirs; do
+ LIBS="-L$i -lreadline $save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 3208 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+ #include <readline.h>
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3216: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lres=$i;break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+CFLAGS="$save_CFLAGS"
+LIBS="$save_LIBS"
+
+if test "$ires" -a "$lres" -a "$with_readline" != "no"; then
+ readline_includedir="$ires"
+ readline_libdir="$lres"
+ INCLUDE_readline="-I$readline_includedir"
+ LIB_readline="-L$readline_libdir -lreadline"
+ cat >> confdefs.h <<EOF
+#define `echo readline | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` 1
+EOF
+
+ with_readline=yes
+ echo "$ac_t""headers $ires, libraries $lres" 1>&6
+else
+ INCLUDE_readline=
+ LIB_readline=
+ with_readline=no
+ echo "$ac_t""$with_readline" 1>&6
+fi
+
+
+
+
+
+# Check whether --with-hesiod or --without-hesiod was given.
+if test "${with_hesiod+set}" = set; then
+ withval="$with_hesiod"
+ :
+fi
+
+# Check whether --with-hesiod-lib or --without-hesiod-lib was given.
+if test "${with_hesiod_lib+set}" = set; then
+ withval="$with_hesiod_lib"
+ if test "$withval" = "yes" -o "$withval" = "no"; then
+ { echo "configure: error: No argument for --with-hesiod-lib" 1>&2; exit 1; }
+elif test "X$with_hesiod" = "X"; then
+ with_hesiod=yes
+fi
+fi
+
+# Check whether --with-hesiod-include or --without-hesiod-include was given.
+if test "${with_hesiod_include+set}" = set; then
+ withval="$with_hesiod_include"
+ if test "$withval" = "yes" -o "$withval" = "no"; then
+ { echo "configure: error: No argument for --with-hesiod-include" 1>&2; exit 1; }
+elif test "X$with_hesiod" = "X"; then
+ with_hesiod=yes
+fi
+fi
+
+
+echo $ac_n "checking for hesiod""... $ac_c" 1>&6
+echo "configure:3278: checking for hesiod" >&5
+
+case "$with_hesiod" in
+yes) ;;
+no) ;;
+"") ;;
+*) if test "$with_hesiod_include" = ""; then
+ with_hesiod_include="$with_hesiod/include"
+ fi
+ if test "$with_hesiod_lib" = ""; then
+ with_hesiod_lib="$with_hesiod/lib$abilibdirext"
+ fi
+ ;;
+esac
+header_dirs=
+lib_dirs=
+d=''
+for i in $d; do
+ header_dirs="$header_dirs $i/include"
+ lib_dirs="$lib_dirs $i/lib$abilibdirext"
+done
+
+case "$with_hesiod_include" in
+yes) ;;
+no) ;;
+*) header_dirs="$with_hesiod_include $header_dirs";;
+esac
+case "$with_hesiod_lib" in
+yes) ;;
+no) ;;
+*) lib_dirs="$with_hesiod_lib $lib_dirs";;
+esac
+
+save_CFLAGS="$CFLAGS"
+save_LIBS="$LIBS"
+ires= lres=
+for i in $header_dirs; do
+ CFLAGS="-I$i $save_CFLAGS"
+ cat > conftest.$ac_ext <<EOF
+#line 3317 "configure"
+#include "confdefs.h"
+#include <hesiod.h>
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3324: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ires=$i;break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+for i in $lib_dirs; do
+ LIBS="-L$i -lhesiod $save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 3336 "configure"
+#include "confdefs.h"
+#include <hesiod.h>
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3343: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lres=$i;break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+CFLAGS="$save_CFLAGS"
+LIBS="$save_LIBS"
+
+if test "$ires" -a "$lres" -a "$with_hesiod" != "no"; then
+ hesiod_includedir="$ires"
+ hesiod_libdir="$lres"
+ INCLUDE_hesiod="-I$hesiod_includedir"
+ LIB_hesiod="-L$hesiod_libdir -lhesiod"
+ cat >> confdefs.h <<EOF
+#define `echo hesiod | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` 1
+EOF
+
+ with_hesiod=yes
+ echo "$ac_t""headers $ires, libraries $lres" 1>&6
+else
+ INCLUDE_hesiod=
+ LIB_hesiod=
+ with_hesiod=no
+ echo "$ac_t""$with_hesiod" 1>&6
+fi
+
+
+
+
+
+# Check whether --enable-bigendian or --disable-bigendian was given.
+if test "${enable_bigendian+set}" = set; then
+ enableval="$enable_bigendian"
+ krb_cv_c_bigendian=yes
+fi
+
+# Check whether --enable-littleendian or --disable-littleendian was given.
+if test "${enable_littleendian+set}" = set; then
+ enableval="$enable_littleendian"
+ krb_cv_c_bigendian=no
+fi
+
+echo $ac_n "checking whether byte order is known at compile time""... $ac_c" 1>&6
+echo "configure:3390: checking whether byte order is known at compile time" >&5
+if eval "test \"`echo '$''{'krb_cv_c_bigendian_compile'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3395 "configure"
+#include "confdefs.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3407: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ krb_cv_c_bigendian_compile=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ krb_cv_c_bigendian_compile=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$krb_cv_c_bigendian_compile" 1>&6
+if test "$krb_cv_c_bigendian_compile" = "no"; then
+ echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:3422: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'krb_cv_c_bigendian'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ if test "$krb_cv_c_bigendian" = ""; then
+ krb_cv_c_bigendian=unknown
+ fi
+ cat > conftest.$ac_ext <<EOF
+#line 3431 "configure"
+#include "confdefs.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3443: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ krb_cv_c_bigendian=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ krb_cv_c_bigendian=no
+fi
+rm -f conftest*
+ if test "$krb_cv_c_bigendian" = "unknown"; then
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: specify either --enable-bigendian or --enable-littleendian" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3458 "configure"
+#include "confdefs.h"
+main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+ }
+EOF
+if { (eval echo configure:3471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ krb_cv_c_bigendian=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ krb_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+ fi
+
+fi
+
+echo "$ac_t""$krb_cv_c_bigendian" 1>&6
+ if test "$krb_cv_c_bigendian" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+ fi
+fi
+if test "$krb_cv_c_bigendian_compile" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENDIANESS_IN_SYS_PARAM_H 1
+EOF
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:3501: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 3508 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:3515: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+echo "configure:3546: checking for X" >&5
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+ withval="$with_x"
+ :
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+ # The user explicitly disabled X.
+ have_x=disabled
+else
+ if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+ # Both variables are already set.
+ have_x=yes
+ else
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=NO ac_x_libraries=NO
+rm -fr conftestdir
+if mkdir conftestdir; then
+ cd conftestdir
+ # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+ cat > Imakefile <<'EOF'
+acfindx:
+ @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+ if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+ # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+ eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+ # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+ for ac_extension in a so sl; do
+ if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+ test -f $ac_im_libdir/libX11.$ac_extension; then
+ ac_im_usrlibdir=$ac_im_libdir; break
+ fi
+ done
+ # Screen out bogus values from the imake configuration. They are
+ # bogus both because they are the default anyway, and because
+ # using them would break gcc on systems where it needs fixed includes.
+ case "$ac_im_incroot" in
+ /usr/include) ;;
+ *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+ esac
+ case "$ac_im_usrlibdir" in
+ /usr/lib | /lib) ;;
+ *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+ esac
+ fi
+ cd ..
+ rm -fr conftestdir
+fi
+
+if test "$ac_x_includes" = NO; then
+ # Guess where to find include files, by looking for this one X11 .h file.
+ test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+ # First, try using that file with no special directory specified.
+cat > conftest.$ac_ext <<EOF
+#line 3608 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3613: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ for ac_dir in \
+ /usr/X11/include \
+ /usr/X11R6/include \
+ /usr/X11R5/include \
+ /usr/X11R4/include \
+ \
+ /usr/include/X11 \
+ /usr/include/X11R6 \
+ /usr/include/X11R5 \
+ /usr/include/X11R4 \
+ \
+ /usr/local/X11/include \
+ /usr/local/X11R6/include \
+ /usr/local/X11R5/include \
+ /usr/local/X11R4/include \
+ \
+ /usr/local/include/X11 \
+ /usr/local/include/X11R6 \
+ /usr/local/include/X11R5 \
+ /usr/local/include/X11R4 \
+ \
+ /usr/X386/include \
+ /usr/x386/include \
+ /usr/XFree86/include/X11 \
+ \
+ /usr/include \
+ /usr/local/include \
+ /usr/unsupported/include \
+ /usr/athena/include \
+ /usr/local/x11r5/include \
+ /usr/lpp/Xamples/include \
+ \
+ /usr/openwin/include \
+ /usr/openwin/share/include \
+ ; \
+ do
+ if test -r "$ac_dir/$x_direct_test_include"; then
+ ac_x_includes=$ac_dir
+ break
+ fi
+ done
+fi
+rm -f conftest*
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+ # Check for the libraries.
+
+ test -z "$x_direct_test_library" && x_direct_test_library=Xt
+ test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+ # See if we find them without any special options.
+ # Don't add to $LIBS permanently.
+ ac_save_LIBS="$LIBS"
+ LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3682 "configure"
+#include "confdefs.h"
+
+int main() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if { (eval echo configure:3689: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+ /usr/X11/lib \
+ /usr/X11R6/lib \
+ /usr/X11R5/lib \
+ /usr/X11R4/lib \
+ \
+ /usr/lib/X11 \
+ /usr/lib/X11R6 \
+ /usr/lib/X11R5 \
+ /usr/lib/X11R4 \
+ \
+ /usr/local/X11/lib \
+ /usr/local/X11R6/lib \
+ /usr/local/X11R5/lib \
+ /usr/local/X11R4/lib \
+ \
+ /usr/local/lib/X11 \
+ /usr/local/lib/X11R6 \
+ /usr/local/lib/X11R5 \
+ /usr/local/lib/X11R4 \
+ \
+ /usr/X386/lib \
+ /usr/x386/lib \
+ /usr/XFree86/lib/X11 \
+ \
+ /usr/lib \
+ /usr/local/lib \
+ /usr/unsupported/lib \
+ /usr/athena/lib \
+ /usr/local/x11r5/lib \
+ /usr/lpp/Xamples/lib \
+ /lib/usr/lib/X11 \
+ \
+ /usr/openwin/lib \
+ /usr/openwin/share/lib \
+ ; \
+do
+ for ac_extension in a so sl; do
+ if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+ ac_x_libraries=$ac_dir
+ break 2
+ fi
+ done
+done
+fi
+rm -f conftest*
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+ # Didn't find X anywhere. Cache the known absence of X.
+ ac_cv_have_x="have_x=no"
+else
+ # Record where we found X for the cache.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+ fi
+ eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+ echo "$ac_t""$have_x" 1>&6
+ no_x=yes
+else
+ # If each of the values was on the command line, it overrides each guess.
+ test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+ test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+ # Update the cache value to reflect the command line values.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+ echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+
+if test "$no_x" = yes; then
+ # Not all programs may use this symbol, but it does not hurt to define it.
+ cat >> confdefs.h <<\EOF
+#define X_DISPLAY_MISSING 1
+EOF
+
+ X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+ if test -n "$x_includes"; then
+ X_CFLAGS="$X_CFLAGS -I$x_includes"
+ fi
+
+ # It would also be nice to do this for all -L options, not just this one.
+ if test -n "$x_libraries"; then
+ X_LIBS="$X_LIBS -L$x_libraries"
+ # For Solaris; some versions of Sun CC require a space after -R and
+ # others require no space. Words are not sufficient . . . .
+ case "`(uname -sr) 2>/dev/null`" in
+ "SunOS 5"*)
+ echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6
+echo "configure:3796: checking whether -R must be followed by a space" >&5
+ ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
+ cat > conftest.$ac_ext <<EOF
+#line 3799 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3806: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_R_nospace=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_R_nospace=no
+fi
+rm -f conftest*
+ if test $ac_R_nospace = yes; then
+ echo "$ac_t""no" 1>&6
+ X_LIBS="$X_LIBS -R$x_libraries"
+ else
+ LIBS="$ac_xsave_LIBS -R $x_libraries"
+ cat > conftest.$ac_ext <<EOF
+#line 3822 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3829: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_R_space=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_R_space=no
+fi
+rm -f conftest*
+ if test $ac_R_space = yes; then
+ echo "$ac_t""yes" 1>&6
+ X_LIBS="$X_LIBS -R $x_libraries"
+ else
+ echo "$ac_t""neither works" 1>&6
+ fi
+ fi
+ LIBS="$ac_xsave_LIBS"
+ esac
+ fi
+
+ # Check for system-dependent libraries X programs must link with.
+ # Do this before checking for the system-independent R6 libraries
+ # (-lICE), since we may need -lsocket or whatever for X linking.
+
+ if test "$ISC" = yes; then
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+ else
+ # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X
+ # libraries were built with DECnet support. And karl@cs.umb.edu says
+ # the Alpha needs dnet_stub (dnet does not exist).
+ echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6
+echo "configure:3861: checking for dnet_ntoa in -ldnet" >&5
+ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldnet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3869 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:3880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+ echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6
+echo "configure:3902: checking for dnet_ntoa in -ldnet_stub" >&5
+ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldnet_stub $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3910 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:3921: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+ # to get the SysV transport functions.
+ # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4)
+ # needs -lnsl.
+ # The nsl library prevents programs from opening the X display
+ # on Irix 5.2, according to dickey@clark.net.
+ echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
+echo "configure:3950: checking for gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3955 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char gethostbyname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+gethostbyname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3978: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_gethostbyname = no; then
+ echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
+echo "configure:3999: checking for gethostbyname in -lnsl" >&5
+ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lnsl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4007 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:4018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # lieder@skyler.mavd.honeywell.com says without -lsocket,
+ # socket/setsockopt and other routines are undefined under SCO ODT
+ # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary
+ # on later versions), says simon@lia.di.epfl.ch: it contains
+ # gethostby* variants that don't use the nameserver (or something).
+ # -lsocket must be given before -lnsl if both are needed.
+ # We assume that if connect needs -lnsl, so does gethostbyname.
+ echo $ac_n "checking for connect""... $ac_c" 1>&6
+echo "configure:4048: checking for connect" >&5
+if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4053 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char connect(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char connect();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+connect();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_connect=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_connect=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_connect = no; then
+ echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
+echo "configure:4097: checking for connect in -lsocket" >&5
+ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4105 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char connect();
+
+int main() {
+connect()
+; return 0; }
+EOF
+if { (eval echo configure:4116: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
+ echo $ac_n "checking for remove""... $ac_c" 1>&6
+echo "configure:4140: checking for remove" >&5
+if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4145 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char remove(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char remove();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_remove) || defined (__stub___remove)
+choke me
+#else
+remove();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4168: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_remove=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_remove=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_remove = no; then
+ echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
+echo "configure:4189: checking for remove in -lposix" >&5
+ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lposix $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4197 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char remove();
+
+int main() {
+remove()
+; return 0; }
+EOF
+if { (eval echo configure:4208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+ echo $ac_n "checking for shmat""... $ac_c" 1>&6
+echo "configure:4232: checking for shmat" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4237 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shmat(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shmat();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shmat) || defined (__stub___shmat)
+choke me
+#else
+shmat();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4260: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_shmat=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shmat=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_shmat = no; then
+ echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
+echo "configure:4281: checking for shmat in -lipc" >&5
+ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lipc $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4289 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shmat();
+
+int main() {
+shmat()
+; return 0; }
+EOF
+if { (eval echo configure:4300: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ fi
+
+ # Check for libraries that X11R6 Xt/Xaw programs need.
+ ac_save_LDFLAGS="$LDFLAGS"
+ test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+ # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+ # check for ICE first), but we must link in the order -lSM -lICE or
+ # we get undefined symbols. So assume we have SM if we have ICE.
+ # These have to be linked with before -lX11, unlike the other
+ # libraries we check for below, so use a different variable.
+ # --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
+ echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6
+echo "configure:4333: checking for IceConnectionNumber in -lICE" >&5
+ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4341 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char IceConnectionNumber();
+
+int main() {
+IceConnectionNumber()
+; return 0; }
+EOF
+if { (eval echo configure:4352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ LDFLAGS="$ac_save_LDFLAGS"
+
+fi
+
+
+# try to figure out if we need any additional ld flags, like -R
+# and yes, the autoconf X test is utterly broken
+if test "$no_x" != yes; then
+ echo $ac_n "checking for special X linker flags""... $ac_c" 1>&6
+echo "configure:4381: checking for special X linker flags" >&5
+if eval "test \"`echo '$''{'krb_cv_sys_x_libs_rpath'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ ac_save_libs="$LIBS"
+ ac_save_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS $X_CFLAGS"
+ krb_cv_sys_x_libs_rpath=""
+ krb_cv_sys_x_libs=""
+ for rflag in "" "-R" "-R " "-rpath "; do
+ if test "$rflag" = ""; then
+ foo="$X_LIBS"
+ else
+ foo=""
+ for flag in $X_LIBS; do
+ case $flag in
+ -L*)
+ foo="$foo $flag `echo $flag | sed \"s/-L/$rflag/\"`"
+ ;;
+ *)
+ foo="$foo $flag"
+ ;;
+ esac
+ done
+ fi
+ LIBS="$ac_save_libs $foo $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4412 "configure"
+#include "confdefs.h"
+
+ #include <X11/Xlib.h>
+ foo()
+ {
+ XOpenDisplay(NULL);
+ }
+ main()
+ {
+ return 0;
+ }
+
+EOF
+if { (eval echo configure:4426: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ krb_cv_sys_x_libs_rpath="$rflag"; krb_cv_sys_x_libs="$foo"; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ :
+fi
+rm -fr conftest*
+fi
+
+ done
+ LIBS="$ac_save_libs"
+ CFLAGS="$ac_save_cflags"
+
+fi
+
+echo "$ac_t""$krb_cv_sys_x_libs_rpath" 1>&6
+ X_LIBS="$krb_cv_sys_x_libs"
+fi
+
+
+if test "$no_x" = "yes" ; then
+ MAKE_X_PROGS_BIN_PROGS=""
+ MAKE_X_PROGS_BIN_SCRPTS=""
+ MAKE_X_PROGS_LIBEXEC_PROGS=""
+else
+ MAKE_X_PROGS_BIN_PROGS='$(X_PROGS_BIN_PROGS)'
+ MAKE_X_PROGS_BIN_SCRPTS='$(X_PROGS_BIN_SCRPTS)'
+ MAKE_X_PROGS_LIBEXEC_PROGS='$(X_PROGS_LIBEXEC_PROGS)'
+fi
+
+
+save_CFLAGS="$CFLAGS"
+CFLAGS="$X_CFLAGS $CFLAGS"
+save_LIBS="$LIBS"
+LIBS="$X_PRE_LIBS $X_EXTRA_LIBS $LIBS"
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $X_LIBS"
+
+
+
+
+
+echo $ac_n "checking for XauWriteAuth""... $ac_c" 1>&6
+echo "configure:4472: checking for XauWriteAuth" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_XauWriteAuth'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_XauWriteAuth\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" X11 Xau; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 4487 "configure"
+#include "confdefs.h"
+
+int main() {
+XauWriteAuth()
+; return 0; }
+EOF
+if { (eval echo configure:4494: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_XauWriteAuth=$ac_lib; else ac_cv_funclib_XauWriteAuth=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_XauWriteAuth=\${ac_cv_funclib_XauWriteAuth-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_XauWriteAuth"
+
+: << END
+@@@funcs="$funcs XauWriteAuth"@@@
+@@@libs="$libs "" X11 Xau"@@@
+END
+
+# XauWriteAuth
+eval "ac_tr_func=HAVE_`echo XauWriteAuth | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_XauWriteAuth=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_XauWriteAuth=yes"
+ eval "LIB_XauWriteAuth="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_XauWriteAuth=no"
+ eval "LIB_XauWriteAuth="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_XauWriteAuth=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+ac_xxx="$LIBS"
+LIBS="$LIB_XauWriteAuth $LIBS"
+
+
+
+echo $ac_n "checking for XauReadAuth""... $ac_c" 1>&6
+echo "configure:4559: checking for XauReadAuth" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_XauReadAuth'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_XauReadAuth\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" X11 Xau; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 4574 "configure"
+#include "confdefs.h"
+
+int main() {
+XauReadAuth()
+; return 0; }
+EOF
+if { (eval echo configure:4581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_XauReadAuth=$ac_lib; else ac_cv_funclib_XauReadAuth=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_XauReadAuth=\${ac_cv_funclib_XauReadAuth-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_XauReadAuth"
+
+: << END
+@@@funcs="$funcs XauReadAuth"@@@
+@@@libs="$libs "" X11 Xau"@@@
+END
+
+# XauReadAuth
+eval "ac_tr_func=HAVE_`echo XauReadAuth | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_XauReadAuth=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_XauReadAuth=yes"
+ eval "LIB_XauReadAuth="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_XauReadAuth=no"
+ eval "LIB_XauReadAuth="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_XauReadAuth=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+LIBS="$LIB_XauReadAauth $LIBS"
+
+
+
+echo $ac_n "checking for XauFileName""... $ac_c" 1>&6
+echo "configure:4645: checking for XauFileName" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_XauFileName'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_XauFileName\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" X11 Xau; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 4660 "configure"
+#include "confdefs.h"
+
+int main() {
+XauFileName()
+; return 0; }
+EOF
+if { (eval echo configure:4667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_XauFileName=$ac_lib; else ac_cv_funclib_XauFileName=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_XauFileName=\${ac_cv_funclib_XauFileName-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_XauFileName"
+
+: << END
+@@@funcs="$funcs XauFileName"@@@
+@@@libs="$libs "" X11 Xau"@@@
+END
+
+# XauFileName
+eval "ac_tr_func=HAVE_`echo XauFileName | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_XauFileName=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_XauFileName=yes"
+ eval "LIB_XauFileName="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_XauFileName=no"
+ eval "LIB_XauFileName="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_XauFileName=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+LIBS="$ac_xxx"
+
+case "$ac_cv_funclib_XauWriteAuth" in
+yes) ;;
+no) ;;
+*) if test "$ac_cv_funclib_XauReadAuth" = yes; then
+ if test "$ac_cv_funclib_XauFileName" = yes; then
+ LIB_XauReadAuth="$LIB_XauWriteAuth"
+ else
+ LIB_XauReadAuth="$LIB_XauWriteAuth $LIB_XauFileName"
+ fi
+ else
+ if test "$ac_cv_funclib_XauFileName" = yes; then
+ LIB_XauReadAuth="$LIB_XauReadAuth $LIB_XauWriteAuth"
+ else
+ LIB_XauReadAuth="$LIB_XauReadAuth $LIB_XauWriteAuth $LIB_XauFileName"
+ fi
+ fi
+ ;;
+esac
+
+if test "$AUTOMAKE" != ""; then
+
+
+if test "$ac_cv_func_XauWriteAuth" != "yes"; then
+ NEED_WRITEAUTH_TRUE=
+ NEED_WRITEAUTH_FALSE='#'
+else
+ NEED_WRITEAUTH_TRUE='#'
+ NEED_WRITEAUTH_FALSE=
+fi
+else
+
+
+ if test "$ac_cv_func_XauWriteAuth" != "yes"; then
+ NEED_WRITEAUTH_TRUE=
+ NEED_WRITEAUTH_FALSE='#'
+ else
+ NEED_WRITEAUTH_TRUE='#'
+ NEED_WRITEAUTH_FALSE=
+ fi
+fi
+CFLAGS=$save_CFLAGS
+LIBS=$save_LIBS
+LDFLAGS=$save_LDFLAGS
+
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:4775: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4780 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:4829: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:4850: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4855 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4863: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 4880 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 4898 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4919 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:4930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:4954: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4959 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:4987: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4992 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
+echo "configure:5020: checking for ssize_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5025 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <unistd.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "ssize_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_ssize_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_ssize_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_ssize_t" 1>&6
+if test $ac_cv_type_ssize_t = no; then
+ cat >> confdefs.h <<\EOF
+#define ssize_t int
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:5054: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5059 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:5087: checking for uid_t in sys/types.h" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5092 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "uid_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_uid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+if test $ac_cv_type_uid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for mode_t""... $ac_c" 1>&6
+echo "configure:5121: checking for mode_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5126 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_mode_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_mode_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_mode_t" 1>&6
+if test $ac_cv_type_mode_t = no; then
+ cat >> confdefs.h <<\EOF
+#define mode_t unsigned short
+EOF
+
+fi
+
+echo $ac_n "checking for sig_atomic_t""... $ac_c" 1>&6
+echo "configure:5155: checking for sig_atomic_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_sig_atomic_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5160 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <signal.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "sig_atomic_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_sig_atomic_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_sig_atomic_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_sig_atomic_t" 1>&6
+if test $ac_cv_type_sig_atomic_t = no; then
+ cat >> confdefs.h <<\EOF
+#define sig_atomic_t int
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:5189: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5194 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:5203: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:5224: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5229 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:5237: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tm=time.h
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+ cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:5259: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5264 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5272: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 5289 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 5307 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5328 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:5339: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+
+if test "$berkeley_db"; then
+ for ac_hdr in \
+ db.h \
+ db_185.h \
+
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:5371: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5376 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5381: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+for ac_hdr in \
+ arpa/ftp.h \
+ arpa/inet.h \
+ arpa/nameser.h \
+ arpa/telnet.h \
+ bind/bitypes.h \
+ bsdsetjmp.h \
+ crypt.h \
+ curses.h \
+ dbm.h \
+ dirent.h \
+ dlfcn.h \
+ err.h \
+ errno.h \
+ fcntl.h \
+ fnmatch.h \
+ grp.h \
+ inttypes.h \
+ io.h \
+ limits.h \
+ maillock.h \
+ ndbm.h \
+ net/if.h \
+ netdb.h \
+ netinet/in.h \
+ netinet/in6.h \
+ netinet/in6_machtypes.h \
+ netinet/in6_var.h \
+ netinet/in_systm.h \
+ netinet6/in6.h \
+ netinfo/ni.h \
+ paths.h \
+ pthread.h \
+ pty.h \
+ pwd.h \
+ resolv.h \
+ rpcsvc/dbm.h \
+ sac.h \
+ security/pam_modules.h \
+ sgtty.h \
+ shadow.h \
+ siad.h \
+ signal.h \
+ stropts.h \
+ sys/bitypes.h \
+ sys/category.h \
+ sys/file.h \
+ sys/filio.h \
+ sys/ioccom.h \
+ sys/ioctl.h \
+ sys/param.h \
+ sys/proc.h \
+ sys/pty.h \
+ sys/ptyio.h \
+ sys/ptyvar.h \
+ sys/resource.h \
+ sys/select.h \
+ sys/socket.h \
+ sys/sockio.h \
+ sys/stat.h \
+ sys/str_tty.h \
+ sys/stream.h \
+ sys/stropts.h \
+ sys/strtty.h \
+ sys/syscall.h \
+ sys/sysctl.h \
+ sys/termio.h \
+ sys/time.h \
+ sys/timeb.h \
+ sys/times.h \
+ sys/tty.h \
+ sys/types.h \
+ sys/uio.h \
+ sys/un.h \
+ sys/utsname.h \
+ sys/wait.h \
+ syslog.h \
+ term.h \
+ termio.h \
+ termios.h \
+ time.h \
+ tmpdir.h \
+ udb.h \
+ unistd.h \
+ util.h \
+ utmp.h \
+ utmpx.h \
+
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:5500: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5505 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5510: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+for ac_hdr in standards.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:5542: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5547 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5552: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for i in netinet/ip.h netinet/tcp.h; do
+
+cv=`echo "$i" | sed 'y%./+-%__p_%'`
+
+echo $ac_n "checking for $i""... $ac_c" 1>&6
+echo "configure:5583: checking for $i" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$cv'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5588 "configure"
+#include "confdefs.h"
+\
+#ifdef HAVE_STANDARDS_H
+#include <standards.h>
+#endif
+#include <$i>
+
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5598: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$cv=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$cv=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""`eval echo \\$ac_cv_header_$cv`" 1>&6
+if test `eval echo \\$ac_cv_header_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo $i | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+fi
+done
+: << END
+@@@headers="$headers netinet/ip.h netinet/tcp.h"@@@
+END
+
+
+
+
+# Check whether --enable-netinfo or --disable-netinfo was given.
+if test "${enable_netinfo+set}" = set; then
+ enableval="$enable_netinfo"
+ :
+fi
+
+
+if test "$ac_cv_header_netinfo_ni_h" = yes -a "$enable_netinfo" = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_NETINFO 1
+EOF
+
+fi
+
+
+
+if test "$ac_cv_header_err_h" = yes; then
+ have_err_h_TRUE=
+ have_err_h_FALSE='#'
+else
+ have_err_h_TRUE='#'
+ have_err_h_FALSE=
+fi
+
+
+if test "$ac_cv_header_fnmatch_h" = yes; then
+ have_fnmatch_h_TRUE=
+ have_fnmatch_h_FALSE='#'
+else
+ have_fnmatch_h_TRUE='#'
+ have_fnmatch_h_FALSE=
+fi
+
+
+# Check whether --with-ipv6 or --without-ipv6 was given.
+if test "${with_ipv6+set}" = set; then
+ withval="$with_ipv6"
+
+if test "$withval" = "no"; then
+ ac_cv_lib_ipv6=no
+fi
+fi
+
+if eval "test \"`echo '$''{'ac_cv_lib_ipv6'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ v6type=unknown
+v6lib=none
+
+echo $ac_n "checking ipv6 stack type""... $ac_c" 1>&6
+echo "configure:5679: checking ipv6 stack type" >&5
+for i in v6d toshiba kame inria zeta linux; do
+ case $i in
+ v6d)
+ cat > conftest.$ac_ext <<EOF
+#line 5684 "configure"
+#include "confdefs.h"
+dnl
+#include </usr/local/v6/include/sys/types.h>
+#ifdef __V6D__
+yes
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ v6type=$i; v6lib=v6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-I/usr/local/v6/include $CFLAGS"
+fi
+rm -f conftest*
+
+ ;;
+ toshiba)
+ cat > conftest.$ac_ext <<EOF
+#line 5704 "configure"
+#include "confdefs.h"
+dnl
+#include <sys/param.h>
+#ifdef _TOSHIBA_INET6
+yes
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"
+fi
+rm -f conftest*
+
+ ;;
+ kame)
+ cat > conftest.$ac_ext <<EOF
+#line 5724 "configure"
+#include "confdefs.h"
+dnl
+#include <netinet/in.h>
+#ifdef __KAME__
+yes
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"
+fi
+rm -f conftest*
+
+ ;;
+ inria)
+ cat > conftest.$ac_ext <<EOF
+#line 5744 "configure"
+#include "confdefs.h"
+dnl
+#include <netinet/in.h>
+#ifdef IPV6_INRIA_VERSION
+yes
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ v6type=$i; CFLAGS="-DINET6 $CFLAGS"
+fi
+rm -f conftest*
+
+ ;;
+ zeta)
+ cat > conftest.$ac_ext <<EOF
+#line 5762 "configure"
+#include "confdefs.h"
+dnl
+#include <sys/param.h>
+#ifdef _ZETA_MINAMI_INET6
+yes
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"
+fi
+rm -f conftest*
+
+ ;;
+ linux)
+ if test -d /usr/inet6; then
+ v6type=$i
+ v6lib=inet6
+ v6libdir=/usr/inet6
+ CFLAGS="-DINET6 $CFLAGS"
+ fi
+ ;;
+ esac
+ if test "$v6type" != "unknown"; then
+ break
+ fi
+done
+echo "$ac_t""$v6type" 1>&6
+
+if test "$v6lib" != "none"; then
+ for dir in $v6libdir /usr/local/v6/lib /usr/local/lib; do
+ if test -d $dir -a -f $dir/lib$v6lib.a; then
+ LIBS="-L$dir -l$v6lib $LIBS"
+ break
+ fi
+ done
+fi
+cat > conftest.$ac_ext <<EOF
+#line 5804 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+
+int main() {
+
+ struct sockaddr_in6 sin6;
+ int s;
+
+ s = socket(AF_INET6, SOCK_DGRAM, 0);
+
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = htons(17);
+ sin6.sin6_addr = in6addr_any;
+ bind(s, (struct sockaddr *)&sin6, sizeof(sin6));
+
+; return 0; }
+EOF
+if { (eval echo configure:5834: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_lib_ipv6=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_lib_ipv6=no
+fi
+rm -f conftest*
+fi
+
+echo $ac_n "checking for IPv6""... $ac_c" 1>&6
+echo "configure:5847: checking for IPv6" >&5
+echo "$ac_t""$ac_cv_lib_ipv6" 1>&6
+if test "$ac_cv_lib_ipv6" = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_IPV6 1
+EOF
+
+fi
+
+
+
+
+
+
+
+echo $ac_n "checking for socket""... $ac_c" 1>&6
+echo "configure:5863: checking for socket" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_socket'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_socket\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" socket; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 5878 "configure"
+#include "confdefs.h"
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:5885: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_socket=$ac_lib; else ac_cv_funclib_socket=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_socket=\${ac_cv_funclib_socket-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_socket"
+
+: << END
+@@@funcs="$funcs socket"@@@
+@@@libs="$libs "" socket"@@@
+END
+
+# socket
+eval "ac_tr_func=HAVE_`echo socket | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_socket=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_socket=yes"
+ eval "LIB_socket="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_socket=no"
+ eval "LIB_socket="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_socket=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test -n "$LIB_socket"; then
+ LIBS="$LIB_socket $LIBS"
+fi
+
+
+
+
+
+echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
+echo "configure:5953: checking for gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_gethostbyname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_gethostbyname\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" nsl; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 5968 "configure"
+#include "confdefs.h"
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:5975: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_gethostbyname=$ac_lib; else ac_cv_funclib_gethostbyname=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_gethostbyname=\${ac_cv_funclib_gethostbyname-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_gethostbyname"
+
+: << END
+@@@funcs="$funcs gethostbyname"@@@
+@@@libs="$libs "" nsl"@@@
+END
+
+# gethostbyname
+eval "ac_tr_func=HAVE_`echo gethostbyname | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_gethostbyname=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_gethostbyname=yes"
+ eval "LIB_gethostbyname="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_gethostbyname=no"
+ eval "LIB_gethostbyname="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_gethostbyname=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test -n "$LIB_gethostbyname"; then
+ LIBS="$LIB_gethostbyname $LIBS"
+fi
+
+
+
+
+
+echo $ac_n "checking for syslog""... $ac_c" 1>&6
+echo "configure:6043: checking for syslog" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_syslog'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_syslog\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" syslog; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 6058 "configure"
+#include "confdefs.h"
+
+int main() {
+syslog()
+; return 0; }
+EOF
+if { (eval echo configure:6065: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_syslog=$ac_lib; else ac_cv_funclib_syslog=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_syslog=\${ac_cv_funclib_syslog-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_syslog"
+
+: << END
+@@@funcs="$funcs syslog"@@@
+@@@libs="$libs "" syslog"@@@
+END
+
+# syslog
+eval "ac_tr_func=HAVE_`echo syslog | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_syslog=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_syslog=yes"
+ eval "LIB_syslog="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_syslog=no"
+ eval "LIB_syslog="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_syslog=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test -n "$LIB_syslog"; then
+ LIBS="$LIB_syslog $LIBS"
+fi
+
+
+
+
+
+echo $ac_n "checking for logwtmp""... $ac_c" 1>&6
+echo "configure:6133: checking for logwtmp" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_logwtmp'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_logwtmp\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" util; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 6148 "configure"
+#include "confdefs.h"
+
+int main() {
+logwtmp()
+; return 0; }
+EOF
+if { (eval echo configure:6155: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_logwtmp=$ac_lib; else ac_cv_funclib_logwtmp=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_logwtmp=\${ac_cv_funclib_logwtmp-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_logwtmp"
+
+: << END
+@@@funcs="$funcs logwtmp"@@@
+@@@libs="$libs "" util"@@@
+END
+
+# logwtmp
+eval "ac_tr_func=HAVE_`echo logwtmp | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_logwtmp=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_logwtmp=yes"
+ eval "LIB_logwtmp="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_logwtmp=no"
+ eval "LIB_logwtmp="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_logwtmp=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+
+
+
+echo $ac_n "checking for tgetent""... $ac_c" 1>&6
+echo "configure:6218: checking for tgetent" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_tgetent'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_tgetent\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" termcap ncurses curses; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 6233 "configure"
+#include "confdefs.h"
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:6240: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_tgetent=$ac_lib; else ac_cv_funclib_tgetent=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_tgetent=\${ac_cv_funclib_tgetent-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_tgetent"
+
+: << END
+@@@funcs="$funcs tgetent"@@@
+@@@libs="$libs "" termcap ncurses curses"@@@
+END
+
+# tgetent
+eval "ac_tr_func=HAVE_`echo tgetent | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_tgetent=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_tgetent=yes"
+ eval "LIB_tgetent="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_tgetent=no"
+ eval "LIB_tgetent="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_tgetent=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+
+
+
+
+echo $ac_n "checking for gethostbyname2""... $ac_c" 1>&6
+echo "configure:6304: checking for gethostbyname2" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_gethostbyname2'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_gethostbyname2\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" inet6 ip6; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 6319 "configure"
+#include "confdefs.h"
+
+int main() {
+gethostbyname2()
+; return 0; }
+EOF
+if { (eval echo configure:6326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_gethostbyname2=$ac_lib; else ac_cv_funclib_gethostbyname2=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_gethostbyname2=\${ac_cv_funclib_gethostbyname2-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_gethostbyname2"
+
+: << END
+@@@funcs="$funcs gethostbyname2"@@@
+@@@libs="$libs "" inet6 ip6"@@@
+END
+
+# gethostbyname2
+eval "ac_tr_func=HAVE_`echo gethostbyname2 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_gethostbyname2=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_gethostbyname2=yes"
+ eval "LIB_gethostbyname2="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_gethostbyname2=no"
+ eval "LIB_gethostbyname2="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_gethostbyname2=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test -n "$LIB_gethostbyname2"; then
+ LIBS="$LIB_gethostbyname2 $LIBS"
+fi
+
+
+
+
+
+
+echo $ac_n "checking for res_search""... $ac_c" 1>&6
+echo "configure:6395: checking for res_search" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_res_search'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_res_search\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" resolv; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 6410 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+
+int main() {
+res_search(0,0,0,0,0)
+; return 0; }
+EOF
+if { (eval echo configure:6431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_res_search=$ac_lib; else ac_cv_funclib_res_search=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_res_search=\${ac_cv_funclib_res_search-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_res_search"
+
+: << END
+@@@funcs="$funcs res_search"@@@
+@@@libs="$libs "" resolv"@@@
+END
+
+# res_search
+eval "ac_tr_func=HAVE_`echo res_search | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_res_search=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_res_search=yes"
+ eval "LIB_res_search="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_res_search=no"
+ eval "LIB_res_search="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_res_search=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test -n "$LIB_res_search"; then
+ LIBS="$LIB_res_search $LIBS"
+fi
+
+
+
+
+
+
+echo $ac_n "checking for dn_expand""... $ac_c" 1>&6
+echo "configure:6500: checking for dn_expand" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_dn_expand'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_dn_expand\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" resolv; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 6515 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+
+int main() {
+dn_expand(0,0,0,0,0)
+; return 0; }
+EOF
+if { (eval echo configure:6536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_dn_expand=$ac_lib; else ac_cv_funclib_dn_expand=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_dn_expand=\${ac_cv_funclib_dn_expand-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_dn_expand"
+
+: << END
+@@@funcs="$funcs dn_expand"@@@
+@@@libs="$libs "" resolv"@@@
+END
+
+# dn_expand
+eval "ac_tr_func=HAVE_`echo dn_expand | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_dn_expand=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_dn_expand=yes"
+ eval "LIB_dn_expand="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_dn_expand=no"
+ eval "LIB_dn_expand="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_dn_expand=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test -n "$LIB_dn_expand"; then
+ LIBS="$LIB_dn_expand $LIBS"
+fi
+
+
+
+
+echo $ac_n "checking for working snprintf""... $ac_c" 1>&6
+echo "configure:6603: checking for working snprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_snprintf_working'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_func_snprintf_working=yes
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6612 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#include <string.h>
+int main()
+{
+ char foo[3];
+ snprintf(foo, 2, "12");
+ return strcmp(foo, "1");
+}
+EOF
+if { (eval echo configure:6624: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_snprintf_working=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_snprintf_working" 1>&6
+
+if test "$ac_cv_func_snprintf_working" = yes; then
+ cat >> confdefs.h <<EOF
+#define HAVE_SNPRINTF 1
+EOF
+
+fi
+if test "$ac_cv_func_snprintf_working" = yes; then
+
+if test "$ac_cv_func_snprintf+set" != set -o "$ac_cv_func_snprintf" = yes; then
+echo $ac_n "checking if snprintf needs a prototype""... $ac_c" 1>&6
+echo "configure:6650: checking if snprintf needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_snprintf_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6655 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int main() {
+struct foo { int foo; } xx;
+extern int snprintf (struct foo*);
+snprintf(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:6665: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_snprintf_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_snprintf_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_snprintf_noproto" 1>&6
+
+if test "$ac_cv_func_snprintf_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_SNPRINTF_PROTO 1
+EOF
+
+fi
+
+fi
+
+fi
+
+
+echo $ac_n "checking for working vsnprintf""... $ac_c" 1>&6
+echo "configure:6692: checking for working vsnprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vsnprintf_working'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_func_vsnprintf_working=yes
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6701 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+int foo(int num, ...)
+{
+ char bar[3];
+ va_list arg;
+ va_start(arg, num);
+ vsnprintf(bar, 2, "%s", arg);
+ va_end(arg);
+ return strcmp(bar, "1");
+}
+
+
+int main()
+{
+ return foo(0, "12");
+}
+EOF
+if { (eval echo configure:6724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_vsnprintf_working=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_vsnprintf_working" 1>&6
+
+if test "$ac_cv_func_vsnprintf_working" = yes; then
+ cat >> confdefs.h <<EOF
+#define HAVE_VSNPRINTF 1
+EOF
+
+fi
+if test "$ac_cv_func_vsnprintf_working" = yes; then
+
+if test "$ac_cv_func_vsnprintf+set" != set -o "$ac_cv_func_vsnprintf" = yes; then
+echo $ac_n "checking if vsnprintf needs a prototype""... $ac_c" 1>&6
+echo "configure:6750: checking if vsnprintf needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vsnprintf_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6755 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int main() {
+struct foo { int foo; } xx;
+extern int vsnprintf (struct foo*);
+vsnprintf(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:6765: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_vsnprintf_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vsnprintf_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_vsnprintf_noproto" 1>&6
+
+if test "$ac_cv_func_vsnprintf_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_VSNPRINTF_PROTO 1
+EOF
+
+fi
+
+fi
+
+fi
+
+
+
+echo $ac_n "checking for working glob""... $ac_c" 1>&6
+echo "configure:6793: checking for working glob" >&5
+if eval "test \"`echo '$''{'ac_cv_func_glob_working'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_func_glob_working=yes
+cat > conftest.$ac_ext <<EOF
+#line 6799 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#include <glob.h>
+int main() {
+
+glob(NULL, GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE, NULL, NULL);
+
+; return 0; }
+EOF
+if { (eval echo configure:6810: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_glob_working=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_glob_working" 1>&6
+
+if test "$ac_cv_func_glob_working" = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GLOB 1
+EOF
+
+fi
+if test "$ac_cv_func_glob_working" = yes; then
+
+if test "$ac_cv_func_glob+set" != set -o "$ac_cv_func_glob" = yes; then
+echo $ac_n "checking if glob needs a prototype""... $ac_c" 1>&6
+echo "configure:6834: checking if glob needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_glob_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6839 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <glob.h>
+int main() {
+struct foo { int foo; } xx;
+extern int glob (struct foo*);
+glob(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:6850: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_glob_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_glob_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_glob_noproto" 1>&6
+
+if test "$ac_cv_func_glob_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_GLOB_PROTO 1
+EOF
+
+fi
+
+fi
+
+fi
+
+
+if test "$ac_cv_func_glob_working" != yes; then
+ LIBOBJS="$LIBOBJS glob.o"
+fi
+
+
+if test "$ac_cv_func_glob_working" = yes; then
+ have_glob_h_TRUE=
+ have_glob_h_FALSE='#'
+else
+ have_glob_h_TRUE='#'
+ have_glob_h_FALSE=
+fi
+
+
+
+
+
+echo $ac_n "checking for dbopen""... $ac_c" 1>&6
+echo "configure:6894: checking for dbopen" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_dbopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_dbopen\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" $berkeley_db; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 6909 "configure"
+#include "confdefs.h"
+
+int main() {
+dbopen()
+; return 0; }
+EOF
+if { (eval echo configure:6916: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_dbopen=$ac_lib; else ac_cv_funclib_dbopen=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_dbopen=\${ac_cv_funclib_dbopen-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_dbopen"
+
+: << END
+@@@funcs="$funcs dbopen"@@@
+@@@libs="$libs "" $berkeley_db"@@@
+END
+
+# dbopen
+eval "ac_tr_func=HAVE_`echo dbopen | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_dbopen=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_dbopen=yes"
+ eval "LIB_dbopen="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_dbopen=no"
+ eval "LIB_dbopen="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_dbopen=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+
+
+
+echo $ac_n "checking for dbm_firstkey""... $ac_c" 1>&6
+echo "configure:6979: checking for dbm_firstkey" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_dbm_firstkey'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_dbm_firstkey\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" $berkeley_db gdbm ndbm; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 6994 "configure"
+#include "confdefs.h"
+
+int main() {
+dbm_firstkey()
+; return 0; }
+EOF
+if { (eval echo configure:7001: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_dbm_firstkey=$ac_lib; else ac_cv_funclib_dbm_firstkey=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_dbm_firstkey=\${ac_cv_funclib_dbm_firstkey-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_dbm_firstkey"
+
+: << END
+@@@funcs="$funcs dbm_firstkey"@@@
+@@@libs="$libs "" $berkeley_db gdbm ndbm"@@@
+END
+
+# dbm_firstkey
+eval "ac_tr_func=HAVE_`echo dbm_firstkey | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_dbm_firstkey=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_dbm_firstkey=yes"
+ eval "LIB_dbm_firstkey="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_dbm_firstkey=no"
+ eval "LIB_dbm_firstkey="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_dbm_firstkey=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+
+DBLIB="$LIB_dbopen"
+if test "$LIB_dbopen" != "$LIB_dbm_firstkey"; then
+ DBLIB="$DBLIB $LIB_dbm_firstkey"
+fi
+
+for ac_func in _getpty _scrsize asnprintf asprintf cgetent fcntl
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7069: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7074 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getmsg getrlimit getspnam gettimeofday getuid
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7124: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7129 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7152: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in grantpt mktime ptsname rand random setproctitle
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7179: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7184 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7207: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in revoke select setitimer setpcred setpgid
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7234: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7239 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7262: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in setregid setresgid setresuid setreuid setutent
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7289: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7294 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7317: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in setsid sigaction strstr
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7344: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7349 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7372: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in sysconf sysctl timegm ttyname ttyslot umask uname
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7399: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7404 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in unlockpt vasnprintf vasprintf vhangup
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7454: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7459 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in yp_get_default_domain
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7509: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7514 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7537: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+if test "$ac_cv_func_cgetent" = no; then
+ LIBOBJS="$LIBOBJS getcap.o"
+fi
+
+
+for ac_func in getlogin setlogin
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7570: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7575 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7598: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+if test "$ac_cv_func_getlogin" = yes; then
+echo $ac_n "checking if getlogin is posix""... $ac_c" 1>&6
+echo "configure:7624: checking if getlogin is posix" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getlogin_posix'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if test "$ac_cv_func_getlogin" = yes -a "$ac_cv_func_setlogin" = yes; then
+ ac_cv_func_getlogin_posix=no
+else
+ ac_cv_func_getlogin_posix=yes
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_getlogin_posix" 1>&6
+if test "$ac_cv_func_getlogin_posix" = yes; then
+ cat >> confdefs.h <<\EOF
+#define POSIX_GETLOGIN 1
+EOF
+
+fi
+fi
+
+
+
+
+for ac_hdr in capability.h sys/capability.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:7653: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7658 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:7663: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+for ac_func in sgi_getcapabilitybyname cap_set_proc
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7693: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7698 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+
+
+
+echo $ac_n "checking for getpwnam_r""... $ac_c" 1>&6
+echo "configure:7752: checking for getpwnam_r" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_getpwnam_r'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_getpwnam_r\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" c_r; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 7767 "configure"
+#include "confdefs.h"
+
+int main() {
+getpwnam_r()
+; return 0; }
+EOF
+if { (eval echo configure:7774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_getpwnam_r=$ac_lib; else ac_cv_funclib_getpwnam_r=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_getpwnam_r=\${ac_cv_funclib_getpwnam_r-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_getpwnam_r"
+
+: << END
+@@@funcs="$funcs getpwnam_r"@@@
+@@@libs="$libs "" c_r"@@@
+END
+
+# getpwnam_r
+eval "ac_tr_func=HAVE_`echo getpwnam_r | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_getpwnam_r=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_getpwnam_r=yes"
+ eval "LIB_getpwnam_r="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_getpwnam_r=no"
+ eval "LIB_getpwnam_r="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_getpwnam_r=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test "$ac_cv_func_getpwnam_r" = yes; then
+ echo $ac_n "checking if getpwnam_r is posix""... $ac_c" 1>&6
+echo "configure:7835: checking if getpwnam_r is posix" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getpwnam_r_posix'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_libs="$LIBS"
+ LIBS="$LIBS $LIB_getpwnam_r"
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7845 "configure"
+#include "confdefs.h"
+
+#include <pwd.h>
+int main()
+{
+ struct passwd pw, *pwd;
+ return getpwnam_r("", &pw, NULL, 0, &pwd) < 0;
+}
+
+EOF
+if { (eval echo configure:7856: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_getpwnam_r_posix=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_getpwnam_r_posix=no
+fi
+rm -fr conftest*
+fi
+
+LIBS="$ac_libs"
+fi
+
+echo "$ac_t""$ac_cv_func_getpwnam_r_posix" 1>&6
+if test "$ac_cv_func_getpwnam_r_posix" = yes; then
+ cat >> confdefs.h <<\EOF
+#define POSIX_GETPWNAM_R 1
+EOF
+
+fi
+fi
+
+
+
+
+
+echo $ac_n "checking for getsockopt""... $ac_c" 1>&6
+echo "configure:7885: checking for getsockopt" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_getsockopt'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_getsockopt\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" ; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 7900 "configure"
+#include "confdefs.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+int main() {
+getsockopt(0,0,0,0,0)
+; return 0; }
+EOF
+if { (eval echo configure:7912: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_getsockopt=$ac_lib; else ac_cv_funclib_getsockopt=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_getsockopt=\${ac_cv_funclib_getsockopt-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_getsockopt"
+
+: << END
+@@@funcs="$funcs getsockopt"@@@
+@@@libs="$libs "" "@@@
+END
+
+# getsockopt
+eval "ac_tr_func=HAVE_`echo getsockopt | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_getsockopt=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_getsockopt=yes"
+ eval "LIB_getsockopt="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_getsockopt=no"
+ eval "LIB_getsockopt="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_getsockopt=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+
+
+
+echo $ac_n "checking for setsockopt""... $ac_c" 1>&6
+echo "configure:7975: checking for setsockopt" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_setsockopt'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_setsockopt\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" ; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 7990 "configure"
+#include "confdefs.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+int main() {
+setsockopt(0,0,0,0,0)
+; return 0; }
+EOF
+if { (eval echo configure:8002: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_setsockopt=$ac_lib; else ac_cv_funclib_setsockopt=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_setsockopt=\${ac_cv_funclib_setsockopt-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_setsockopt"
+
+: << END
+@@@funcs="$funcs setsockopt"@@@
+@@@libs="$libs "" "@@@
+END
+
+# setsockopt
+eval "ac_tr_func=HAVE_`echo setsockopt | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_setsockopt=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_setsockopt=yes"
+ eval "LIB_setsockopt="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_setsockopt=no"
+ eval "LIB_setsockopt="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_setsockopt=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+
+for ac_func in getudbnam setlim
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8065: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8070 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8093: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:8119: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8124 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:8141: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+if test "$ac_cv_type_signal" = "void" ; then
+ cat >> confdefs.h <<\EOF
+#define VOID_RETSIGTYPE 1
+EOF
+
+fi
+
+
+
+
+
+
+echo $ac_n "checking for hstrerror""... $ac_c" 1>&6
+echo "configure:8172: checking for hstrerror" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_hstrerror'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_hstrerror\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" resolv; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 8187 "configure"
+#include "confdefs.h"
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+int main() {
+hstrerror(17)
+; return 0; }
+EOF
+if { (eval echo configure:8196: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_hstrerror=$ac_lib; else ac_cv_funclib_hstrerror=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_hstrerror=\${ac_cv_funclib_hstrerror-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_hstrerror"
+
+: << END
+@@@funcs="$funcs hstrerror"@@@
+@@@libs="$libs "" resolv"@@@
+END
+
+# hstrerror
+eval "ac_tr_func=HAVE_`echo hstrerror | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_hstrerror=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_hstrerror=yes"
+ eval "LIB_hstrerror="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_hstrerror=no"
+ eval "LIB_hstrerror="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_hstrerror=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test -n "$LIB_hstrerror"; then
+ LIBS="$LIB_hstrerror $LIBS"
+fi
+
+if eval "test \"$ac_cv_func_hstrerror\" != yes"; then
+LIBOBJS="$LIBOBJS hstrerror.o"
+fi
+
+if test "$ac_cv_func_hstrerror" = yes; then
+
+if test "$ac_cv_func_hstrerror+set" != set -o "$ac_cv_func_hstrerror" = yes; then
+echo $ac_n "checking if hstrerror needs a prototype""... $ac_c" 1>&6
+echo "configure:8267: checking if hstrerror needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_hstrerror_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8272 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+int main() {
+struct foo { int foo; } xx;
+extern int hstrerror (struct foo*);
+hstrerror(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:8285: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_hstrerror_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_hstrerror_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_hstrerror_noproto" 1>&6
+
+if test "$ac_cv_func_hstrerror_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_HSTRERROR_PROTO 1
+EOF
+
+fi
+
+fi
+
+fi
+
+if test "$ac_cv_func_asprintf" = yes; then
+
+if test "$ac_cv_func_asprintf+set" != set -o "$ac_cv_func_asprintf" = yes; then
+echo $ac_n "checking if asprintf needs a prototype""... $ac_c" 1>&6
+echo "configure:8314: checking if asprintf needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_asprintf_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8319 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#include <string.h>
+int main() {
+struct foo { int foo; } xx;
+extern int asprintf (struct foo*);
+asprintf(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:8331: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_asprintf_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_asprintf_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_asprintf_noproto" 1>&6
+
+if test "$ac_cv_func_asprintf_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_ASPRINTF_PROTO 1
+EOF
+
+fi
+
+fi
+fi
+if test "$ac_cv_func_vasprintf" = yes; then
+
+if test "$ac_cv_func_vasprintf+set" != set -o "$ac_cv_func_vasprintf" = yes; then
+echo $ac_n "checking if vasprintf needs a prototype""... $ac_c" 1>&6
+echo "configure:8358: checking if vasprintf needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vasprintf_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8363 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#include <string.h>
+int main() {
+struct foo { int foo; } xx;
+extern int vasprintf (struct foo*);
+vasprintf(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:8375: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_vasprintf_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vasprintf_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_vasprintf_noproto" 1>&6
+
+if test "$ac_cv_func_vasprintf_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_VASPRINTF_PROTO 1
+EOF
+
+fi
+
+fi
+fi
+if test "$ac_cv_func_asnprintf" = yes; then
+
+if test "$ac_cv_func_asnprintf+set" != set -o "$ac_cv_func_asnprintf" = yes; then
+echo $ac_n "checking if asnprintf needs a prototype""... $ac_c" 1>&6
+echo "configure:8402: checking if asnprintf needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_asnprintf_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8407 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#include <string.h>
+int main() {
+struct foo { int foo; } xx;
+extern int asnprintf (struct foo*);
+asnprintf(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:8419: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_asnprintf_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_asnprintf_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_asnprintf_noproto" 1>&6
+
+if test "$ac_cv_func_asnprintf_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_ASNPRINTF_PROTO 1
+EOF
+
+fi
+
+fi
+fi
+if test "$ac_cv_func_vasnprintf" = yes; then
+
+if test "$ac_cv_func_vasnprintf+set" != set -o "$ac_cv_func_vasnprintf" = yes; then
+echo $ac_n "checking if vasnprintf needs a prototype""... $ac_c" 1>&6
+echo "configure:8446: checking if vasnprintf needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vasnprintf_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8451 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#include <string.h>
+int main() {
+struct foo { int foo; } xx;
+extern int vasnprintf (struct foo*);
+vasnprintf(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:8463: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_vasnprintf_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vasnprintf_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_vasnprintf_noproto" 1>&6
+
+if test "$ac_cv_func_vasnprintf_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_VASNPRINTF_PROTO 1
+EOF
+
+fi
+
+fi
+fi
+
+for ac_func in chown copyhostent daemon err errx fchown flock fnmatch
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8490: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8495 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8518: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs chown copyhostent daemon err errx fchown flock fnmatch"@@@
+END
+done
+
+for ac_func in freeaddrinfo freehostent gai_strerror getaddrinfo
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8551: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8556 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs freeaddrinfo freehostent gai_strerror getaddrinfo"@@@
+END
+done
+
+for ac_func in getcwd getdtablesize gethostname getipnodebyaddr getipnodebyname
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8612: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8617 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8640: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs getcwd getdtablesize gethostname getipnodebyaddr getipnodebyname"@@@
+END
+done
+
+for ac_func in geteuid getgid getegid
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8673: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8678 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8701: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs geteuid getgid getegid"@@@
+END
+done
+
+for ac_func in getnameinfo getopt getusershell
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8734: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8739 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8762: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs getnameinfo getopt getusershell"@@@
+END
+done
+
+for ac_func in inet_aton inet_ntop inet_pton initgroups innetgr iruserok lstat
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8795: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8800 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs inet_aton inet_ntop inet_pton initgroups innetgr iruserok lstat"@@@
+END
+done
+
+for ac_func in memmove
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8856: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8861 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs memmove"@@@
+END
+done
+
+for ac_func in mkstemp putenv rcmd readv recvmsg sendmsg setegid setenv seteuid
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8917: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8922 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8945: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs mkstemp putenv rcmd readv recvmsg sendmsg setegid setenv seteuid"@@@
+END
+done
+
+for ac_func in strcasecmp strncasecmp strdup strerror strftime
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8978: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8983 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:9006: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs strcasecmp strncasecmp strdup strerror strftime"@@@
+END
+done
+
+for ac_func in strlcat strlcpy strlwr
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:9039: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9044 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:9067: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs strlcat strlcpy strlwr"@@@
+END
+done
+
+for ac_func in strndup strnlen strptime strsep strtok_r strupr
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:9100: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9105 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:9128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs strndup strnlen strptime strsep strtok_r strupr"@@@
+END
+done
+
+for ac_func in swab unsetenv verr verrx vsyslog
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:9161: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9166 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:9189: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs swab unsetenv verr verrx vsyslog"@@@
+END
+done
+
+for ac_func in vwarn vwarnx warn warnx writev
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:9222: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9227 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:9250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ac_tr_func=HAVE_`echo $ac_func | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+: << END
+@@@funcs="$funcs vwarn vwarnx warn warnx writev"@@@
+END
+done
+
+
+
+if test "$ac_cv_func_setenv+set" != set -o "$ac_cv_func_setenv" = yes; then
+echo $ac_n "checking if setenv needs a prototype""... $ac_c" 1>&6
+echo "configure:9284: checking if setenv needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_setenv_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9289 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+int main() {
+struct foo { int foo; } xx;
+extern int setenv (struct foo*);
+setenv(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:9299: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_setenv_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_setenv_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_setenv_noproto" 1>&6
+
+if test "$ac_cv_func_setenv_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_SETENV_PROTO 1
+EOF
+
+fi
+
+fi
+
+
+if test "$ac_cv_func_unsetenv+set" != set -o "$ac_cv_func_unsetenv" = yes; then
+echo $ac_n "checking if unsetenv needs a prototype""... $ac_c" 1>&6
+echo "configure:9325: checking if unsetenv needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_unsetenv_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9330 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+int main() {
+struct foo { int foo; } xx;
+extern int unsetenv (struct foo*);
+unsetenv(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:9340: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_unsetenv_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_unsetenv_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_unsetenv_noproto" 1>&6
+
+if test "$ac_cv_func_unsetenv_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_UNSETENV_PROTO 1
+EOF
+
+fi
+
+fi
+
+
+if test "$ac_cv_func_gethostname+set" != set -o "$ac_cv_func_gethostname" = yes; then
+echo $ac_n "checking if gethostname needs a prototype""... $ac_c" 1>&6
+echo "configure:9366: checking if gethostname needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostname_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9371 "configure"
+#include "confdefs.h"
+#include <unistd.h>
+int main() {
+struct foo { int foo; } xx;
+extern int gethostname (struct foo*);
+gethostname(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:9381: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostname_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostname_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_gethostname_noproto" 1>&6
+
+if test "$ac_cv_func_gethostname_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_GETHOSTNAME_PROTO 1
+EOF
+
+fi
+
+fi
+
+
+if test "$ac_cv_func_mkstemp+set" != set -o "$ac_cv_func_mkstemp" = yes; then
+echo $ac_n "checking if mkstemp needs a prototype""... $ac_c" 1>&6
+echo "configure:9407: checking if mkstemp needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mkstemp_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9412 "configure"
+#include "confdefs.h"
+#include <unistd.h>
+int main() {
+struct foo { int foo; } xx;
+extern int mkstemp (struct foo*);
+mkstemp(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:9422: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_mkstemp_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_mkstemp_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_mkstemp_noproto" 1>&6
+
+if test "$ac_cv_func_mkstemp_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_MKSTEMP_PROTO 1
+EOF
+
+fi
+
+fi
+
+
+if test "$ac_cv_func_getusershell+set" != set -o "$ac_cv_func_getusershell" = yes; then
+echo $ac_n "checking if getusershell needs a prototype""... $ac_c" 1>&6
+echo "configure:9448: checking if getusershell needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getusershell_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9453 "configure"
+#include "confdefs.h"
+#include <unistd.h>
+int main() {
+struct foo { int foo; } xx;
+extern int getusershell (struct foo*);
+getusershell(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:9463: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_getusershell_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_getusershell_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_getusershell_noproto" 1>&6
+
+if test "$ac_cv_func_getusershell_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_GETUSERSHELL_PROTO 1
+EOF
+
+fi
+
+fi
+
+
+
+if test "$ac_cv_func_inet_aton+set" != set -o "$ac_cv_func_inet_aton" = yes; then
+echo $ac_n "checking if inet_aton needs a prototype""... $ac_c" 1>&6
+echo "configure:9490: checking if inet_aton needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_inet_aton_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9495 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+int main() {
+struct foo { int foo; } xx;
+extern int inet_aton (struct foo*);
+inet_aton(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:9517: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_inet_aton_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_inet_aton_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_inet_aton_noproto" 1>&6
+
+if test "$ac_cv_func_inet_aton_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_INET_ATON_PROTO 1
+EOF
+
+fi
+
+fi
+
+
+
+
+
+echo $ac_n "checking for crypt""... $ac_c" 1>&6
+echo "configure:9545: checking for crypt" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_crypt'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_crypt\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" crypt; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 9560 "configure"
+#include "confdefs.h"
+
+int main() {
+crypt()
+; return 0; }
+EOF
+if { (eval echo configure:9567: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_crypt=$ac_lib; else ac_cv_funclib_crypt=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_crypt=\${ac_cv_funclib_crypt-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_crypt"
+
+: << END
+@@@funcs="$funcs crypt"@@@
+@@@libs="$libs "" crypt"@@@
+END
+
+# crypt
+eval "ac_tr_func=HAVE_`echo crypt | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_crypt=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_crypt=yes"
+ eval "LIB_crypt="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_crypt=no"
+ eval "LIB_crypt="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_crypt=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+
+LIB_roken='$(top_builddir)/lib/roken/libroken.la $(LIB_crypt) $(LIB_dbopen)'
+
+echo $ac_n "checking if realloc if broken""... $ac_c" 1>&6
+echo "configure:9630: checking if realloc if broken" >&5
+if eval "test \"`echo '$''{'ac_cv_func_realloc_broken'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ac_cv_func_realloc_broken=no
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9640 "configure"
+#include "confdefs.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+int main()
+{
+ return realloc(NULL, 17) == NULL;
+}
+
+EOF
+if { (eval echo configure:9652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_realloc_broken=yes
+fi
+rm -fr conftest*
+fi
+
+
+fi
+
+echo "$ac_t""$ac_cv_func_realloc_broken" 1>&6
+if test "$ac_cv_func_realloc_broken" = yes ; then
+ cat >> confdefs.h <<\EOF
+#define BROKEN_REALLOC 1
+EOF
+
+fi
+
+
+
+
+echo $ac_n "checking if gethostbyname is compatible with system prototype""... $ac_c" 1>&6
+echo "configure:9679: checking if gethostbyname is compatible with system prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyname_proto_compat'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9684 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+int main() {
+struct hostent *gethostbyname(const char *);
+; return 0; }
+EOF
+if { (eval echo configure:9707: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname_proto_compat=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname_proto_compat=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_gethostbyname_proto_compat" 1>&6
+
+if test "$ac_cv_func_gethostbyname_proto_compat" = yes; then
+ cat >> confdefs.h <<\EOF
+#define GETHOSTBYNAME_PROTO_COMPATIBLE 1
+EOF
+
+fi
+
+
+
+
+echo $ac_n "checking if gethostbyaddr is compatible with system prototype""... $ac_c" 1>&6
+echo "configure:9732: checking if gethostbyaddr is compatible with system prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyaddr_proto_compat'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9737 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+int main() {
+struct hostent *gethostbyaddr(const void *, size_t, int);
+; return 0; }
+EOF
+if { (eval echo configure:9760: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyaddr_proto_compat=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyaddr_proto_compat=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_gethostbyaddr_proto_compat" 1>&6
+
+if test "$ac_cv_func_gethostbyaddr_proto_compat" = yes; then
+ cat >> confdefs.h <<\EOF
+#define GETHOSTBYADDR_PROTO_COMPATIBLE 1
+EOF
+
+fi
+
+
+
+
+echo $ac_n "checking if getservbyname is compatible with system prototype""... $ac_c" 1>&6
+echo "configure:9785: checking if getservbyname is compatible with system prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getservbyname_proto_compat'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9790 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+int main() {
+struct servent *getservbyname(const char *, const char *);
+; return 0; }
+EOF
+if { (eval echo configure:9813: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_getservbyname_proto_compat=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_getservbyname_proto_compat=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_getservbyname_proto_compat" 1>&6
+
+if test "$ac_cv_func_getservbyname_proto_compat" = yes; then
+ cat >> confdefs.h <<\EOF
+#define GETSERVBYNAME_PROTO_COMPATIBLE 1
+EOF
+
+fi
+
+
+
+
+echo $ac_n "checking if openlog is compatible with system prototype""... $ac_c" 1>&6
+echo "configure:9838: checking if openlog is compatible with system prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_openlog_proto_compat'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9843 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
+int main() {
+void openlog(const char *, int, int);
+; return 0; }
+EOF
+if { (eval echo configure:9854: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_openlog_proto_compat=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_openlog_proto_compat=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_openlog_proto_compat" 1>&6
+
+if test "$ac_cv_func_openlog_proto_compat" = yes; then
+ cat >> confdefs.h <<\EOF
+#define OPENLOG_PROTO_COMPATIBLE 1
+EOF
+
+fi
+
+
+
+
+if test "$ac_cv_func_crypt+set" != set -o "$ac_cv_func_crypt" = yes; then
+echo $ac_n "checking if crypt needs a prototype""... $ac_c" 1>&6
+echo "configure:9880: checking if crypt needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_crypt_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9885 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int main() {
+struct foo { int foo; } xx;
+extern int crypt (struct foo*);
+crypt(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:9902: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_crypt_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_crypt_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_crypt_noproto" 1>&6
+
+if test "$ac_cv_func_crypt_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_CRYPT_PROTO 1
+EOF
+
+fi
+
+fi
+
+
+
+if test "$ac_cv_func_strtok_r+set" != set -o "$ac_cv_func_strtok_r" = yes; then
+echo $ac_n "checking if strtok_r needs a prototype""... $ac_c" 1>&6
+echo "configure:9929: checking if strtok_r needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strtok_r_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9934 "configure"
+#include "confdefs.h"
+
+#include <string.h>
+
+int main() {
+struct foo { int foo; } xx;
+extern int strtok_r (struct foo*);
+strtok_r(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:9946: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_strtok_r_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strtok_r_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_strtok_r_noproto" 1>&6
+
+if test "$ac_cv_func_strtok_r_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_STRTOK_R_PROTO 1
+EOF
+
+fi
+
+fi
+
+
+
+if test "$ac_cv_func_strsep+set" != set -o "$ac_cv_func_strsep" = yes; then
+echo $ac_n "checking if strsep needs a prototype""... $ac_c" 1>&6
+echo "configure:9973: checking if strsep needs a prototype" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strsep_noproto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9978 "configure"
+#include "confdefs.h"
+
+#include <string.h>
+
+int main() {
+struct foo { int foo; } xx;
+extern int strsep (struct foo*);
+strsep(&xx);
+
+; return 0; }
+EOF
+if { (eval echo configure:9990: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_strsep_noproto=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strsep_noproto=no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_strsep_noproto" 1>&6
+
+if test "$ac_cv_func_strsep_noproto" = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_STRSEP_PROTO 1
+EOF
+
+fi
+
+fi
+
+
+
+echo $ac_n "checking for h_errno""... $ac_c" 1>&6
+echo "configure:10016: checking for h_errno" >&5
+if eval "test \"`echo '$''{'ac_cv_var_h_errno'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10022 "configure"
+#include "confdefs.h"
+extern int h_errno;
+int foo() { return h_errno; }
+int main() {
+foo()
+; return 0; }
+EOF
+if { (eval echo configure:10030: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_var_h_errno=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_var_h_errno=no
+fi
+rm -f conftest*
+
+fi
+
+
+
+echo "$ac_t""`eval echo \\$ac_cv_var_h_errno`" 1>&6
+if test `eval echo \\$ac_cv_var_h_errno` = yes; then
+ cat >> confdefs.h <<EOF
+#define HAVE_H_ERRNO 1
+EOF
+
+
+echo $ac_n "checking if h_errno is properly declared""... $ac_c" 1>&6
+echo "configure:10053: checking if h_errno is properly declared" >&5
+if eval "test \"`echo '$''{'ac_cv_var_h_errno_declaration'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10059 "configure"
+#include "confdefs.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+extern struct { int foo; } h_errno;
+int main() {
+h_errno.foo = 1;
+; return 0; }
+EOF
+if { (eval echo configure:10072: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_var_h_errno_declaration=no"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_var_h_errno_declaration=yes"
+fi
+rm -f conftest*
+
+fi
+
+
+
+
+echo "$ac_t""$ac_cv_var_h_errno_declaration" 1>&6
+if eval "test \"\$ac_cv_var_h_errno_declaration\" = yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_H_ERRNO_DECLARATION 1
+EOF
+
+fi
+
+
+fi
+
+
+
+
+echo $ac_n "checking for h_errlist""... $ac_c" 1>&6
+echo "configure:10103: checking for h_errlist" >&5
+if eval "test \"`echo '$''{'ac_cv_var_h_errlist'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10109 "configure"
+#include "confdefs.h"
+extern int h_errlist;
+int foo() { return h_errlist; }
+int main() {
+foo()
+; return 0; }
+EOF
+if { (eval echo configure:10117: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_var_h_errlist=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_var_h_errlist=no
+fi
+rm -f conftest*
+
+fi
+
+
+
+echo "$ac_t""`eval echo \\$ac_cv_var_h_errlist`" 1>&6
+if test `eval echo \\$ac_cv_var_h_errlist` = yes; then
+ cat >> confdefs.h <<EOF
+#define HAVE_H_ERRLIST 1
+EOF
+
+
+echo $ac_n "checking if h_errlist is properly declared""... $ac_c" 1>&6
+echo "configure:10140: checking if h_errlist is properly declared" >&5
+if eval "test \"`echo '$''{'ac_cv_var_h_errlist_declaration'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10146 "configure"
+#include "confdefs.h"
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+extern struct { int foo; } h_errlist;
+int main() {
+h_errlist.foo = 1;
+; return 0; }
+EOF
+if { (eval echo configure:10156: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_var_h_errlist_declaration=no"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_var_h_errlist_declaration=yes"
+fi
+rm -f conftest*
+
+fi
+
+
+
+
+echo "$ac_t""$ac_cv_var_h_errlist_declaration" 1>&6
+if eval "test \"\$ac_cv_var_h_errlist_declaration\" = yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_H_ERRLIST_DECLARATION 1
+EOF
+
+fi
+
+
+fi
+
+
+
+
+echo $ac_n "checking for h_nerr""... $ac_c" 1>&6
+echo "configure:10187: checking for h_nerr" >&5
+if eval "test \"`echo '$''{'ac_cv_var_h_nerr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10193 "configure"
+#include "confdefs.h"
+extern int h_nerr;
+int foo() { return h_nerr; }
+int main() {
+foo()
+; return 0; }
+EOF
+if { (eval echo configure:10201: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_var_h_nerr=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_var_h_nerr=no
+fi
+rm -f conftest*
+
+fi
+
+
+
+echo "$ac_t""`eval echo \\$ac_cv_var_h_nerr`" 1>&6
+if test `eval echo \\$ac_cv_var_h_nerr` = yes; then
+ cat >> confdefs.h <<EOF
+#define HAVE_H_NERR 1
+EOF
+
+
+echo $ac_n "checking if h_nerr is properly declared""... $ac_c" 1>&6
+echo "configure:10224: checking if h_nerr is properly declared" >&5
+if eval "test \"`echo '$''{'ac_cv_var_h_nerr_declaration'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10230 "configure"
+#include "confdefs.h"
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+extern struct { int foo; } h_nerr;
+int main() {
+h_nerr.foo = 1;
+; return 0; }
+EOF
+if { (eval echo configure:10240: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_var_h_nerr_declaration=no"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_var_h_nerr_declaration=yes"
+fi
+rm -f conftest*
+
+fi
+
+
+
+
+echo "$ac_t""$ac_cv_var_h_nerr_declaration" 1>&6
+if eval "test \"\$ac_cv_var_h_nerr_declaration\" = yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_H_NERR_DECLARATION 1
+EOF
+
+fi
+
+
+fi
+
+
+
+
+echo $ac_n "checking for __progname""... $ac_c" 1>&6
+echo "configure:10271: checking for __progname" >&5
+if eval "test \"`echo '$''{'ac_cv_var___progname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10277 "configure"
+#include "confdefs.h"
+extern int __progname;
+int foo() { return __progname; }
+int main() {
+foo()
+; return 0; }
+EOF
+if { (eval echo configure:10285: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_var___progname=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_var___progname=no
+fi
+rm -f conftest*
+
+fi
+
+
+
+echo "$ac_t""`eval echo \\$ac_cv_var___progname`" 1>&6
+if test `eval echo \\$ac_cv_var___progname` = yes; then
+ cat >> confdefs.h <<EOF
+#define HAVE___PROGNAME 1
+EOF
+
+
+echo $ac_n "checking if __progname is properly declared""... $ac_c" 1>&6
+echo "configure:10308: checking if __progname is properly declared" >&5
+if eval "test \"`echo '$''{'ac_cv_var___progname_declaration'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10314 "configure"
+#include "confdefs.h"
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+extern struct { int foo; } __progname;
+int main() {
+__progname.foo = 1;
+; return 0; }
+EOF
+if { (eval echo configure:10324: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_var___progname_declaration=no"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_var___progname_declaration=yes"
+fi
+rm -f conftest*
+
+fi
+
+
+
+
+echo "$ac_t""$ac_cv_var___progname_declaration" 1>&6
+if eval "test \"\$ac_cv_var___progname_declaration\" = yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE___PROGNAME_DECLARATION 1
+EOF
+
+fi
+
+
+fi
+
+
+
+
+echo $ac_n "checking if optarg is properly declared""... $ac_c" 1>&6
+echo "configure:10355: checking if optarg is properly declared" >&5
+if eval "test \"`echo '$''{'ac_cv_var_optarg_declaration'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10361 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+extern struct { int foo; } optarg;
+int main() {
+optarg.foo = 1;
+; return 0; }
+EOF
+if { (eval echo configure:10372: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_var_optarg_declaration=no"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_var_optarg_declaration=yes"
+fi
+rm -f conftest*
+
+fi
+
+
+
+
+echo "$ac_t""$ac_cv_var_optarg_declaration" 1>&6
+if eval "test \"\$ac_cv_var_optarg_declaration\" = yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_OPTARG_DECLARATION 1
+EOF
+
+fi
+
+
+
+echo $ac_n "checking if optind is properly declared""... $ac_c" 1>&6
+echo "configure:10399: checking if optind is properly declared" >&5
+if eval "test \"`echo '$''{'ac_cv_var_optind_declaration'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10405 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+extern struct { int foo; } optind;
+int main() {
+optind.foo = 1;
+; return 0; }
+EOF
+if { (eval echo configure:10416: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_var_optind_declaration=no"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_var_optind_declaration=yes"
+fi
+rm -f conftest*
+
+fi
+
+
+
+
+echo "$ac_t""$ac_cv_var_optind_declaration" 1>&6
+if eval "test \"\$ac_cv_var_optind_declaration\" = yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_OPTIND_DECLARATION 1
+EOF
+
+fi
+
+
+
+echo $ac_n "checking if opterr is properly declared""... $ac_c" 1>&6
+echo "configure:10443: checking if opterr is properly declared" >&5
+if eval "test \"`echo '$''{'ac_cv_var_opterr_declaration'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10449 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+extern struct { int foo; } opterr;
+int main() {
+opterr.foo = 1;
+; return 0; }
+EOF
+if { (eval echo configure:10460: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_var_opterr_declaration=no"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_var_opterr_declaration=yes"
+fi
+rm -f conftest*
+
+fi
+
+
+
+
+echo "$ac_t""$ac_cv_var_opterr_declaration" 1>&6
+if eval "test \"\$ac_cv_var_opterr_declaration\" = yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_OPTERR_DECLARATION 1
+EOF
+
+fi
+
+
+
+echo $ac_n "checking if optopt is properly declared""... $ac_c" 1>&6
+echo "configure:10487: checking if optopt is properly declared" >&5
+if eval "test \"`echo '$''{'ac_cv_var_optopt_declaration'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10493 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+extern struct { int foo; } optopt;
+int main() {
+optopt.foo = 1;
+; return 0; }
+EOF
+if { (eval echo configure:10504: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_var_optopt_declaration=no"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_var_optopt_declaration=yes"
+fi
+rm -f conftest*
+
+fi
+
+
+
+
+echo "$ac_t""$ac_cv_var_optopt_declaration" 1>&6
+if eval "test \"\$ac_cv_var_optopt_declaration\" = yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_OPTOPT_DECLARATION 1
+EOF
+
+fi
+
+
+
+
+echo $ac_n "checking if environ is properly declared""... $ac_c" 1>&6
+echo "configure:10532: checking if environ is properly declared" >&5
+if eval "test \"`echo '$''{'ac_cv_var_environ_declaration'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10538 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+extern struct { int foo; } environ;
+int main() {
+environ.foo = 1;
+; return 0; }
+EOF
+if { (eval echo configure:10546: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_var_environ_declaration=no"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_var_environ_declaration=yes"
+fi
+rm -f conftest*
+
+fi
+
+
+
+
+echo "$ac_t""$ac_cv_var_environ_declaration" 1>&6
+if eval "test \"\$ac_cv_var_environ_declaration\" = yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ENVIRON_DECLARATION 1
+EOF
+
+fi
+
+
+
+
+
+
+echo $ac_n "checking for ut_addr in struct utmp""... $ac_c" 1>&6
+echo "configure:10576: checking for ut_addr in struct utmp" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_utmp_ut_addr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10582 "configure"
+#include "confdefs.h"
+#include <utmp.h>
+int main() {
+struct utmp x; x.ut_addr;
+; return 0; }
+EOF
+if { (eval echo configure:10589: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_addr=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_addr=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_utmp_ut_addr" 1>&6
+if test "$ac_cv_type_struct_utmp_ut_addr" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_UTMP_UT_ADDR 1
+EOF
+
+
+fi
+
+
+
+
+echo $ac_n "checking for ut_host in struct utmp""... $ac_c" 1>&6
+echo "configure:10615: checking for ut_host in struct utmp" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_utmp_ut_host'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10621 "configure"
+#include "confdefs.h"
+#include <utmp.h>
+int main() {
+struct utmp x; x.ut_host;
+; return 0; }
+EOF
+if { (eval echo configure:10628: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_host=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_host=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_utmp_ut_host" 1>&6
+if test "$ac_cv_type_struct_utmp_ut_host" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_UTMP_UT_HOST 1
+EOF
+
+
+fi
+
+
+
+
+echo $ac_n "checking for ut_id in struct utmp""... $ac_c" 1>&6
+echo "configure:10654: checking for ut_id in struct utmp" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_utmp_ut_id'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10660 "configure"
+#include "confdefs.h"
+#include <utmp.h>
+int main() {
+struct utmp x; x.ut_id;
+; return 0; }
+EOF
+if { (eval echo configure:10667: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_id=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_id=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_utmp_ut_id" 1>&6
+if test "$ac_cv_type_struct_utmp_ut_id" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_UTMP_UT_ID 1
+EOF
+
+
+fi
+
+
+
+
+echo $ac_n "checking for ut_pid in struct utmp""... $ac_c" 1>&6
+echo "configure:10693: checking for ut_pid in struct utmp" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_utmp_ut_pid'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10699 "configure"
+#include "confdefs.h"
+#include <utmp.h>
+int main() {
+struct utmp x; x.ut_pid;
+; return 0; }
+EOF
+if { (eval echo configure:10706: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_pid=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_pid=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_utmp_ut_pid" 1>&6
+if test "$ac_cv_type_struct_utmp_ut_pid" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_UTMP_UT_PID 1
+EOF
+
+
+fi
+
+
+
+
+echo $ac_n "checking for ut_type in struct utmp""... $ac_c" 1>&6
+echo "configure:10732: checking for ut_type in struct utmp" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_utmp_ut_type'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10738 "configure"
+#include "confdefs.h"
+#include <utmp.h>
+int main() {
+struct utmp x; x.ut_type;
+; return 0; }
+EOF
+if { (eval echo configure:10745: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_type=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_type=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_utmp_ut_type" 1>&6
+if test "$ac_cv_type_struct_utmp_ut_type" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_UTMP_UT_TYPE 1
+EOF
+
+
+fi
+
+
+
+
+echo $ac_n "checking for ut_user in struct utmp""... $ac_c" 1>&6
+echo "configure:10771: checking for ut_user in struct utmp" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_utmp_ut_user'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10777 "configure"
+#include "confdefs.h"
+#include <utmp.h>
+int main() {
+struct utmp x; x.ut_user;
+; return 0; }
+EOF
+if { (eval echo configure:10784: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_user=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_utmp_ut_user=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_utmp_ut_user" 1>&6
+if test "$ac_cv_type_struct_utmp_ut_user" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_UTMP_UT_USER 1
+EOF
+
+
+fi
+
+
+
+
+echo $ac_n "checking for ut_exit in struct utmpx""... $ac_c" 1>&6
+echo "configure:10810: checking for ut_exit in struct utmpx" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_utmpx_ut_exit'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10816 "configure"
+#include "confdefs.h"
+#include <utmpx.h>
+int main() {
+struct utmpx x; x.ut_exit;
+; return 0; }
+EOF
+if { (eval echo configure:10823: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_utmpx_ut_exit=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_utmpx_ut_exit=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_utmpx_ut_exit" 1>&6
+if test "$ac_cv_type_struct_utmpx_ut_exit" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_UTMPX_UT_EXIT 1
+EOF
+
+
+fi
+
+
+
+
+echo $ac_n "checking for ut_syslen in struct utmpx""... $ac_c" 1>&6
+echo "configure:10849: checking for ut_syslen in struct utmpx" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_utmpx_ut_syslen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10855 "configure"
+#include "confdefs.h"
+#include <utmpx.h>
+int main() {
+struct utmpx x; x.ut_syslen;
+; return 0; }
+EOF
+if { (eval echo configure:10862: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_utmpx_ut_syslen=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_utmpx_ut_syslen=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_utmpx_ut_syslen" 1>&6
+if test "$ac_cv_type_struct_utmpx_ut_syslen" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_UTMPX_UT_SYSLEN 1
+EOF
+
+
+fi
+
+
+
+
+
+
+echo $ac_n "checking for tm_gmtoff in struct tm""... $ac_c" 1>&6
+echo "configure:10890: checking for tm_gmtoff in struct tm" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_tm_tm_gmtoff'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10896 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+struct tm x; x.tm_gmtoff;
+; return 0; }
+EOF
+if { (eval echo configure:10903: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_tm_tm_gmtoff=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_tm_tm_gmtoff=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_tm_tm_gmtoff" 1>&6
+if test "$ac_cv_type_struct_tm_tm_gmtoff" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_TM_TM_GMTOFF 1
+EOF
+
+
+fi
+
+
+
+
+echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6
+echo "configure:10929: checking for tm_zone in struct tm" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_tm_tm_zone'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10935 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+struct tm x; x.tm_zone;
+; return 0; }
+EOF
+if { (eval echo configure:10942: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_tm_tm_zone=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_tm_tm_zone=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_tm_tm_zone" 1>&6
+if test "$ac_cv_type_struct_tm_tm_zone" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_TM_TM_ZONE 1
+EOF
+
+
+fi
+
+
+
+
+
+echo $ac_n "checking for timezone""... $ac_c" 1>&6
+echo "configure:10969: checking for timezone" >&5
+if eval "test \"`echo '$''{'ac_cv_var_timezone'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 10975 "configure"
+#include "confdefs.h"
+extern int timezone;
+int foo() { return timezone; }
+int main() {
+foo()
+; return 0; }
+EOF
+if { (eval echo configure:10983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_var_timezone=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_var_timezone=no
+fi
+rm -f conftest*
+
+fi
+
+
+
+echo "$ac_t""`eval echo \\$ac_cv_var_timezone`" 1>&6
+if test `eval echo \\$ac_cv_var_timezone` = yes; then
+ cat >> confdefs.h <<EOF
+#define HAVE_TIMEZONE 1
+EOF
+
+
+echo $ac_n "checking if timezone is properly declared""... $ac_c" 1>&6
+echo "configure:11006: checking if timezone is properly declared" >&5
+if eval "test \"`echo '$''{'ac_cv_var_timezone_declaration'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 11012 "configure"
+#include "confdefs.h"
+#include <time.h>
+extern struct { int foo; } timezone;
+int main() {
+timezone.foo = 1;
+; return 0; }
+EOF
+if { (eval echo configure:11020: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_var_timezone_declaration=no"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_var_timezone_declaration=yes"
+fi
+rm -f conftest*
+
+fi
+
+
+
+
+echo "$ac_t""$ac_cv_var_timezone_declaration" 1>&6
+if eval "test \"\$ac_cv_var_timezone_declaration\" = yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TIMEZONE_DECLARATION 1
+EOF
+
+fi
+
+
+fi
+
+
+
+
+
+cv=`echo "sa_family_t" | sed 'y%./+- %__p__%'`
+echo $ac_n "checking for sa_family_t""... $ac_c" 1>&6
+echo "configure:11053: checking for sa_family_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_$cv'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11058 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <sys/socket.h>
+int main() {
+sa_family_t foo;
+; return 0; }
+EOF
+if { (eval echo configure:11070: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_type_$cv=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_type_$cv=no"
+fi
+rm -f conftest*
+fi
+echo "$ac_t""`eval echo \\$ac_cv_type_$cv`" 1>&6
+if test `eval echo \\$ac_cv_type_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo sa_family_t | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
+
+: << END
+@@@funcs="$funcs sa_family_t"@@@
+END
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+fi
+
+
+
+
+cv=`echo "socklen_t" | sed 'y%./+- %__p__%'`
+echo $ac_n "checking for socklen_t""... $ac_c" 1>&6
+echo "configure:11100: checking for socklen_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_$cv'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11105 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <sys/socket.h>
+int main() {
+socklen_t foo;
+; return 0; }
+EOF
+if { (eval echo configure:11117: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_type_$cv=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_type_$cv=no"
+fi
+rm -f conftest*
+fi
+echo "$ac_t""`eval echo \\$ac_cv_type_$cv`" 1>&6
+if test `eval echo \\$ac_cv_type_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo socklen_t | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
+
+: << END
+@@@funcs="$funcs socklen_t"@@@
+END
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+fi
+
+
+
+
+cv=`echo "struct sockaddr" | sed 'y%./+- %__p__%'`
+echo $ac_n "checking for struct sockaddr""... $ac_c" 1>&6
+echo "configure:11147: checking for struct sockaddr" >&5
+if eval "test \"`echo '$''{'ac_cv_type_$cv'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11152 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <sys/socket.h>
+int main() {
+struct sockaddr foo;
+; return 0; }
+EOF
+if { (eval echo configure:11164: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_type_$cv=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_type_$cv=no"
+fi
+rm -f conftest*
+fi
+echo "$ac_t""`eval echo \\$ac_cv_type_$cv`" 1>&6
+if test `eval echo \\$ac_cv_type_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo struct sockaddr | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
+
+: << END
+@@@funcs="$funcs struct_sockaddr"@@@
+END
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+fi
+
+
+
+
+cv=`echo "struct sockaddr_storage" | sed 'y%./+- %__p__%'`
+echo $ac_n "checking for struct sockaddr_storage""... $ac_c" 1>&6
+echo "configure:11194: checking for struct sockaddr_storage" >&5
+if eval "test \"`echo '$''{'ac_cv_type_$cv'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11199 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <sys/socket.h>
+int main() {
+struct sockaddr_storage foo;
+; return 0; }
+EOF
+if { (eval echo configure:11211: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_type_$cv=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_type_$cv=no"
+fi
+rm -f conftest*
+fi
+echo "$ac_t""`eval echo \\$ac_cv_type_$cv`" 1>&6
+if test `eval echo \\$ac_cv_type_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo struct sockaddr_storage | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
+
+: << END
+@@@funcs="$funcs struct_sockaddr_storage"@@@
+END
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+fi
+
+
+
+
+cv=`echo "struct addrinfo" | sed 'y%./+- %__p__%'`
+echo $ac_n "checking for struct addrinfo""... $ac_c" 1>&6
+echo "configure:11241: checking for struct addrinfo" >&5
+if eval "test \"`echo '$''{'ac_cv_type_$cv'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11246 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <netdb.h>
+int main() {
+struct addrinfo foo;
+; return 0; }
+EOF
+if { (eval echo configure:11258: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_type_$cv=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_type_$cv=no"
+fi
+rm -f conftest*
+fi
+echo "$ac_t""`eval echo \\$ac_cv_type_$cv`" 1>&6
+if test `eval echo \\$ac_cv_type_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo struct addrinfo | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
+
+: << END
+@@@funcs="$funcs struct_addrinfo"@@@
+END
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+fi
+
+
+
+
+echo $ac_n "checking for struct winsize""... $ac_c" 1>&6
+echo "configure:11287: checking for struct winsize" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_winsize'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ac_cv_struct_winsize=no
+for i in sys/termios.h sys/ioctl.h; do
+cat > conftest.$ac_ext <<EOF
+#line 11295 "configure"
+#include "confdefs.h"
+#include <$i>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "struct[ ]*winsize" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_struct_winsize=yes; break
+fi
+rm -f conftest*
+done
+
+fi
+
+if test "$ac_cv_struct_winsize" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_WINSIZE 1
+EOF
+
+fi
+echo "$ac_t""$ac_cv_struct_winsize" 1>&6
+cat > conftest.$ac_ext <<EOF
+#line 11317 "configure"
+#include "confdefs.h"
+#include <termios.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "ws_xpixel" >/dev/null 2>&1; then
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define HAVE_WS_XPIXEL 1
+EOF
+
+fi
+rm -f conftest*
+
+cat > conftest.$ac_ext <<EOF
+#line 11332 "configure"
+#include "confdefs.h"
+#include <termios.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "ws_ypixel" >/dev/null 2>&1; then
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define HAVE_WS_YPIXEL 1
+EOF
+
+fi
+rm -f conftest*
+
+
+
+
+
+echo $ac_n "checking for struct spwd""... $ac_c" 1>&6
+echo "configure:11351: checking for struct spwd" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_spwd'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 11357 "configure"
+#include "confdefs.h"
+#include <pwd.h>
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+int main() {
+struct spwd foo;
+; return 0; }
+EOF
+if { (eval echo configure:11367: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_spwd=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_spwd=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_struct_spwd" 1>&6
+
+if test "$ac_cv_struct_spwd" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_SPWD 1
+EOF
+
+fi
+
+
+
+
+
+echo $ac_n "checking for sa_len in struct sockaddr""... $ac_c" 1>&6
+echo "configure:11394: checking for sa_len in struct sockaddr" >&5
+if eval "test \"`echo '$''{'ac_cv_type_struct_sockaddr_sa_len'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 11400 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+int main() {
+struct sockaddr x; x.sa_len;
+; return 0; }
+EOF
+if { (eval echo configure:11408: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_struct_sockaddr_sa_len=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_struct_sockaddr_sa_len=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_struct_sockaddr_sa_len" 1>&6
+if test "$ac_cv_type_struct_sockaddr_sa_len" = yes; then
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_SOCKADDR_SA_LEN 1
+EOF
+
+
+fi
+
+
+
+
+
+for i in int8_t int16_t int32_t int64_t; do
+ echo $ac_n "checking for $i""... $ac_c" 1>&6
+echo "configure:11436: checking for $i" >&5
+
+if eval "test \"`echo '$''{'ac_cv_type_$i'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11442 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#ifdef HAVE_BIND_BITYPES_H
+#include <bind/bitypes.h>
+#endif
+#ifdef HAVE_NETINET_IN6_MACHTYPES_H
+#include <netinet/in6_machtypes.h>
+#endif
+
+int main() {
+$i x;
+
+; return 0; }
+EOF
+if { (eval echo configure:11466: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval ac_cv_type_$i=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval ac_cv_type_$i=no
+fi
+rm -f conftest*
+fi
+
+ eval ac_res=\$ac_cv_type_$i
+ if test "$ac_res" = yes; then
+ type=HAVE_`echo $i | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+ cat >> confdefs.h <<EOF
+#define $type 1
+EOF
+
+ fi
+ echo "$ac_t""$ac_res" 1>&6
+done
+
+
+for i in u_int8_t u_int16_t u_int32_t u_int64_t; do
+ echo $ac_n "checking for $i""... $ac_c" 1>&6
+echo "configure:11492: checking for $i" >&5
+
+if eval "test \"`echo '$''{'ac_cv_type_$i'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11498 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#ifdef HAVE_BIND_BITYPES_H
+#include <bind/bitypes.h>
+#endif
+#ifdef HAVE_NETINET_IN6_MACHTYPES_H
+#include <netinet/in6_machtypes.h>
+#endif
+
+int main() {
+$i x;
+
+; return 0; }
+EOF
+if { (eval echo configure:11522: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval ac_cv_type_$i=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval ac_cv_type_$i=no
+fi
+rm -f conftest*
+fi
+
+ eval ac_res=\$ac_cv_type_$i
+ if test "$ac_res" = yes; then
+ type=HAVE_`echo $i | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+ cat >> confdefs.h <<EOF
+#define $type 1
+EOF
+
+ fi
+ echo "$ac_t""$ac_res" 1>&6
+done
+
+
+
+
+
+
+
+echo $ac_n "checking for el_init""... $ac_c" 1>&6
+echo "configure:11552: checking for el_init" >&5
+if eval "test \"`echo '$''{'ac_cv_funclib_el_init'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if eval "test \"\$ac_cv_func_el_init\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in "" edit; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS=" $ac_lib $LIB_tgetent $ac_save_LIBS"
+ cat > conftest.$ac_ext <<EOF
+#line 11567 "configure"
+#include "confdefs.h"
+
+int main() {
+el_init()
+; return 0; }
+EOF
+if { (eval echo configure:11574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "if test -n \"$ac_lib\";then ac_cv_funclib_el_init=$ac_lib; else ac_cv_funclib_el_init=yes; fi";break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ done
+ eval "ac_cv_funclib_el_init=\${ac_cv_funclib_el_init-no}"
+ LIBS="$ac_save_LIBS"
+fi
+
+fi
+
+
+eval "ac_res=\$ac_cv_funclib_el_init"
+
+: << END
+@@@funcs="$funcs el_init"@@@
+@@@libs="$libs "" edit"@@@
+END
+
+# el_init
+eval "ac_tr_func=HAVE_`echo el_init | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`"
+eval "LIB_el_init=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_el_init=yes"
+ eval "LIB_el_init="
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+ ;;
+ no)
+ eval "ac_cv_func_el_init=no"
+ eval "LIB_el_init="
+ echo "$ac_t""no" 1>&6
+ ;;
+ *)
+ eval "ac_cv_func_el_init=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ echo "$ac_t""yes, in $ac_res" 1>&6
+ ;;
+esac
+
+
+if test "$ac_cv_func_el_init" = yes ; then
+ echo $ac_n "checking for four argument el_init""... $ac_c" 1>&6
+echo "configure:11635: checking for four argument el_init" >&5
+if eval "test \"`echo '$''{'ac_cv_func_el_init_four'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ cat > conftest.$ac_ext <<EOF
+#line 11641 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+ #include <histedit.h>
+int main() {
+el_init("", NULL, NULL, NULL);
+; return 0; }
+EOF
+if { (eval echo configure:11649: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_func_el_init_four=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_el_init_four=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_el_init_four" 1>&6
+ if test "$ac_cv_func_el_init_four" = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_FOUR_VALUED_EL_INIT 1
+EOF
+
+ fi
+fi
+
+
+ac_foo=no
+if test "$with_readline" = yes; then
+ :
+elif test "$ac_cv_func_readline" = yes; then
+ :
+elif test "$ac_cv_func_el_init" = yes; then
+ ac_foo=yes
+ LIB_readline="\$(top_builddir)/lib/editline/libel_compat.a $LIB_el_init"
+else
+ LIB_readline='$(top_builddir)/lib/editline/libeditline.a'
+fi
+
+
+if test "$ac_foo" = yes; then
+ el_compat_TRUE=
+ el_compat_FALSE='#'
+else
+ el_compat_TRUE='#'
+ el_compat_FALSE=
+fi
+if test "$readline_libdir"; then
+ LIB_readline="-rpath $readline_libdir $LIB_readline"
+fi
+LIB_readline="$LIB_readline \$(LIB_tgetent)"
+cat >> confdefs.h <<\EOF
+#define HAVE_READLINE 1
+EOF
+
+
+cat >> confdefs.h <<\EOF
+#define AUTHENTICATION 1
+EOF
+cat >> confdefs.h <<\EOF
+#define ENCRYPTION 1
+EOF
+cat >> confdefs.h <<\EOF
+#define DES_ENCRYPTION 1
+EOF
+cat >> confdefs.h <<\EOF
+#define DIAGNOSTICS 1
+EOF
+cat >> confdefs.h <<\EOF
+#define OLD_ENVIRON 1
+EOF
+if false; then
+cat >> confdefs.h <<\EOF
+#define ENV_HACK 1
+EOF
+
+fi
+
+# Simple test for streamspty, based on the existance of getmsg(), alas
+# this breaks on SunOS4 which have streams but BSD-like ptys
+#
+# And also something wierd has happend with dec-osf1, fallback to bsd-ptys
+
+echo $ac_n "checking for streamspty""... $ac_c" 1>&6
+echo "configure:11728: checking for streamspty" >&5
+case "$host" in
+*-*-aix3*|*-*-sunos4*|*-*-osf*|*-*-hpux10*)
+ krb_cv_sys_streamspty=no
+ ;;
+*)
+ krb_cv_sys_streamspty="$ac_cv_func_getmsg"
+ ;;
+esac
+if test "$krb_cv_sys_streamspty" = yes; then
+ cat >> confdefs.h <<\EOF
+#define STREAMSPTY 1
+EOF
+
+fi
+echo "$ac_t""$krb_cv_sys_streamspty" 1>&6
+
+
+echo $ac_n "checking which authentication modules should be built""... $ac_c" 1>&6
+echo "configure:11747: checking which authentication modules should be built" >&5
+
+LIB_AUTH_SUBDIRS=
+
+if test "$ac_cv_header_siad_h" = yes; then
+ LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS sia"
+fi
+
+if test "$ac_cv_header_security_pam_modules_h" = yes -a "$enable_shared" = yes; then
+ LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS pam"
+fi
+
+case "${host}" in
+*-*-irix[56]*) LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS afskauthlib" ;;
+esac
+
+echo "$ac_t""$LIB_AUTH_SUBDIRS" 1>&6
+
+
+
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+for i in bin lib libexec sbin; do
+ i=${i}dir
+ foo=`echo $i | tr 'xindiscernible' 'XINDISCERNIBLE'`
+ x="\$${i}"
+ eval y="$x"
+ while test "x$y" != "x$x"; do
+ x="$y"
+ eval y="$x"
+ done
+ cat >> confdefs.h <<EOF
+#define $foo "$x"
+EOF
+
+done
+
+if false; then
+ # hack to shut up automake
+ LIBOBJS="$LIBOBJS make-print-version.o"
+fi
+LTLIBOBJS=`echo "$LIBOBJS" | sed 's/\.o/\.lo/g'`
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile \
+ include/Makefile \
+ include/kadm5/Makefile \
+ lib/Makefile \
+ lib/45/Makefile \
+ lib/auth/Makefile \
+ lib/auth/afskauthlib/Makefile \
+ lib/auth/pam/Makefile \
+ lib/auth/sia/Makefile \
+ lib/asn1/Makefile \
+ lib/com_err/Makefile \
+ lib/des/Makefile \
+ lib/editline/Makefile \
+ lib/gssapi/Makefile \
+ lib/hdb/Makefile \
+ lib/kadm5/Makefile \
+ lib/kafs/Makefile \
+ lib/krb5/Makefile \
+ lib/otp/Makefile \
+ lib/roken/Makefile \
+ lib/sl/Makefile \
+ kuser/Makefile \
+ kpasswd/Makefile \
+ kadmin/Makefile \
+ admin/Makefile \
+ kdc/Makefile \
+ appl/Makefile \
+ appl/afsutil/Makefile \
+ appl/ftp/Makefile \
+ appl/ftp/common/Makefile \
+ appl/ftp/ftp/Makefile \
+ appl/ftp/ftpd/Makefile \
+ appl/kauth/Makefile \
+ appl/kx/Makefile \
+ appl/login/Makefile \
+ appl/otp/Makefile \
+ appl/popper/Makefile \
+ appl/push/Makefile \
+ appl/rsh/Makefile \
+ appl/su/Makefile \
+ appl/xnlock/Makefile \
+ appl/telnet/Makefile \
+ appl/telnet/libtelnet/Makefile \
+ appl/telnet/telnet/Makefile \
+ appl/telnet/telnetd/Makefile \
+ appl/test/Makefile \
+ appl/kf/Makefile \
+ doc/Makefile \
+ include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@CANONICAL_HOST@%$CANONICAL_HOST%g
+s%@CC@%$CC%g
+s%@OBJEXT@%$OBJEXT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@YACC@%$YACC%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@CPP@%$CPP%g
+s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g
+s%@RANLIB@%$RANLIB%g
+s%@AWK@%$AWK%g
+s%@LN_S@%$LN_S%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@WFLAGS@%$WFLAGS%g
+s%@WFLAGS_NOUNUSED@%$WFLAGS_NOUNUSED%g
+s%@WFLAGS_NOIMPLICITINT@%$WFLAGS_NOIMPLICITINT%g
+s%@INCLUDE_krb4@%$INCLUDE_krb4%g
+s%@LIB_krb4@%$LIB_krb4%g
+s%@EXTRA_LIB45@%$EXTRA_LIB45%g
+s%@LIB_krb_enable_debug@%$LIB_krb_enable_debug%g
+s%@LIB_krb_disable_debug@%$LIB_krb_disable_debug%g
+s%@LIB_krb_get_our_ip_for_realm@%$LIB_krb_get_our_ip_for_realm%g
+s%@KRB4_TRUE@%$KRB4_TRUE%g
+s%@KRB4_FALSE@%$KRB4_FALSE%g
+s%@KRB5_TRUE@%$KRB5_TRUE%g
+s%@KRB5_FALSE@%$KRB5_FALSE%g
+s%@LIB_kdb@%$LIB_kdb%g
+s%@AIX_TRUE@%$AIX_TRUE%g
+s%@AIX_FALSE@%$AIX_FALSE%g
+s%@AIX4_TRUE@%$AIX4_TRUE%g
+s%@AIX4_FALSE@%$AIX4_FALSE%g
+s%@AIX_DYNAMIC_AFS_TRUE@%$AIX_DYNAMIC_AFS_TRUE%g
+s%@AIX_DYNAMIC_AFS_FALSE@%$AIX_DYNAMIC_AFS_FALSE%g
+s%@LIB_dlopen@%$LIB_dlopen%g
+s%@HAVE_DLOPEN_TRUE@%$HAVE_DLOPEN_TRUE%g
+s%@HAVE_DLOPEN_FALSE@%$HAVE_DLOPEN_FALSE%g
+s%@AFS_EXTRA_LD@%$AFS_EXTRA_LD%g
+s%@AIX_EXTRA_KAFS@%$AIX_EXTRA_KAFS%g
+s%@LIB_otp@%$LIB_otp%g
+s%@OTP_TRUE@%$OTP_TRUE%g
+s%@OTP_FALSE@%$OTP_FALSE%g
+s%@LIB_security@%$LIB_security%g
+s%@NROFF@%$NROFF%g
+s%@GROFF@%$GROFF%g
+s%@CATMAN@%$CATMAN%g
+s%@CATMAN_TRUE@%$CATMAN_TRUE%g
+s%@CATMAN_FALSE@%$CATMAN_FALSE%g
+s%@CATMANEXT@%$CATMANEXT%g
+s%@INCLUDE_readline@%$INCLUDE_readline%g
+s%@LIB_readline@%$LIB_readline%g
+s%@INCLUDE_hesiod@%$INCLUDE_hesiod%g
+s%@LIB_hesiod@%$LIB_hesiod%g
+s%@X_CFLAGS@%$X_CFLAGS%g
+s%@X_PRE_LIBS@%$X_PRE_LIBS%g
+s%@X_LIBS@%$X_LIBS%g
+s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g
+s%@MAKE_X_PROGS_BIN_PROGS@%$MAKE_X_PROGS_BIN_PROGS%g
+s%@MAKE_X_PROGS_BIN_SCRPTS@%$MAKE_X_PROGS_BIN_SCRPTS%g
+s%@MAKE_X_PROGS_LIBEXEC_PROGS@%$MAKE_X_PROGS_LIBEXEC_PROGS%g
+s%@LIB_XauWriteAuth@%$LIB_XauWriteAuth%g
+s%@LIB_XauReadAuth@%$LIB_XauReadAuth%g
+s%@LIB_XauFileName@%$LIB_XauFileName%g
+s%@NEED_WRITEAUTH_TRUE@%$NEED_WRITEAUTH_TRUE%g
+s%@NEED_WRITEAUTH_FALSE@%$NEED_WRITEAUTH_FALSE%g
+s%@have_err_h_TRUE@%$have_err_h_TRUE%g
+s%@have_err_h_FALSE@%$have_err_h_FALSE%g
+s%@have_fnmatch_h_TRUE@%$have_fnmatch_h_TRUE%g
+s%@have_fnmatch_h_FALSE@%$have_fnmatch_h_FALSE%g
+s%@LIB_socket@%$LIB_socket%g
+s%@LIB_gethostbyname@%$LIB_gethostbyname%g
+s%@LIB_syslog@%$LIB_syslog%g
+s%@LIB_logwtmp@%$LIB_logwtmp%g
+s%@LIB_tgetent@%$LIB_tgetent%g
+s%@LIB_gethostbyname2@%$LIB_gethostbyname2%g
+s%@LIB_res_search@%$LIB_res_search%g
+s%@LIB_dn_expand@%$LIB_dn_expand%g
+s%@have_glob_h_TRUE@%$have_glob_h_TRUE%g
+s%@have_glob_h_FALSE@%$have_glob_h_FALSE%g
+s%@LIB_dbopen@%$LIB_dbopen%g
+s%@LIB_dbm_firstkey@%$LIB_dbm_firstkey%g
+s%@DBLIB@%$DBLIB%g
+s%@LIB_getpwnam_r@%$LIB_getpwnam_r%g
+s%@LIB_getsockopt@%$LIB_getsockopt%g
+s%@LIB_setsockopt@%$LIB_setsockopt%g
+s%@VOID_RETSIGTYPE@%$VOID_RETSIGTYPE%g
+s%@LIB_hstrerror@%$LIB_hstrerror%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@LIB_crypt@%$LIB_crypt%g
+s%@LIB_roken@%$LIB_roken%g
+s%@LIB_el_init@%$LIB_el_init%g
+s%@el_compat_TRUE@%$el_compat_TRUE%g
+s%@el_compat_FALSE@%$el_compat_FALSE%g
+s%@LIB_AUTH_SUBDIRS@%$LIB_AUTH_SUBDIRS%g
+s%@LTLIBOBJS@%$LTLIBOBJS%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile \
+ include/Makefile \
+ include/kadm5/Makefile \
+ lib/Makefile \
+ lib/45/Makefile \
+ lib/auth/Makefile \
+ lib/auth/afskauthlib/Makefile \
+ lib/auth/pam/Makefile \
+ lib/auth/sia/Makefile \
+ lib/asn1/Makefile \
+ lib/com_err/Makefile \
+ lib/des/Makefile \
+ lib/editline/Makefile \
+ lib/gssapi/Makefile \
+ lib/hdb/Makefile \
+ lib/kadm5/Makefile \
+ lib/kafs/Makefile \
+ lib/krb5/Makefile \
+ lib/otp/Makefile \
+ lib/roken/Makefile \
+ lib/sl/Makefile \
+ kuser/Makefile \
+ kpasswd/Makefile \
+ kadmin/Makefile \
+ admin/Makefile \
+ kdc/Makefile \
+ appl/Makefile \
+ appl/afsutil/Makefile \
+ appl/ftp/Makefile \
+ appl/ftp/common/Makefile \
+ appl/ftp/ftp/Makefile \
+ appl/ftp/ftpd/Makefile \
+ appl/kauth/Makefile \
+ appl/kx/Makefile \
+ appl/login/Makefile \
+ appl/otp/Makefile \
+ appl/popper/Makefile \
+ appl/push/Makefile \
+ appl/rsh/Makefile \
+ appl/su/Makefile \
+ appl/xnlock/Makefile \
+ appl/telnet/Makefile \
+ appl/telnet/libtelnet/Makefile \
+ appl/telnet/telnet/Makefile \
+ appl/telnet/telnetd/Makefile \
+ appl/test/Makefile \
+ appl/kf/Makefile \
+ doc/Makefile \
+"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="include/config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > include/stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
+HEIMDALVERSION="$PACKAGE-$VERSION"
+
+cat > include/newversion.h.in <<EOF
+char *heimdal_long_version = "@(#)\$Version: $HEIMDALVERSION by @USER@ on @HOST@ ($host) @DATE@ \$";
+char *heimdal_version = "$HEIMDALVERSION";
+EOF
+
+if test -f include/version.h && cmp -s include/newversion.h.in include/version.h.in; then
+ echo "include/version.h is unchanged"
+ rm -f include/newversion.h.in
+else
+ echo "creating include/version.h"
+ User=${USER-${LOGNAME}}
+ Host=`(hostname || uname -n || echo unknown) 2>/dev/null | sed 1q`
+ Date=`date`
+ mv -f include/newversion.h.in include/version.h.in
+ sed -e "s/@USER@/$User/" -e "s/@HOST@/$Host/" -e "s/@DATE@/$Date/" include/version.h.in > include/version.h
+fi
diff --git a/crypto/heimdal/configure.in b/crypto/heimdal/configure.in
new file mode 100644
index 000000000000..f406c0304e86
--- /dev/null
+++ b/crypto/heimdal/configure.in
@@ -0,0 +1,934 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_REVISION($Revision: 1.215 $)
+AC_INIT(lib/krb5/send_to_kdc.c)
+AM_CONFIG_HEADER(include/config.h)
+
+AM_INIT_AUTOMAKE(heimdal,0.2m)
+
+AC_PREFIX_DEFAULT(/usr/heimdal)
+
+AC_CANONICAL_HOST
+CANONICAL_HOST=$host
+AC_SUBST(CANONICAL_HOST)
+
+sunos=no
+case "$host" in
+*-*-sunos4*)
+ sunos=40
+ ;;
+*-*-solaris2.7)
+ sunos=57
+ ;;
+*-*-solaris2*)
+ sunos=50
+ ;;
+esac
+if test "$sunos" != no; then
+ AC_DEFINE_UNQUOTED(SunOS, $sunos,
+ [Define to what version of SunOS you are running.])
+fi
+
+aix=no
+case "$host" in
+*-*-aix3*)
+ aix=3
+ ;;
+*-*-aix4*)
+ aix=4
+ ;;
+esac
+
+#test -z "$CFLAGS" && CFLAGS="-g"
+
+dnl Checks for programs.
+AC_PROG_CC
+
+AC_CYGWIN
+AC_OBJEXT
+AC_EXEEXT
+
+dnl AC_KRB_PROG_YACC
+AC_PROG_YACC
+AM_PROG_LEX
+AC_PROG_RANLIB
+AC_PROG_AWK
+AC_KRB_PROG_LN_S
+
+AC_MIPS_ABI
+CC="$CC $abi"
+libdir="$libdir$abilibdirext"
+
+AC_C___ATTRIBUTE__
+
+AM_DISABLE_SHARED
+AM_PROG_LIBTOOL
+
+AC_WFLAGS(-Wall -Wmissing-prototypes -Wpointer-arith -Wbad-function-cast -Wmissing-declarations -Wnested-externs)
+
+berkeley_db=db
+AC_ARG_WITH(berkeley-db,
+[ --without-berkeley-db if you don't want berkeley db],[
+if test "$withval" = no; then
+ berkeley_db=""
+fi
+])
+
+AC_TEST_PACKAGE_NEW(krb4,[#include <krb.h>],-lkrb,-ldes,/usr/athena)
+
+LIB_kdb=
+if test "$with_krb4" != "no"; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $INCLUDE_krb4"
+ save_LIBS="$LIBS"
+ LIBS="$LIB_krb4 -ldes $LIBS"
+ EXTRA_LIB45=lib45.a
+ AC_SUBST(EXTRA_LIB45)
+ AC_CACHE_CHECK(for four valued krb_put_int, ac_cv_func_krb_put_int_four,
+ [AC_TRY_COMPILE([#include <krb.h>],[
+ char tmp[4];
+ krb_put_int(17, tmp, 4, sizeof(tmp));],
+ ac_cv_func_krb_put_int_four=yes,
+ ac_cv_func_krb_put_int_four=no)
+ ])
+ if test "$ac_cv_func_krb_put_int_four" = yes; then
+ AC_DEFINE(HAVE_FOUR_VALUED_KRB_PUT_INT, 1,
+ [define if krb_put_int takes four arguments.])
+ fi
+ AC_CACHE_CHECK(for KRB_VERIFY_SECURE, ac_cv_func_krb_verify_secure,
+ [AC_TRY_COMPILE([#include <krb.h>],[
+ int x = KRB_VERIFY_SECURE],
+ ac_cv_func_krb_verify_secure=yes,
+ ac_cv_func_krb_verify_secure=no)
+ ])
+ if test "$ac_cv_func_krb_verify_secure" != yes; then
+ AC_DEFINE(KRB_VERIFY_SECURE, 1,
+ [Define to one if your krb.h doesn't])
+ AC_DEFINE(KRB_VERIFY_SECURE_FAIL, 2,
+ [Define to two if your krb.h doesn't])
+ fi
+ AC_CACHE_CHECK(for KRB_VERIFY_NOT_SECURE,
+ ac_cv_func_krb_verify_not_secure,
+ [AC_TRY_COMPILE([#include <krb.h>],[
+ int x = KRB_VERIFY_NOT_SECURE],
+ ac_cv_func_krb_verify_not_secure=yes,
+ ac_cv_func_krb_verify_not_secure=no)
+ ])
+ if test "$ac_cv_func_krb_verify_not_secure" != yes; then
+ AC_DEFINE(KRB_VERIFY_NOT_SECURE, 0,
+ [Define to zero if your krb.h doesn't])
+ fi
+ AC_FIND_FUNC(krb_enable_debug)
+ AC_FIND_FUNC(krb_disable_debug)
+ AC_FIND_FUNC(krb_get_our_ip_for_realm)
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+ LIB_kdb="-lkdb -lkrb"
+ if test "$krb4_libdir"; then
+ LIB_krb4="-rpath $krb4_libdir $LIB_krb4"
+ LIB_kdb="-rpath $krb4_libdir -L$krb4_libdir $LIB_kdb"
+ fi
+fi
+AM_CONDITIONAL(KRB4, test "$with_krb4" != "no")
+AM_CONDITIONAL(KRB5, true)
+AC_DEFINE(KRB5, 1, [Enable Kerberos 5 support in applications.])dnl
+AC_SUBST(LIB_kdb)dnl
+AM_CONDITIONAL(AIX, test "$aix" != no)dnl
+AM_CONDITIONAL(AIX4, test "$aix" = 4)
+aix_dynamic_afs=yes
+AM_CONDITIONAL(AIX_DYNAMIC_AFS, test "$aix_dynamic_afs" = yes)dnl
+
+AC_FIND_FUNC_NO_LIBS(dlopen, dl)
+
+if test "$aix" != no; then
+ if test "$aix_dynamic_afs" = yes; then
+ if test "$ac_cv_funclib_dlopen" = yes; then
+ AIX_EXTRA_KAFS=
+ elif test "$ac_cv_funclib_dlopen" != no; then
+ AIX_EXTRA_KAFS="$ac_cv_funclib_dlopen"
+ else
+ AIX_EXTRA_KAFS=-lld
+ fi
+ else
+ AIX_EXTRA_KAFS=
+ fi
+fi
+
+AM_CONDITIONAL(HAVE_DLOPEN, test "$ac_cv_funclib_dlopen" != no)dnl
+AC_SUBST(AFS_EXTRA_LD)dnl
+AC_SUBST(AIX_EXTRA_KAFS)dnl
+
+AC_ARG_ENABLE(kaserver,
+[ --enable-kaserver if you want the KDC to try to emulate a kaserver])
+if test "$enable_kaserver" = yes; then
+ AC_DEFINE(KASERVER, 1,
+ [Define if you want to use the KDC as a kaserver.])
+ if test "$with_krb4" = "no"; then
+ AC_MSG_ERROR(kaserver requires krb4)
+ exit 1
+ fi
+fi
+
+AC_ARG_ENABLE(kaserver-db,
+[ --enable-kaserver-db if you want support for reading kaserver databases in hprop])
+if test "$enable_kaserver_db" = yes; then
+ AC_DEFINE(KASERVER_DB, 1,
+ [Define if you want support in hprop for reading kaserver databases])
+ if test "$with_krb4" = "no"; then
+ AC_MSG_ERROR(kaserver-db requires krb4)
+ exit 1
+ fi
+fi
+
+otp=yes
+AC_ARG_ENABLE(otp,
+[ --disable-otp if you don't want OTP support],
+[
+if test "$enableval" = "no"; then
+ otp=no
+fi
+])
+if test "$otp" = "yes"; then
+ AC_DEFINE(OTP, 1, [Define if you want OTP support in applications.])
+ LIB_otp='$(top_builddir)/lib/otp/libotp.la'
+fi
+AC_SUBST(LIB_otp)
+AM_CONDITIONAL(OTP, test "$otp" = yes)dnl
+
+AC_CHECK_OSFC2
+
+AC_CHECK_MAN
+
+AC_TEST_PACKAGE_NEW(readline,
+[#include <stdio.h>
+ #include <readline.h>],-lreadline)
+
+AC_TEST_PACKAGE_NEW(hesiod,[#include <hesiod.h>],-lhesiod)
+
+KRB_C_BIGENDIAN
+AC_C_INLINE
+
+KRB_CHECK_X
+
+if test "$no_x" = "yes" ; then
+ MAKE_X_PROGS_BIN_PROGS=""
+ MAKE_X_PROGS_BIN_SCRPTS=""
+ MAKE_X_PROGS_LIBEXEC_PROGS=""
+else
+ MAKE_X_PROGS_BIN_PROGS='$(X_PROGS_BIN_PROGS)'
+ MAKE_X_PROGS_BIN_SCRPTS='$(X_PROGS_BIN_SCRPTS)'
+ MAKE_X_PROGS_LIBEXEC_PROGS='$(X_PROGS_LIBEXEC_PROGS)'
+fi
+AC_SUBST(MAKE_X_PROGS_BIN_PROGS)dnl
+AC_SUBST(MAKE_X_PROGS_BIN_SCRPTS)dnl
+AC_SUBST(MAKE_X_PROGS_LIBEXEC_PROGS)dnl
+
+AC_CHECK_XAU
+
+dnl AM_C_PROTOTYPES
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_CHECK_TYPE_EXTRA(ssize_t, int, [#include <unistd.h>])
+AC_TYPE_PID_T
+AC_TYPE_UID_T
+AC_CHECK_TYPE_EXTRA(mode_t, unsigned short, [])
+AC_CHECK_TYPE_EXTRA(sig_atomic_t, int, [#include <signal.h>])
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl Checks for header files.
+AC_HEADER_STDC
+
+if test "$berkeley_db"; then
+ AC_CHECK_HEADERS([ \
+ db.h \
+ db_185.h \
+ ])
+fi
+
+AC_CHECK_HEADERS([\
+ arpa/ftp.h \
+ arpa/inet.h \
+ arpa/nameser.h \
+ arpa/telnet.h \
+ bind/bitypes.h \
+ bsdsetjmp.h \
+ crypt.h \
+ curses.h \
+ dbm.h \
+ dirent.h \
+ dlfcn.h \
+ err.h \
+ errno.h \
+ fcntl.h \
+ fnmatch.h \
+ grp.h \
+ inttypes.h \
+ io.h \
+ limits.h \
+ maillock.h \
+ ndbm.h \
+ net/if.h \
+ netdb.h \
+ netinet/in.h \
+ netinet/in6.h \
+ netinet/in6_machtypes.h \
+ netinet/in6_var.h \
+ netinet/in_systm.h \
+ netinet6/in6.h \
+ netinfo/ni.h \
+ paths.h \
+ pthread.h \
+ pty.h \
+ pwd.h \
+ resolv.h \
+ rpcsvc/dbm.h \
+ sac.h \
+ security/pam_modules.h \
+ sgtty.h \
+ shadow.h \
+ siad.h \
+ signal.h \
+ stropts.h \
+ sys/bitypes.h \
+ sys/category.h \
+ sys/file.h \
+ sys/filio.h \
+ sys/ioccom.h \
+ sys/ioctl.h \
+ sys/param.h \
+ sys/proc.h \
+ sys/pty.h \
+ sys/ptyio.h \
+ sys/ptyvar.h \
+ sys/resource.h \
+ sys/select.h \
+ sys/socket.h \
+ sys/sockio.h \
+ sys/stat.h \
+ sys/str_tty.h \
+ sys/stream.h \
+ sys/stropts.h \
+ sys/strtty.h \
+ sys/syscall.h \
+ sys/sysctl.h \
+ sys/termio.h \
+ sys/time.h \
+ sys/timeb.h \
+ sys/times.h \
+ sys/tty.h \
+ sys/types.h \
+ sys/uio.h \
+ sys/un.h \
+ sys/utsname.h \
+ sys/wait.h \
+ syslog.h \
+ term.h \
+ termio.h \
+ termios.h \
+ time.h \
+ tmpdir.h \
+ udb.h \
+ unistd.h \
+ util.h \
+ utmp.h \
+ utmpx.h \
+])
+
+CHECK_NETINET_IP_AND_TCP
+
+
+AC_ARG_ENABLE(netinfo,
+[ --enable-netinfo enable netinfo for configuration lookup])
+
+if test "$ac_cv_header_netinfo_ni_h" = yes -a "$enable_netinfo" = yes; then
+ AC_DEFINE(HAVE_NETINFO, 1,
+ [Define if you want to use Netinfo instead of krb5.conf.])
+fi
+
+AM_CONDITIONAL(have_err_h, test "$ac_cv_header_err_h" = yes)
+AM_CONDITIONAL(have_fnmatch_h, test "$ac_cv_header_fnmatch_h" = yes)
+
+AC_KRB_IPV6
+
+dnl Checks for libraries.
+
+AC_FIND_FUNC(socket, socket)
+AC_FIND_FUNC(gethostbyname, nsl)
+AC_FIND_FUNC(syslog, syslog)
+
+AC_FIND_FUNC_NO_LIBS(logwtmp, util)
+AC_FIND_FUNC_NO_LIBS(tgetent, termcap ncurses curses)
+AC_FIND_FUNC(gethostbyname2, inet6 ip6)
+
+AC_FIND_FUNC(res_search, resolv,
+[
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+],
+[0,0,0,0,0])
+
+AC_FIND_FUNC(dn_expand, resolv,
+[
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+],
+[0,0,0,0,0])
+
+dnl Checks for library functions.
+
+AC_BROKEN_SNPRINTF
+AC_BROKEN_VSNPRINTF
+
+AC_BROKEN_GLOB
+
+if test "$ac_cv_func_glob_working" != yes; then
+ LIBOBJS="$LIBOBJS glob.o"
+fi
+AM_CONDITIONAL(have_glob_h, test "$ac_cv_func_glob_working" = yes)
+
+dnl these should happen after tests for *snprintf
+
+AC_FIND_FUNC_NO_LIBS(dbopen, $berkeley_db)
+AC_FIND_FUNC_NO_LIBS(dbm_firstkey, $berkeley_db gdbm ndbm)
+
+DBLIB="$LIB_dbopen"
+if test "$LIB_dbopen" != "$LIB_dbm_firstkey"; then
+ DBLIB="$DBLIB $LIB_dbm_firstkey"
+fi
+AC_SUBST(DBLIB)dnl
+
+AC_CHECK_FUNCS(_getpty _scrsize asnprintf asprintf cgetent fcntl)
+AC_CHECK_FUNCS(getmsg getrlimit getspnam gettimeofday getuid)
+AC_CHECK_FUNCS(grantpt mktime ptsname rand random setproctitle)
+AC_CHECK_FUNCS(revoke select setitimer setpcred setpgid)
+AC_CHECK_FUNCS(setregid setresgid setresuid setreuid setutent)
+AC_CHECK_FUNCS(setsid sigaction strstr)
+AC_CHECK_FUNCS(sysconf sysctl timegm ttyname ttyslot umask uname)
+AC_CHECK_FUNCS(unlockpt vasnprintf vasprintf vhangup)
+AC_CHECK_FUNCS(yp_get_default_domain)
+
+if test "$ac_cv_func_cgetent" = no; then
+ LIBOBJS="$LIBOBJS getcap.o"
+fi
+
+AC_FUNC_GETLOGIN
+
+KRB_CAPABILITIES
+
+AC_CHECK_GETPWNAM_R_POSIX
+
+AC_FIND_FUNC_NO_LIBS(getsockopt,,
+[#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif],
+[0,0,0,0,0])
+AC_FIND_FUNC_NO_LIBS(setsockopt,,
+[#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif],
+[0,0,0,0,0])
+
+dnl Cray stuff
+AC_CHECK_FUNCS(getudbnam setlim)
+
+AC_TYPE_SIGNAL
+if test "$ac_cv_type_signal" = "void" ; then
+ AC_DEFINE(VOID_RETSIGTYPE, 1, [Define if signal handlers return void.])
+fi
+AC_SUBST(VOID_RETSIGTYPE)
+
+AC_FIND_IF_NOT_BROKEN(hstrerror, resolv,
+[#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif],
+17)
+if test "$ac_cv_func_hstrerror" = yes; then
+AC_NEED_PROTO([
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif],
+hstrerror)
+fi
+
+dnl sigh, wish this could be done in a loop
+if test "$ac_cv_func_asprintf" = yes; then
+AC_NEED_PROTO([
+#include <stdio.h>
+#include <string.h>],
+asprintf)dnl
+fi
+if test "$ac_cv_func_vasprintf" = yes; then
+AC_NEED_PROTO([
+#include <stdio.h>
+#include <string.h>],
+vasprintf)dnl
+fi
+if test "$ac_cv_func_asnprintf" = yes; then
+AC_NEED_PROTO([
+#include <stdio.h>
+#include <string.h>],
+asnprintf)dnl
+fi
+if test "$ac_cv_func_vasnprintf" = yes; then
+AC_NEED_PROTO([
+#include <stdio.h>
+#include <string.h>],
+vasnprintf)dnl
+fi
+
+AC_BROKEN(chown copyhostent daemon err errx fchown flock fnmatch)
+AC_BROKEN(freeaddrinfo freehostent gai_strerror getaddrinfo)
+AC_BROKEN(getcwd getdtablesize gethostname getipnodebyaddr getipnodebyname)
+AC_BROKEN(geteuid getgid getegid)
+AC_BROKEN(getnameinfo getopt getusershell)
+AC_BROKEN(inet_aton inet_ntop inet_pton initgroups innetgr iruserok lstat)
+AC_BROKEN(memmove)
+AC_BROKEN(mkstemp putenv rcmd readv recvmsg sendmsg setegid setenv seteuid)
+AC_BROKEN(strcasecmp strncasecmp strdup strerror strftime)
+AC_BROKEN(strlcat strlcpy strlwr)
+AC_BROKEN(strndup strnlen strptime strsep strtok_r strupr)
+AC_BROKEN(swab unsetenv verr verrx vsyslog)
+AC_BROKEN(vwarn vwarnx warn warnx writev)
+
+AC_NEED_PROTO([#include <stdlib.h>], setenv)
+AC_NEED_PROTO([#include <stdlib.h>], unsetenv)
+AC_NEED_PROTO([#include <unistd.h>], gethostname)
+AC_NEED_PROTO([#include <unistd.h>], mkstemp)
+AC_NEED_PROTO([#include <unistd.h>], getusershell)
+
+AC_NEED_PROTO([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif],
+inet_aton)
+
+AC_FIND_FUNC_NO_LIBS(crypt, crypt)dnl
+
+dnl
+dnl libroken references crypt and dbopen
+dnl
+
+LIB_roken='$(top_builddir)/lib/roken/libroken.la $(LIB_crypt) $(LIB_dbopen)'
+AC_SUBST(LIB_roken)dnl
+
+AC_CACHE_CHECK(if realloc if broken, ac_cv_func_realloc_broken, [
+ac_cv_func_realloc_broken=no
+AC_TRY_RUN([
+#include <stddef.h>
+#include <stdlib.h>
+
+int main()
+{
+ return realloc(NULL, 17) == NULL;
+}
+],:, ac_cv_func_realloc_broken=yes, :)
+])
+if test "$ac_cv_func_realloc_broken" = yes ; then
+ AC_DEFINE(BROKEN_REALLOC, 1, [Define if realloc(NULL) doesn't work.])
+fi
+
+dnl AC_KRB_FUNC_GETCWD_BROKEN
+
+dnl
+dnl Checks for prototypes and declarations
+dnl
+
+AC_PROTO_COMPAT([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+],
+gethostbyname, struct hostent *gethostbyname(const char *))
+
+AC_PROTO_COMPAT([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+],
+gethostbyaddr, struct hostent *gethostbyaddr(const void *, size_t, int))
+
+AC_PROTO_COMPAT([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+],
+getservbyname, struct servent *getservbyname(const char *, const char *))
+
+AC_PROTO_COMPAT([
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+],
+openlog, void openlog(const char *, int, int))
+
+AC_NEED_PROTO([
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],
+crypt)
+
+AC_NEED_PROTO([
+#include <string.h>
+],
+strtok_r)
+
+AC_NEED_PROTO([
+#include <string.h>
+],
+strsep)
+
+AC_CHECK_VAR([#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif],
+h_errno)
+
+AC_CHECK_VAR([#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif],
+h_errlist)
+
+AC_CHECK_VAR([#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif],
+h_nerr)
+
+AC_CHECK_VAR([#ifdef HAVE_ERR_H
+#include <err.h>
+#endif],[__progname])
+
+AC_CHECK_DECLARATION([#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif], optarg)
+AC_CHECK_DECLARATION([#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif], optind)
+AC_CHECK_DECLARATION([#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif], opterr)
+AC_CHECK_DECLARATION([#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif], optopt)
+
+AC_CHECK_DECLARATION([#include <stdlib.h>], environ)
+
+dnl
+dnl Check for fields in struct utmp
+dnl
+
+AC_HAVE_STRUCT_FIELD(struct utmp, ut_addr, [#include <utmp.h>])
+AC_HAVE_STRUCT_FIELD(struct utmp, ut_host, [#include <utmp.h>])
+AC_HAVE_STRUCT_FIELD(struct utmp, ut_id, [#include <utmp.h>])
+AC_HAVE_STRUCT_FIELD(struct utmp, ut_pid, [#include <utmp.h>])
+AC_HAVE_STRUCT_FIELD(struct utmp, ut_type, [#include <utmp.h>])
+AC_HAVE_STRUCT_FIELD(struct utmp, ut_user, [#include <utmp.h>])
+AC_HAVE_STRUCT_FIELD(struct utmpx, ut_exit, [#include <utmpx.h>])
+AC_HAVE_STRUCT_FIELD(struct utmpx, ut_syslen, [#include <utmpx.h>])
+
+dnl
+dnl Check for fields in struct tm
+dnl
+
+AC_HAVE_STRUCT_FIELD(struct tm, tm_gmtoff, [#include <time.h>])
+AC_HAVE_STRUCT_FIELD(struct tm, tm_zone, [#include <time.h>])
+
+dnl
+dnl or do we have a variable `timezone' ?
+dnl
+
+AC_CHECK_VAR(
+[#include <time.h>],
+timezone)
+
+AC_HAVE_TYPE([sa_family_t],[#include <sys/socket.h>])
+
+AC_HAVE_TYPE([socklen_t],[#include <sys/socket.h>])
+
+AC_HAVE_TYPE([struct sockaddr], [#include <sys/socket.h>])
+
+AC_HAVE_TYPE([struct sockaddr_storage], [#include <sys/socket.h>])
+
+AC_HAVE_TYPE([struct addrinfo], [#include <netdb.h>])
+
+dnl
+dnl Check for struct winsize
+dnl
+
+AC_KRB_STRUCT_WINSIZE
+
+dnl
+dnl Check for struct spwd
+dnl
+
+AC_KRB_STRUCT_SPWD
+
+dnl
+dnl Check for sa_len in struct sockaddr
+dnl
+
+AC_HAVE_STRUCT_FIELD(struct sockaddr, sa_len, [#include <sys/types.h>
+#include <sys/socket.h>])
+
+
+AC_GROK_TYPES(int8_t int16_t int32_t int64_t)
+AC_GROK_TYPES(u_int8_t u_int16_t u_int32_t u_int64_t)
+
+dnl
+dnl Tests for editline
+dnl
+
+dnl el_init
+
+AC_FIND_FUNC_NO_LIBS(el_init, edit, [], [], [$LIB_tgetent])
+if test "$ac_cv_func_el_init" = yes ; then
+ AC_CACHE_CHECK(for four argument el_init, ac_cv_func_el_init_four,[
+ AC_TRY_COMPILE([#include <stdio.h>
+ #include <histedit.h>],
+ [el_init("", NULL, NULL, NULL);],
+ ac_cv_func_el_init_four=yes,
+ ac_cv_func_el_init_four=no)])
+ if test "$ac_cv_func_el_init_four" = yes; then
+ AC_DEFINE(HAVE_FOUR_VALUED_EL_INIT, 1, [Define if el_init takes four arguments.])
+ fi
+fi
+
+dnl readline
+
+ac_foo=no
+if test "$with_readline" = yes; then
+ :
+elif test "$ac_cv_func_readline" = yes; then
+ :
+elif test "$ac_cv_func_el_init" = yes; then
+ ac_foo=yes
+ LIB_readline="\$(top_builddir)/lib/editline/libel_compat.a $LIB_el_init"
+else
+ LIB_readline='$(top_builddir)/lib/editline/libeditline.a'
+fi
+AM_CONDITIONAL(el_compat, test "$ac_foo" = yes)
+if test "$readline_libdir"; then
+ LIB_readline="-rpath $readline_libdir $LIB_readline"
+fi
+LIB_readline="$LIB_readline \$(LIB_tgetent)"
+AC_DEFINE(HAVE_READLINE, 1,
+ [Define if you have a readline compatible library.])dnl
+
+dnl telnet muck --------------------------------------------------
+
+AC_DEFINE(AUTHENTICATION, 1,
+ [Define if you want authentication support in telnet.])dnl
+AC_DEFINE(ENCRYPTION, 1,
+ [Define if you want encryption support in telnet.])dnl
+AC_DEFINE(DES_ENCRYPTION, 1,
+ [Define if you want to use DES encryption in telnet.])dnl
+AC_DEFINE(DIAGNOSTICS, 1,
+ [Define this to enable diagnostics in telnet.])dnl
+AC_DEFINE(OLD_ENVIRON, 1,
+ [Define this to enable old environment option in telnet.])dnl
+if false; then
+AC_DEFINE(ENV_HACK, 1,
+ [Define this if you want support for broken ENV_{VAR,VAL} telnets.])
+fi
+
+# Simple test for streamspty, based on the existance of getmsg(), alas
+# this breaks on SunOS4 which have streams but BSD-like ptys
+#
+# And also something wierd has happend with dec-osf1, fallback to bsd-ptys
+
+AC_MSG_CHECKING(for streamspty)
+case "$host" in
+*-*-aix3*|*-*-sunos4*|*-*-osf*|*-*-hpux10*)
+ krb_cv_sys_streamspty=no
+ ;;
+*)
+ krb_cv_sys_streamspty="$ac_cv_func_getmsg"
+ ;;
+esac
+if test "$krb_cv_sys_streamspty" = yes; then
+ AC_DEFINE(STREAMSPTY, 1, [Define if you have streams ptys.])
+fi
+dnl AC_SUBST(STREAMSPTY)
+AC_MSG_RESULT($krb_cv_sys_streamspty)
+
+AC_AUTH_MODULES
+
+dnl This is done by AC_OUTPUT but we need the result here.
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+for i in bin lib libexec sbin; do
+ i=${i}dir
+ foo=`echo $i | tr 'xindiscernible' 'XINDISCERNIBLE'`
+ x="\$${i}"
+ eval y="$x"
+ while test "x$y" != "x$x"; do
+ x="$y"
+ eval y="$x"
+ done
+ AC_DEFINE_UNQUOTED($foo,"$x")
+done
+
+if false; then
+ # hack to shut up automake
+ LIBOBJS="$LIBOBJS make-print-version.o"
+fi
+LTLIBOBJS=`echo "$LIBOBJS" | sed 's/\.o/\.lo/g'`
+AC_SUBST(LTLIBOBJS)
+AC_OUTPUT(Makefile \
+ include/Makefile \
+ include/kadm5/Makefile \
+ lib/Makefile \
+ lib/45/Makefile \
+ lib/auth/Makefile \
+ lib/auth/afskauthlib/Makefile \
+ lib/auth/pam/Makefile \
+ lib/auth/sia/Makefile \
+ lib/asn1/Makefile \
+ lib/com_err/Makefile \
+ lib/des/Makefile \
+ lib/editline/Makefile \
+ lib/gssapi/Makefile \
+ lib/hdb/Makefile \
+ lib/kadm5/Makefile \
+ lib/kafs/Makefile \
+ lib/krb5/Makefile \
+ lib/otp/Makefile \
+ lib/roken/Makefile \
+ lib/sl/Makefile \
+ kuser/Makefile \
+ kpasswd/Makefile \
+ kadmin/Makefile \
+ admin/Makefile \
+ kdc/Makefile \
+ appl/Makefile \
+ appl/afsutil/Makefile \
+ appl/ftp/Makefile \
+ appl/ftp/common/Makefile \
+ appl/ftp/ftp/Makefile \
+ appl/ftp/ftpd/Makefile \
+ appl/kauth/Makefile \
+ appl/kx/Makefile \
+ appl/login/Makefile \
+ appl/otp/Makefile \
+ appl/popper/Makefile \
+ appl/push/Makefile \
+ appl/rsh/Makefile \
+ appl/su/Makefile \
+ appl/xnlock/Makefile \
+ appl/telnet/Makefile \
+ appl/telnet/libtelnet/Makefile \
+ appl/telnet/telnet/Makefile \
+ appl/telnet/telnetd/Makefile \
+ appl/test/Makefile \
+ appl/kf/Makefile \
+ doc/Makefile \
+)
+
+dnl
+dnl This is the release version name-number[beta]
+dnl
+HEIMDALVERSION="$PACKAGE-$VERSION"
+
+cat > include/newversion.h.in <<EOF
+char *heimdal_long_version = "@(#)\$Version: $HEIMDALVERSION by @USER@ on @HOST@ ($host) @DATE@ \$";
+char *heimdal_version = "$HEIMDALVERSION";
+EOF
+
+if test -f include/version.h && cmp -s include/newversion.h.in include/version.h.in; then
+ echo "include/version.h is unchanged"
+ rm -f include/newversion.h.in
+else
+ echo "creating include/version.h"
+ User=${USER-${LOGNAME}}
+ Host=`(hostname || uname -n || echo unknown) 2>/dev/null | sed 1q`
+ Date=`date`
+ mv -f include/newversion.h.in include/version.h.in
+ sed -e "s/@USER@/$User/" -e "s/@HOST@/$Host/" -e "s/@DATE@/$Date/" include/version.h.in > include/version.h
+fi
diff --git a/crypto/heimdal/doc/Makefile.am b/crypto/heimdal/doc/Makefile.am
new file mode 100644
index 000000000000..734bf62dae83
--- /dev/null
+++ b/crypto/heimdal/doc/Makefile.am
@@ -0,0 +1,8 @@
+# $Id: Makefile.am,v 1.6 1999/03/20 13:58:16 joda Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+AUTOMAKE_OPTIONS += no-texinfo.tex
+
+info_TEXINFOS = heimdal.texi
+heimdal_TEXINFOS = intro.texi install.texi setup.texi kerberos4.texi
diff --git a/crypto/heimdal/doc/Makefile.in b/crypto/heimdal/doc/Makefile.in
new file mode 100644
index 000000000000..710abb86f3ac
--- /dev/null
+++ b/crypto/heimdal/doc/Makefile.in
@@ -0,0 +1,620 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.6 1999/03/20 13:58:16 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies no-texinfo.tex
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+info_TEXINFOS = heimdal.texi
+heimdal_TEXINFOS = intro.texi install.texi setup.texi kerberos4.texi
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/config.h
+CONFIG_CLEAN_FILES =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+TEXI2DVI = texi2dvi
+INFO_DEPS = heimdal.info
+DVIS = heimdal.dvi
+TEXINFOS = heimdal.texi
+DIST_COMMON = $(heimdal_TEXINFOS) Makefile.am Makefile.in mdate-sh
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .dvi .et .h .info .ps .texi .texinfo .txi .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+heimdal.info: heimdal.texi $(heimdal_TEXINFOS)
+heimdal.dvi: heimdal.texi $(heimdal_TEXINFOS)
+
+
+DVIPS = dvips
+
+.texi.info:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texi.dvi:
+ TEXINPUTS=.:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.texi:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo.info:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo.dvi:
+ TEXINPUTS=.:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi.info:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.txi.dvi:
+ TEXINPUTS=.:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+.dvi.ps:
+ $(DVIPS) $< -o $@
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ d=$(srcdir); \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
+ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
+ done; \
+ else : ; fi
+
+uninstall-info:
+ $(PRE_UNINSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ ii=yes; \
+ else ii=; fi; \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ test -z "$ii" \
+ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
+ done
+ @$(NORMAL_UNINSTALL)
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ done
+
+dist-info: $(INFO_DEPS)
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ d=$(srcdir); \
+ for file in `cd $$d && eval echo $$base*`; do \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -f heimdal.aux heimdal.cp heimdal.cps heimdal.dvi heimdal.fn \
+ heimdal.fns heimdal.ky heimdal.kys heimdal.ps heimdal.log \
+ heimdal.pg heimdal.toc heimdal.tp heimdal.tps heimdal.vr \
+ heimdal.vrs heimdal.op heimdal.tr heimdal.cv heimdal.cn
+
+clean-aminfo:
+
+distclean-aminfo:
+
+maintainer-clean-aminfo:
+ cd $(srcdir) && for i in $(INFO_DEPS); do \
+ rm -f $$i; \
+ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
+ rm -f $$i-[0-9]*; \
+ fi; \
+ done
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = doc
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am: $(INFO_DEPS)
+info: info-am
+dvi-am: $(DVIS)
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-info-am install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-info
+uninstall: uninstall-am
+all-am: Makefile $(INFO_DEPS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-aminfo clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-aminfo distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-aminfo maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: install-info-am uninstall-info mostlyclean-aminfo \
+distclean-aminfo clean-aminfo maintainer-clean-aminfo tags distdir \
+info-am info dvi-am dvi check-local check check-am installcheck-am \
+installcheck install-exec-am install-exec install-data-local \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-local all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/doc/ack.texi b/crypto/heimdal/doc/ack.texi
new file mode 100644
index 000000000000..bfb03b8166ca
--- /dev/null
+++ b/crypto/heimdal/doc/ack.texi
@@ -0,0 +1,55 @@
+@node Acknowledgments, , Windows 2000 compatability, Top
+@comment node-name, next, previous, up
+@appendix Acknowledgments
+
+Eric Young wrote ``libdes''.
+
+The University of California at Berkeley initially wrote @code{telnet},
+and @code{telnetd}. The authentication and encryption code of
+@code{telnet} and @code{telnetd} was added by David Borman (then of Cray
+Research, Inc). The encryption code was removed when this was exported
+and then added back by Juha Eskelinen, @email{esc@@magic.fi}.
+
+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.
+
+Bugfixes, documentation, encouragement, and code has been contributed by:
+@table @asis
+@item Derrick J Brashear
+@email{shadow@@dementia.org}
+@item Ken Hornstein
+@email{kenh@@cmf.nrl.navy.mil}
+@item Johan Ihrén
+@email{johani@@pdc.kth.se}
+@item Love Hörnquist-Åstrand
+@email{e96_lho@@e.kth.se}
+@item Magnus Ahltorp
+@email{map@@stacken.kth.se}
+@item Mark Eichin
+@email{eichin@@cygnus.com}
+@item Marc Horowitz
+@email{marc@@cygnus.com}
+@item Luke Howard
+@email{lukeh@@xedoc.com.au}
+@item Brandon S. Allbery KF8NH
+@email{allbery@@kf8nh.apk.net}
+@item Jun-ichiro itojun Hagino
+@email{itojun@@kame.net}
+@item Daniel Kouril
+@email{kouril@@informatics.muni.cz}
+@item Åke Sandgren
+@email{ake@@cs.umu.se}
+@item Michal Vocu
+@email{michal@@karlin.mff.cuni.cz}
+@item Miroslav Ruda
+@email{ruda@@ics.muni.cz}
+@item Brian A May
+@email{bmay@@snoopy.apana.org.au}
+@item and we hope that those not mentioned here will forgive us.
+@end table
+
+All bugs were introduced by ourselves.
diff --git a/crypto/heimdal/doc/heimdal.texi b/crypto/heimdal/doc/heimdal.texi
new file mode 100644
index 000000000000..4cf1b3f5d9e1
--- /dev/null
+++ b/crypto/heimdal/doc/heimdal.texi
@@ -0,0 +1,246 @@
+\input texinfo @c -*- texinfo -*-
+@c %**start of header
+@c $Id: heimdal.texi,v 1.14 2000/01/02 04:09:00 assar Exp $
+@setfilename heimdal.info
+@settitle HEIMDAL
+@iftex
+@afourpaper
+@end iftex
+@c some sensible characters, please?
+@tex
+\input latin1.tex
+@end tex
+@setchapternewpage on
+@syncodeindex pg cp
+@c %**end of header
+
+@c not yet @include version.texi
+@set UPDATED $Date: 2000/01/02 04:09:00 $
+@set EDITION 0.0
+@set VERSION 0.2k
+
+@ifinfo
+@dircategory Heimdal
+@direntry
+* Heimdal: (heimdal). The Kerberos 5 distribution from KTH
+@end direntry
+@end ifinfo
+
+@c title page
+@titlepage
+@title Heimdal
+@subtitle Kerberos 5 from KTH
+@subtitle Edition @value{EDITION}, for version @value{VERSION}
+@subtitle 1999
+@author Johan Danielsson
+@author Assar Westerlund
+@author last updated @value{UPDATED}
+
+@def@copynext{@vskip 20pt plus 1fil@penalty-1000}
+@def@copyrightstart{}
+@def@copyrightend{}
+@page
+@copyrightstart
+Copyright (c) 1997-2000 Kungliga Tekniska Högskolan
+(Royal Institute of Technology, Stockholm, Sweden).
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+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.
+
+@copynext
+
+Copyright (C) 1995-1997 Eric Young (eay@@mincom.oz.au)
+All rights reserved.
+
+This package is an DES implementation written by Eric Young (eay@@mincom.oz.au).
+The implementation was written so as to conform with MIT's libdes.
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to. The following conditions
+apply to all code found in this distribution.
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+If this package is used in a product, Eric Young should be given attribution
+as the author of that the SSL library. This can be in the form of a textual
+message at program startup or in documentation (online or textual) provided
+with the package.
+
+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 copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by Eric Young (eay@@mincom.oz.au)
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
+
+@copynext
+
+Copyright (C) 1990 by the Massachusetts Institute of Technology
+
+Export of this software from the United States of America may
+require a specific license from the United States Government.
+It is the responsibility of any person or organization contemplating
+export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+@copynext
+
+Copyright (c) 1988, 1990, 1993
+ The Regents of the University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+
+4. 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.
+
+@copynext
+
+Copyright 1992 Simmule Turner and Rich Salz. All rights reserved.
+
+This software is not subject to any license of the American Telephone
+and Telegraph Company or of the Regents of the University of California.
+
+Permission is granted to anyone to use this software for any purpose on
+any computer system, and to alter it and redistribute it freely, subject
+to the following restrictions:
+
+1. The authors are not responsible for the consequences of use of this
+ software, no matter how awful, even if they arise from flaws in it.
+
+2. The origin of this software must not be misrepresented, either by
+ explicit claim or by omission. Since few users ever read sources,
+ credits must appear in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+ misrepresented as being the original software. Since few users
+ ever read sources, credits must appear in the documentation.
+
+4. This notice may not be removed or altered.
+
+@copyrightend
+@end titlepage
+
+@c Less filling! Tastes great!
+@iftex
+@parindent=0pt
+@global@parskip 6pt plus 1pt
+@global@chapheadingskip = 15pt plus 4pt minus 2pt
+@global@secheadingskip = 12pt plus 3pt minus 2pt
+@global@subsecheadingskip = 9pt plus 2pt minus 2pt
+@end iftex
+@ifinfo
+@paragraphindent 0
+@end ifinfo
+
+@ifinfo
+@node Top, Introduction, (dir), (dir)
+@top Heimdal
+@end ifinfo
+
+@menu
+* Introduction::
+* What is Kerberos?::
+* Building and Installing::
+* Setting up a realm::
+* Things in search for a better place::
+* Kerberos 4 issues::
+* Windows 2000 compatability::
+* Acknowledgments::
+
+@end menu
+
+@include intro.texi
+@include whatis.texi
+@include install.texi
+@include setup.texi
+@include misc.texi
+@include kerberos4.texi
+@include win2k.texi
+@include ack.texi
+
+@c @shortcontents
+@contents
+
+@bye
diff --git a/crypto/heimdal/doc/init-creds b/crypto/heimdal/doc/init-creds
new file mode 100644
index 000000000000..13667e0434e5
--- /dev/null
+++ b/crypto/heimdal/doc/init-creds
@@ -0,0 +1,374 @@
+Currently, getting an initial ticket for a user involves many function
+calls, especially when a full set of features including password
+expiration and challenge preauthentication is desired. In order to
+solve this problem, a new api is proposed.
+
+typedef struct _krb5_prompt {
+ char *prompt;
+ int hidden;
+ krb5_data *reply;
+} krb5_prompt;
+
+typedef int (*krb5_prompter_fct)(krb5_context context,
+ void *data,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[]);
+
+typedef struct _krb5_get_init_creds_opt {
+ krb5_flags flags;
+ krb5_deltat tkt_life;
+ krb5_deltat renew_life;
+ int forwardable;
+ int proxiable;
+ krb5_enctype *etype_list;
+ int etype_list_length;
+ krb5_address **address_list;
+ /* XXX the next three should not be used, as they may be
+ removed later */
+ krb5_preauthtype *preauth_list;
+ int preauth_list_length;
+ krb5_data *salt;
+} krb5_get_init_creds_opt;
+
+#define KRB5_GET_INIT_CREDS_OPT_TKT_LIFE 0x0001
+#define KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE 0x0002
+#define KRB5_GET_INIT_CREDS_OPT_FORWARDABLE 0x0004
+#define KRB5_GET_INIT_CREDS_OPT_PROXIABLE 0x0008
+#define KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST 0x0010
+#define KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST 0x0020
+#define KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST 0x0040
+#define KRB5_GET_INIT_CREDS_OPT_SALT 0x0080
+
+void krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt);
+
+void krb5_get_init_creds_opt_set_tkt_life(krb5_get_init_creds_opt *opt,
+ krb5_deltat tkt_life);
+void krb5_get_init_creds_opt_set_renew_life(krb5_get_init_creds_opt *opt,
+ krb5_deltat renew_life);
+void krb5_get_init_creds_opt_set_forwardable(krb5_get_init_creds_opt *opt,
+ int forwardable);
+void krb5_get_init_creds_opt_set_proxiable(krb5_get_init_creds_opt *opt,
+ int proxiable);
+void krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt *opt,
+ krb5_enctype *etype_list,
+ int etype_list_length);
+void krb5_get_init_creds_opt_set_address_list(krb5_get_init_creds_opt *opt,
+ krb5_address **addresses);
+void krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt,
+ krb5_preauthtype *preauth_list,
+ int preauth_list_length);
+void krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt,
+ krb5_data *salt);
+
+krb5_error_code
+krb5_get_init_creds_password(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ char *password,
+ krb5_prompter_fct prompter,
+ void *data,
+ krb5_deltat start_time,
+ char *in_tkt_service,
+ krb5_get_init_creds_opt *options);
+
+This function will attempt to acquire an initial ticket. The function
+will perform whatever tasks are necessary to do so. This may include
+changing an expired password, preauthentication.
+
+The arguments divide into two types. Some arguments are basically
+invariant and arbitrary across all initial tickets, and if not
+specified are determined by configuration or library defaults. Some
+arguments are different for each execution or application, and if not
+specified can be determined correctly from system configuration or
+environment. The former arguments are contained in a structure whose
+pointer is passed to the function. A bitmask specifies which elements
+of the structure should be used. In most cases, a NULL pointer can be
+used. The latter arguments are specified as individual arguments to
+the function.
+
+If a pointer to a credential is specified, the initial credential is
+filled in. If the caller only wishes to do a simple password check
+and will not be doing any other kerberos functions, then a NULL
+pointer may be specified, and the credential will be destroyed.
+
+If the client name is non-NULL, the initial ticket requested will be
+for that principal. Otherwise, the principal will be the the username
+specified by the USER environment variable, or if the USER environment
+variable is not set, the username corresponding to the real user id of
+the caller.
+
+If the password is non-NULL, then this string is used as the password.
+Otherwise, the prompter function will be used to prompt the user for
+the password.
+
+If a prompter function is non-NULL, it will be used if additional user
+input is required, such as if the user's password has expired and
+needs to be changed, or if input preauthentication is necessary. If
+no function is specified and input is required, then the login will
+fail.
+
+ The context argument is the same as that passed to krb5_login.
+ The data argument is passed unmodified to the prompter
+ function and is intended to be used to pass application data
+ (such as a display handle) to the prompter function.
+
+ The banner argument, if non-NULL, will indicate what sort of
+ input is expected from the user (for example, "Password has
+ expired and must be changed" or "Enter Activcard response for
+ challenge 012345678"), and should be displayed accordingly.
+
+ The num_prompts argument indicates the number of values which
+ should be prompted for. If num_prompts == 0, then the banner
+ contains an informational message which should be displayed to
+ the user.
+
+ The prompts argument contains an array describing the values
+ for which the user should be prompted. The prompt member
+ indicates the prompt for each value ("Enter new
+ password"/"Enter it again", or "Challenge response"). The
+ hidden member is nonzero if the response should not be
+ displayed back to the user. The reply member is a pointer to
+ krb5_data structure which has already been allocated. The
+ prompter should fill in the structure with the NUL-terminated
+ response from the user.
+
+ If the response data does not fit, or if any other error
+ occurs, then the prompter function should return a non-zero
+ value which will be returned by the krb5_get_init_creds
+ function. Otherwise, zero should be returned.
+
+ The library function krb5_prompter_posix() implements
+ a prompter using a posix terminal for user in. This function
+ does not use the data argument.
+
+If the start_time is zero, then the requested ticket will be valid
+beginning immediately. Otherwise, the start_time indicates how far in
+the future the ticket should be postdated.
+
+If the in_tkt_service name is non-NULL, that principal name will be
+used as the server name for the initial ticket request. The realm of
+the name specified will be ignored and will be set to the realm of the
+client name. If no in_tkt_service name is specified,
+krbtgt/CLIENT-REALM@CLIENT-REALM will be used.
+
+For the rest of arguments, a configuration or library default will be
+used if no value is specified in the options structure.
+
+If a tkt_life is specified, that will be the lifetime of the ticket.
+The library default is 10 hours; there is no configuration variable
+(there should be, but it's not there now).
+
+If a renew_life is specified and non-zero, then the RENEWABLE option
+on the ticket will be set, and the value of the argument will be the
+the renewable lifetime. The configuration variable [libdefaults]
+"renew_lifetime" is the renewable lifetime if none is passed in. The
+library default is not to set the RENEWABLE option.
+
+If forwardable is specified, the FORWARDABLE option on the ticket will
+be set if and only if forwardable is non-zero. The configuration
+variable [libdefaults] "forwardable" is used if no value is passed in.
+The option will be set if and only if the variable is "y", "yes",
+"true", "t", "1", or "on", case insensitive. The library default is
+not to set the FORWARDABLE option.
+
+If proxiable is specified, the PROXIABLE option on the ticket will be
+set if and only if proxiable is non-zero. The configuration variable
+[libdefaults] "proxiable" is used if no value is passed in. The
+option will be set if and only if the variable is "y", "yes", "true",
+"t", "1", or "on", case insensitive. The library default is not to
+set the PROXIABLE option.
+
+If etype_list is specified, it will be used as the list of desired
+encryption algorithms in the request. The configuration variable
+[libdefaults] "default_tkt_enctypes" is used if no value is passed in.
+The library default is "des-cbc-md5 des-cbc-crc".
+
+If address_list is specified, it will be used as the list of addresses
+for which the ticket will be valid. The library default is to use all
+local non-loopback addresses. There is no configuration variable.
+
+If preauth_list is specified, it names preauth data types which will
+be included in the request. The library default is to interact with
+the kdc to determine the required preauth types. There is no
+configuration variable.
+
+If salt is specified, it specifies the salt which will be used when
+converting the password to a key. The library default is to interact
+with the kdc to determine the correct salt. There is no configuration
+variable.
+
+================================================================
+
+typedef struct _krb5_verify_init_creds_opt {
+ krb5_flags flags;
+ int ap_req_nofail;
+} krb5_verify_init_creds_opt;
+
+#define KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL 0x0001
+
+void krb5_verify_init_creds_opt_init(krb5_init_creds_opt *options);
+void krb5_verify_init_creds_opt_set_ap_req_nofail(krb5_init_creds_opt *options,
+ int ap_req_nofail);
+
+krb5_error_code
+krb5_verify_init_creds(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal ap_req_server,
+ krb5_keytab ap_req_keytab,
+ krb5_ccache *ccache,
+ krb5_verify_init_creds_opt *options);
+
+This function will use the initial ticket in creds to make an AP_REQ
+and verify it to insure that the AS_REP has not been spoofed.
+
+If the ap_req_server name is non-NULL, then this service name will be
+used for the AP_REQ; otherwise, the default host key
+(host/hostname.domain@LOCAL-REALM) will be used.
+
+If ap_req_keytab is non-NULL, the service key for the verification
+will be read from that keytab; otherwise, the service key will be read
+from the default keytab.
+
+If the service of the ticket in creds is the same as the service name
+for the AP_REQ, then this ticket will be used directly. If the ticket
+is a tgt, then it will be used to obtain credentials for the service.
+Otherwise, the verification will fail, and return an error.
+
+Other failures of the AP_REQ verification may or may not be considered
+errors, as described below.
+
+If a pointer to a credential cache handle is specified, and the handle
+is NULL, a credential cache handle referring to all credentials
+obtained in the course of verifying the user will be returned. In
+order to avoid potential setuid race conditions and other problems
+related to file system access, this handle will refer to a memory
+credential cache. If the handle is non-NULL, then the credentials
+will be added to the existing ccache. If the caller only wishes to
+verify the password and will not be doing any other kerberos
+functions, then a NULL pointer may be specified, and the credentials
+will be deleted before the function returns.
+
+If ap_req_nofail is specified, then failures of the AP_REQ
+verification are considered errors if and only if ap_req_nofail is
+non-zero.
+
+Whether or not AP_REQ validation is performed and what failures mean
+depends on these inputs:
+
+ A) The appropriate keytab exists and contains the named key.
+
+ B) An AP_REQ request to the kdc succeeds, and the resulting AP_REQ
+can be decrypted and verified.
+
+ C) The administrator has specified in a configuration file that
+AP_REQ validation must succeed. This is basically a paranoid bit, and
+can be overridden by the application based on a command line flag or
+other application-specific info. This flag is especially useful if
+the admin is concerned that DNS might be spoofed while determining the
+host/FQDN name. The configuration variable [libdefaults]
+"verify_ap_req_nofail" is used if no value is passed in. The library
+default is not to set this option.
+
+Initial ticket verification will succeed if and only if:
+
+ - A && B or
+ - !A && !C
+
+================================================================
+
+For illustrative purposes, here's the invocations I expect some
+programs will use. Of course, error checking needs to be added.
+
+kinit:
+
+ /* Fill in client from the command line || existing ccache, and,
+ start_time, and options.{tkt_life,renew_life,forwardable,proxiable}
+ from the command line. Some or all may remain unset. */
+
+ krb5_get_init_creds(context, &creds, client,
+ krb5_initial_prompter_posix, NULL,
+ start_time, NULL, &options);
+ krb5_cc_store_cred(context, ccache, &creds);
+ krb5_free_cred_contents(context, &creds);
+
+login:
+
+ krb5_get_init_creds(context, &creds, client,
+ krb5_initial_prompter_posix, NULL,
+ 0, NULL, NULL);
+ krb5_verify_init_creds(context, &creds, NULL, NULL, &vcc, NULL);
+ /* setuid */
+ krb5_cc_store_cred(context, ccache, &creds);
+ krb5_cc_copy(context, vcc, ccache);
+ krb5_free_cred_contents(context, &creds);
+ krb5_cc_destroy(context, vcc);
+
+xdm:
+
+ krb5_get_initial_creds(context, &creds, client,
+ krb5_initial_prompter_xt, (void *) &xtstuff,
+ 0, NULL, NULL);
+ krb5_verify_init_creds(context, &creds, NULL, NULL, &vcc, NULL);
+ /* setuid */
+ krb5_cc_store_cred(context, ccache, &creds);
+ krb5_free_cred_contents(context, &creds);
+ krb5_cc_copy(context, vcc, ccache);
+ krb5_cc_destroy(context, vcc);
+
+passwd:
+
+ krb5_init_creds_opt_init(&options);
+ krb5_init_creds_opt_set_tkt_life = 300;
+ krb5_get_initial_creds(context, &creds, client,
+ krb5_initial_prompter_posix, NULL,
+ 0, "kadmin/changepw", &options);
+ /* change password */
+ krb5_free_cred_contents(context, &creds);
+
+pop3d (simple password validator when no user interation possible):
+
+ krb5_get_initial_creds(context, &creds, client,
+ NULL, NULL, 0, NULL, NULL);
+ krb5_verify_init_creds(context, &creds, NULL, NULL, &vcc, NULL);
+ krb5_cc_destroy(context, vcc);
+
+================================================================
+
+password expiration has a subtlety. When a password expires and is
+changed, there is a delay between when the master gets the new key
+(immediately), and the slaves (propogation interval). So, when
+getting an in_tkt, if the password is expired, the request should be
+reissued to the master (this kind of sucks if you have SAM, oh well).
+If this says expired, too, then the password should be changed, and
+then the initial ticket request should be issued to the master again.
+If the master times out, then a message that the password has expired
+and cannot be changed due to the master being unreachable should be
+displayed.
+
+================================================================
+
+get_init_creds reads config stuff from:
+
+[libdefaults]
+ varname1 = defvalue
+ REALM = {
+ varname1 = value
+ varname2 = value
+ }
+
+typedef struct _krb5_get_init_creds_opt {
+ krb5_flags flags;
+ krb5_deltat tkt_life; /* varname = "ticket_lifetime" */
+ krb5_deltat renew_life; /* varname = "renew_lifetime" */
+ int forwardable; /* varname = "forwardable" */
+ int proxiable; /* varname = "proxiable" */
+ krb5_enctype *etype_list; /* varname = "default_tkt_enctypes" */
+ int etype_list_length;
+ krb5_address **address_list; /* no varname */
+ krb5_preauthtype *preauth_list; /* no varname */
+ int preauth_list_length;
+ krb5_data *salt;
+} krb5_get_init_creds_opt;
+
+
diff --git a/crypto/heimdal/doc/install.texi b/crypto/heimdal/doc/install.texi
new file mode 100644
index 000000000000..5d195a661373
--- /dev/null
+++ b/crypto/heimdal/doc/install.texi
@@ -0,0 +1,86 @@
+@node Building and Installing, Setting up a realm, What is Kerberos?, Top
+@comment node-name, next, previous, up
+@chapter Building and Installing
+
+Heimdal uses GNU Autoconf to configure for specific hosts, and GNU
+Automake to manage makefiles. If this is new to you, the short
+instruction is to run the @code{configure} script in the top level
+directory, and when that finishes @code{make}.
+
+If you want to build the distribution in a different directory from the
+source directory, you will need a make that implements VPATH correctly,
+such as GNU make.
+
+You will need to build the distribution:
+
+@itemize @bullet
+@item
+A compiler that supports a ``loose'' ANSI C mode, such as @code{gcc}.
+@item
+lex or flex
+@item
+awk
+@item
+yacc or bison
+@item
+a socket library
+@item
+NDBM or Berkeley DB for building the server side.
+@end itemize
+
+When everything is built, you can install by doing @kbd{make
+install}. The default location for installation is @file{/usr/heimdal},
+but this can be changed by running @code{configure} with
+@samp{--prefix=/some/other/place}.
+
+If you need to change the default behavior, configure understands the
+following options:
+
+@table @asis
+@item @kbd{--without-berkeley-db}
+DB is preferred before NDBM, but if you for some reason want to use NDBM
+instead, you can use this option.
+
+@item @kbd{--with-krb4=@file{dir}}
+Gives the location of Kerberos 4 libraries and headers. This enables
+Kerberos 4 support in the applications (telnet, rsh, popper, etc) and
+the KDC. It is automatically check for in @file{/usr/athena}. If you
+keep libraries and headers in different places, you can instead give the
+path to each with the @kbd{--with-krb4-lib=@file{dir}}, and
+@kbd{--with-krb4-include=@file{dir}} options.
+
+You will need a fairly recent version of our Kerberos 4 distribution for
+@code{rshd} and @code{popper} to support version 4 clients.
+
+@item @kbd{--enable-kaserver}
+Enables experimental kaserver support in the KDC. This is the protocol
+used by the ``KDC'' in AFS. Requires Kerberos 4 support.
+
+@item @kbd{--enable-kaserver-db}
+Enables experimental support for reading kaserver databases in hprop.
+This is useful when migrating from a kaserver to a Heimdal KDC.
+
+@item @kbd{--disable-otp}
+By default some of the application programs will build with support for
+one-time passwords (OTP). Use this option to disable that support.
+
+@item @kbd{--enable-osfc2}
+Enable some C2 support for OSF/Digital Unix/Tru64. Use this option if
+you are running your OSF operating system in C2 mode.
+
+@item @kbd{--with-readline=@file{dir}}
+Gives the path for the GNU Readline library, which will be used in some
+programs. If no readline library is found, the (simpler) editline
+library will be used instead.
+
+@item @kbd{--with-hesiod=@file{dir}}
+Enables hesiod support in push.
+
+@item @kbd{--enable-netinfo}
+Add support for using netinfo to lookup configuration information.
+Probably only useful (and working) on NextStep/Mac OS X.
+
+@item @kbd{--without-ipv6}
+Disable the IPv6 support.
+
+@end table
diff --git a/crypto/heimdal/doc/intro.texi b/crypto/heimdal/doc/intro.texi
new file mode 100644
index 000000000000..518aada8aa3a
--- /dev/null
+++ b/crypto/heimdal/doc/intro.texi
@@ -0,0 +1,93 @@
+@node Introduction, What is Kerberos?, Top, Top
+@c @node Introduction, What is Kerberos?, Top, Top
+@comment node-name, next, previous, up
+@chapter Introduction
+
+@heading What is Heimdal?
+
+Heimdal is a free implementation of Kerberos 5. The goals are to:
+
+@itemize @bullet
+@item
+have an implementation that can be freely used by anyone
+@item
+be protocol compatible with existing implementations and, if not in
+conflict, with RFC 1510 (and any future updated RFC)
+@item
+be reasonably compatible with the M.I.T Kerberos V5 API
+@item
+have support for Kerberos V5 over GSS-API (RFC1964)
+@item
+include the most important and useful application programs (rsh, telnet,
+popper, etc.)
+@item
+include enough backwards compatibility with Kerberos V4
+@end itemize
+
+@heading Status
+
+Heimdal has the following features (this does not mean any of this
+works):
+
+@itemize @bullet
+@item
+a stub generator and a library to encode/decode/whatever ASN.1/DER
+stuff
+@item
+a @code{libkrb5} library that should be possible to get to work with
+simple applications
+@item
+a GSS-API library that should have all the important functions for
+building applications
+@item
+Eric Young's @file{libdes}
+@item
+@file{kinit}, @file{klist}, @file{kdestroy}
+@item
+@file{telnet}, @file{telnetd}
+@item
+@file{rsh}, @file{rshd}
+@item
+@file{popper}, @file{push} (a movemail equivalent)
+@item
+@file{ftp}, and @file{ftpd}
+@item
+a library @file{libkafs} for authenticating to AFS and a program
+@file{afslog} that uses it
+@item
+some simple test programs
+@item
+a KDC that supports most things; optionally, it may also support
+Kerberos V4 and kaserver,
+@item
+simple programs for distributing databases between a KDC master and
+slaves
+@item
+a password changing daemon @file{kpasswdd}, library functions for
+changing passwords and a simple client
+@item
+some kind of administration system
+@item
+Kerberos V4 support in many of the applications.
+@end itemize
+
+@heading Bug reports
+
+If you find bugs in this software, make sure it is a genuine bug and not
+just a part of the code that isn't implemented.
+
+Bug reports should be sent to @email{heimdal-bugs@@pdc.kth.se}. Please
+include information on what machine and operating system (including
+version) you are running, what you are trying to do, what happens, what
+you think should have happened, an example for us to repeat, the output
+you get when trying the example, and a patch for the problem if you have
+one. Please make any patches with @code{diff -u} or @code{diff -c}.
+
+Suggestions, comments and other non bug reports are also welcome.
+
+@heading Mailing list
+
+There are two mailing lists with talk about
+Heimdal. @email{heimdal-announce@@sics.se} is a low-volume announcement
+list, while @email{heimdal-discuss@@sics.se} is for general discussion.
+Send a message to @email{majordomo@@sics.se} to subscribe.
diff --git a/crypto/heimdal/doc/kerberos4.texi b/crypto/heimdal/doc/kerberos4.texi
new file mode 100644
index 000000000000..93671f9d118a
--- /dev/null
+++ b/crypto/heimdal/doc/kerberos4.texi
@@ -0,0 +1,183 @@
+@node Kerberos 4 issues, Windows 2000 compatability, Things in search for a better place, Top
+@comment node-name, next, previous, up
+@chapter Kerberos 4 issues
+
+If compiled with version 4 support, the KDC can serve requests from a
+Kerberos 4 client. There are a few things you must do for this to work.
+
+@menu
+* Principal conversion issues::
+* Converting a version 4 database::
+@end menu
+
+@node Principal conversion issues, Converting a version 4 database, Kerberos 4 issues, Kerberos 4 issues
+@section Principal conversion issues
+
+First, Kerberos 4 and Kerberos 5 principals are different. A version 4
+principal consists of a name, an instance, and a realm. A version 5
+principal has one or more components, and a realm (the terms ``name''
+and ``instance'' are still used, for the first and second component,
+respectively). Also, in some cases the name of a version 4 principal
+differs from the first component of the corresponding version 5
+principal. One notable example is the ``host'' type principals, where
+the version 4 name is @samp{rcmd} (for ``remote command''), and the
+version 5 name is @samp{host}. For the class of principals that has a
+hostname as instance, there is an other major difference, Kerberos 4
+uses only the first component of the hostname, whereas Kerberos 5 uses
+the fully qualified hostname.
+
+Because of this it can be hard or impossible to correctly convert a
+version 4 principal to a version 5 principal @footnote{the other way is
+not always trivial either, but usually easier}. The biggest problem is
+to know if the conversion resulted in a valid principal. To give an
+example, suppose you want to convert the principal @samp{rcmd.foo}.
+
+The @samp{rcmd} name suggests that the instance is a hostname (even if
+there are exceptions to this rule). To correctly convert the instance
+@samp{foo} to a hostname, you have to know which host it is referring
+to. You can to this by either guessing (from the realm) which domain
+name to append, or you have to have a list of possible hostnames. In the
+simplest cases you can cover most principals with the first rule. If you
+have several domains sharing a single realm this will not usually
+work. If the exceptions are few you can probably come by with a lookup
+table for the exceptions.
+
+In a complex scenario you will need some kind of host lookup mechanism.
+Using DNS for this is tempting, but DNS is error prone, slow and unsafe
+@footnote{at least until secure DNS is commonly available}.
+
+Fortunately, the KDC has a trump on hand: it can easily tell if a
+principal exists in the database. The KDC will use
+@code{krb5_425_conv_principal_ext} to convert principals when handling
+to version 4 requests.
+
+@node Converting a version 4 database, , Principal conversion issues, Kerberos 4 issues
+@section Converting a version 4 database
+
+If you want to convert an existing version 4 database, the principal
+conversion issue arises too.
+
+If you decide to convert your database once and for all, you will only
+have to do this conversion once. It is also possible to run a version 5
+KDC as a slave to a version 4 KDC. In this case this conversion will
+happen every time the database is propagated. When doing this
+conversion, there are a few things to look out for. If you have stale
+entries in the database, these entries will not be converted. This might
+be because these principals are not used anymore, or it might be just
+because the principal couldn't be converted.
+
+You might also see problems with a many-to-one mapping of
+principals. For instance, if you are using DNS lookups and you have two
+principals @samp{rcmd.foo} and @samp{rcmd.bar}, where `foo' is a CNAME
+for `bar', the resulting principals will be the same. Since the
+conversion function can't tell which is correct, these conflicts will
+have to be resolved manually.
+
+@subsection Conversion example
+
+Given the following set of hosts and services:
+
+@example
+foo.se rcmd
+mail.foo.se rcmd, pop
+ftp.bar.se rcmd, ftp
+@end example
+
+you have a database that consists of the following principals:
+
+@samp{rcmd.foo}, @samp{rcmd.mail}, @samp{pop.mail}, @samp{rcmd.ftp}, and
+@samp{ftp.ftp}.
+
+lets say you also got these extra principals: @samp{rcmd.gone},
+@samp{rcmd.old-mail}, where @samp{gone.foo.se} was a machine that has
+now passed away, and @samp{old-mail.foo.se} was an old mail machine that
+is now a CNAME for @samp{mail.foo.se}.
+
+When you convert this database you want the following conversions to be
+done:
+@example
+rcmd.foo host/foo.se
+rcmd.mail host/mail.foo.se
+pop.mail pop/mail.foo.se
+rcmd.ftp host/ftp.bar.se
+ftp.ftp ftp/ftp.bar.se
+rcmd.gone @i{removed}
+rcmd.old-mail @i{removed}
+@end example
+
+A @file{krb5.conf} that does this looks like:
+
+@example
+[realms]
+ FOO.SE = @{
+ v4_name_convert = @{
+ host = @{
+ ftp = ftp
+ pop = pop
+ rcmd = host
+ @}
+ @}
+ v4_instance_convert = @{
+ foo = foo.se
+ ftp = ftp.bar.se
+ @}
+ default_domain = foo.se
+ @}
+@end example
+
+The @samp{v4_name_convert} section says which names should be considered
+having an instance consisting of a hostname, and it also says how the
+names should be converted (for instance @samp{rcmd} should be converted
+to @samp{host}). The @samp{v4_instance_convert} section says how a
+hostname should be qualified (this is just a hosts-file in
+disguise). Host-instances that aren't covered by
+@samp{v4_instance_convert} are qualified by appending the contents of
+the @samp{default_domain}.
+
+Actually, this example doesn't work. Or rather, it works to well. Since
+it has no way of knowing which hostnames are valid and which are not, it
+will happily convert @samp{rcmd.gone} to @samp{host/gone.foo.se}. This
+isn't a big problem, but if you have run your kerberos realm for a few
+years, chances are big that you have quite a few `junk' principals.
+
+If you don't want this you can remove the @samp{default_domain}
+statement, but then you will have to add entries for @emph{all} your hosts
+in the @samp{v4_instance_convert} section.
+
+Instead of doing this you can use DNS to convert instances. This is not
+a solution without problems, but it is probably easier than adding lots
+of static host entries.
+
+To enable DNS lookup you should turn on @samp{v4_instance_resolve} in
+the @samp{[libdefaults]} section.
+
+@subsection Converting a database
+
+The database conversion is done with @samp{hprop}. Assuming that you
+have the @samp{kadmin/hprop} key in the keytab @file{hprop.keytab}, you
+can run this command to propagate the database to the machine called
+@samp{slave-server} (which should be running a @samp{hpropd}).
+
+@example
+hprop -4 -E -k hprop.keytab slave-server
+@end example
+
+@section Version 4 Kadmin
+
+@samp{kadmind} can act as a version 4 kadmind, and you can do most
+operations, but with some restrictions (since the version 4 kadmin
+protocol is, lets say, very ad hoc.) One example is that it only passes
+des keys when creating principals and changing passwords (modern kpasswd
+clients do send the password, so it's possible to to password quality
+checks). Because of this you can only create principals with des keys,
+and you can't set any flags or do any other fancy stuff.
+
+To get this to work, you have to create a @samp{changepw/kerberos}
+principal (if you are converting a version 4 data you should have this
+principal), and add it to the keytab the @samp{kadmind} is using. You
+then have to add another entry to inetd (since version 4 uses port 751,
+not 749).
+
+@emph{And then there are a many more things you can do; more on this in
+a later version of this manual. Until then, UTSL.}
+
diff --git a/crypto/heimdal/doc/latin1.tex b/crypto/heimdal/doc/latin1.tex
new file mode 100644
index 000000000000..e683dd271dc1
--- /dev/null
+++ b/crypto/heimdal/doc/latin1.tex
@@ -0,0 +1,95 @@
+% ISO Latin 1 (ISO 8859/1) encoding for Computer Modern fonts.
+% Jan Michael Rynning <jmr@nada.kth.se> 1990-10-12
+\def\inmathmode#1{\relax\ifmmode#1\else$#1$\fi}
+\global\catcode`\^^a0=\active \global\let^^a0=~ % no-break space
+\global\catcode`\^^a1=\active \global\def^^a1{!`} % inverted exclamation mark
+\global\catcode`\^^a2=\active \global\def^^a2{{\rm\rlap/c}} % cent sign
+\global\catcode`\^^a3=\active \global\def^^a3{{\it\$}} % pound sign
+% currency sign, yen sign, broken bar
+\global\catcode`\^^a7=\active \global\let^^a7=\S % section sign
+\global\catcode`\^^a8=\active \global\def^^a8{\"{}} % diaeresis
+\global\catcode`\^^a9=\active \global\let^^a9=\copyright % copyright sign
+% feminine ordinal indicator, left angle quotation mark
+\global\catcode`\^^ac=\active \global\def^^ac{\inmathmode\neg}% not sign
+\global\catcode`\^^ad=\active \global\let^^ad=\- % soft hyphen
+% registered trade mark sign
+\global\catcode`\^^af=\active \global\def^^af{\={}} % macron
+% ...
+\global\catcode`\^^b1=\active \global\def^^b1{\inmathmode\pm} % plus minus
+\global\catcode`\^^b2=\active \global\def^^b2{\inmathmode{{^2}}}
+\global\catcode`\^^b3=\active \global\def^^b3{\inmathmode{{^3}}}
+\global\catcode`\^^b4=\active \global\def^^b4{\'{}} % acute accent
+\global\catcode`\^^b5=\active \global\def^^b5{\inmathmode\mu} % mu
+\global\catcode`\^^b6=\active \global\let^^b6=\P % pilcroy
+\global\catcode`\^^b7=\active \global\def^^b7{\inmathmode{{\cdot}}}
+\global\catcode`\^^b8=\active \global\def^^b8{\c{}} % cedilla
+\global\catcode`\^^b9=\active \global\def^^b9{\inmathmode{{^1}}}
+% ...
+\global\catcode`\^^bc=\active \global\def^^bc{\inmathmode{{1\over4}}}
+\global\catcode`\^^bd=\active \global\def^^bd{\inmathmode{{1\over2}}}
+\global\catcode`\^^be=\active \global\def^^be{\inmathmode{{3\over4}}}
+\global\catcode`\^^bf=\active \global\def^^bf{?`} % inverted question mark
+\global\catcode`\^^c0=\active \global\def^^c0{\`A}
+\global\catcode`\^^c1=\active \global\def^^c1{\'A}
+\global\catcode`\^^c2=\active \global\def^^c2{\^A}
+\global\catcode`\^^c3=\active \global\def^^c3{\~A}
+\global\catcode`\^^c4=\active \global\def^^c4{\"A} % capital a with diaeresis
+\global\catcode`\^^c5=\active \global\let^^c5=\AA % capital a with ring above
+\global\catcode`\^^c6=\active \global\let^^c6=\AE
+\global\catcode`\^^c7=\active \global\def^^c7{\c C}
+\global\catcode`\^^c8=\active \global\def^^c8{\`E}
+\global\catcode`\^^c9=\active \global\def^^c9{\'E}
+\global\catcode`\^^ca=\active \global\def^^ca{\^E}
+\global\catcode`\^^cb=\active \global\def^^cb{\"E}
+\global\catcode`\^^cc=\active \global\def^^cc{\`I}
+\global\catcode`\^^cd=\active \global\def^^cd{\'I}
+\global\catcode`\^^ce=\active \global\def^^ce{\^I}
+\global\catcode`\^^cf=\active \global\def^^cf{\"I}
+% capital eth
+\global\catcode`\^^d1=\active \global\def^^d1{\~N}
+\global\catcode`\^^d2=\active \global\def^^d2{\`O}
+\global\catcode`\^^d3=\active \global\def^^d3{\'O}
+\global\catcode`\^^d4=\active \global\def^^d4{\^O}
+\global\catcode`\^^d5=\active \global\def^^d5{\~O}
+\global\catcode`\^^d6=\active \global\def^^d6{\"O} % capital o with diaeresis
+\global\catcode`\^^d7=\active \global\def^^d7{\inmathmode\times}% multiplication sign
+\global\catcode`\^^d8=\active \global\let^^d8=\O
+\global\catcode`\^^d9=\active \global\def^^d9{\`U}
+\global\catcode`\^^da=\active \global\def^^da{\'U}
+\global\catcode`\^^db=\active \global\def^^db{\^U}
+\global\catcode`\^^dc=\active \global\def^^dc{\"U}
+\global\catcode`\^^dd=\active \global\def^^dd{\'Y}
+% capital thorn
+\global\catcode`\^^df=\active \global\def^^df{\ss}
+\global\catcode`\^^e0=\active \global\def^^e0{\`a}
+\global\catcode`\^^e1=\active \global\def^^e1{\'a}
+\global\catcode`\^^e2=\active \global\def^^e2{\^a}
+\global\catcode`\^^e3=\active \global\def^^e3{\~a}
+\global\catcode`\^^e4=\active \global\def^^e4{\"a} % small a with diaeresis
+\global\catcode`\^^e5=\active \global\let^^e5=\aa % small a with ring above
+\global\catcode`\^^e6=\active \global\let^^e6=\ae
+\global\catcode`\^^e7=\active \global\def^^e7{\c c}
+\global\catcode`\^^e8=\active \global\def^^e8{\`e}
+\global\catcode`\^^e9=\active \global\def^^e9{\'e}
+\global\catcode`\^^ea=\active \global\def^^ea{\^e}
+\global\catcode`\^^eb=\active \global\def^^eb{\"e}
+\global\catcode`\^^ec=\active \global\def^^ec{\`\i}
+\global\catcode`\^^ed=\active \global\def^^ed{\'\i}
+\global\catcode`\^^ee=\active \global\def^^ee{\^\i}
+\global\catcode`\^^ef=\active \global\def^^ef{\"\i}
+% small eth
+\global\catcode`\^^f1=\active \global\def^^f1{\~n}
+\global\catcode`\^^f2=\active \global\def^^f2{\`o}
+\global\catcode`\^^f3=\active \global\def^^f3{\'o}
+\global\catcode`\^^f4=\active \global\def^^f4{\^o}
+\global\catcode`\^^f5=\active \global\def^^f5{\~o}
+\global\catcode`\^^f6=\active \global\def^^f6{\"o} % small o with diaeresis
+\global\catcode`\^^f7=\active \global\def^^f7{\inmathmode\div}% division sign
+\global\catcode`\^^f8=\active \global\let^^f8=\o
+\global\catcode`\^^f9=\active \global\def^^f9{\`u}
+\global\catcode`\^^fa=\active \global\def^^fa{\'u}
+\global\catcode`\^^fb=\active \global\def^^fb{\^u}
+\global\catcode`\^^fc=\active \global\def^^fc{\"u}
+\global\catcode`\^^fd=\active \global\def^^fd{\'y}
+% capital thorn
+\global\catcode`\^^ff=\active \global\def^^ff{\"y}
diff --git a/crypto/heimdal/doc/layman.asc b/crypto/heimdal/doc/layman.asc
new file mode 100644
index 000000000000..d4fbe64be99d
--- /dev/null
+++ b/crypto/heimdal/doc/layman.asc
@@ -0,0 +1,1855 @@
+A Layman's Guide to a Subset of ASN.1, BER, and DER
+
+An RSA Laboratories Technical Note
+Burton S. Kaliski Jr.
+Revised November 1, 1993
+
+
+Supersedes June 3, 1991 version, which was also published as
+NIST/OSI Implementors' Workshop document SEC-SIG-91-17.
+PKCS documents are available by electronic mail to
+<pkcs@rsa.com>.
+
+Copyright (C) 1991-1993 RSA Laboratories, a division of RSA
+Data Security, Inc. License to copy this document is granted
+provided that it is identified as "RSA Data Security, Inc.
+Public-Key Cryptography Standards (PKCS)" in all material
+mentioning or referencing this document.
+003-903015-110-000-000
+
+
+Abstract. This note gives a layman's introduction to a
+subset of OSI's Abstract Syntax Notation One (ASN.1), Basic
+Encoding Rules (BER), and Distinguished Encoding Rules
+(DER). The particular purpose of this note is to provide
+background material sufficient for understanding and
+implementing the PKCS family of standards.
+
+
+1. Introduction
+
+It is a generally accepted design principle that abstraction
+is a key to managing software development. With abstraction,
+a designer can specify a part of a system without concern
+for how the part is actually implemented or represented.
+Such a practice leaves the implementation open; it
+simplifies the specification; and it makes it possible to
+state "axioms" about the part that can be proved when the
+part is implemented, and assumed when the part is employed
+in another, higher-level part. Abstraction is the hallmark
+of most modern software specifications.
+
+One of the most complex systems today, and one that also
+involves a great deal of abstraction, is Open Systems
+Interconnection (OSI, described in X.200). OSI is an
+internationally standardized architecture that governs the
+interconnection of computers from the physical layer up to
+the user application layer. Objects at higher layers are
+defined abstractly and intended to be implemented with
+objects at lower layers. For instance, a service at one
+layer may require transfer of certain abstract objects
+between computers; a lower layer may provide transfer
+services for strings of ones and zeroes, using encoding
+rules to transform the abstract objects into such strings.
+OSI is called an open system because it supports many
+different implementations of the services at each layer.
+
+OSI's method of specifying abstract objects is called ASN.1
+(Abstract Syntax Notation One, defined in X.208), and one
+set of rules for representing such objects as strings of
+ones and zeros is called the BER (Basic Encoding Rules,
+defined in X.209). ASN.1 is a flexible notation that allows
+one to define a variety data types, from simple types such
+as integers and bit strings to structured types such as sets
+and sequences, as well as complex types defined in terms of
+others. BER describes how to represent or encode values of
+each ASN.1 type as a string of eight-bit octets. There is
+generally more than one way to BER-encode a given value.
+Another set of rules, called the Distinguished Encoding
+Rules (DER), which is a subset of BER, gives a unique
+encoding to each ASN.1 value.
+
+The purpose of this note is to describe a subset of ASN.1,
+BER and DER sufficient to understand and implement one OSI-
+based application, RSA Data Security, Inc.'s Public-Key
+Cryptography Standards. The features described include an
+overview of ASN.1, BER, and DER and an abridged list of
+ASN.1 types and their BER and DER encodings. Sections 2-4
+give an overview of ASN.1, BER, and DER, in that order.
+Section 5 lists some ASN.1 types, giving their notation,
+specific encoding rules, examples, and comments about their
+application to PKCS. Section 6 concludes with an example,
+X.500 distinguished names.
+
+Advanced features of ASN.1, such as macros, are not
+described in this note, as they are not needed to implement
+PKCS. For information on the other features, and for more
+detail generally, the reader is referred to CCITT
+Recommendations X.208 and X.209, which define ASN.1 and BER.
+
+Terminology and notation. In this note, an octet is an eight-
+bit unsigned integer. Bit 8 of the octet is the most
+significant and bit 1 is the least significant.
+
+The following meta-syntax is used for in describing ASN.1
+notation:
+
+ BIT monospace denotes literal characters in the type
+ and value notation; in examples, it generally
+ denotes an octet value in hexadecimal
+
+ n1 bold italics denotes a variable
+
+ [] bold square brackets indicate that a term is
+ optional
+
+ {} bold braces group related terms
+
+ | bold vertical bar delimits alternatives with a
+ group
+
+ ... bold ellipsis indicates repeated occurrences
+
+ = bold equals sign expresses terms as subterms
+
+
+2. Abstract Syntax Notation One
+
+Abstract Syntax Notation One, abbreviated ASN.1, is a
+notation for describing abstract types and values.
+
+In ASN.1, a type is a set of values. For some types, there
+are a finite number of values, and for other types there are
+an infinite number. A value of a given ASN.1 type is an
+element of the type's set. ASN.1 has four kinds of type:
+simple types, which are "atomic" and have no components;
+structured types, which have components; tagged types, which
+are derived from other types; and other types, which include
+the CHOICE type and the ANY type. Types and values can be
+given names with the ASN.1 assignment operator (::=) , and
+those names can be used in defining other types and values.
+
+Every ASN.1 type other than CHOICE and ANY has a tag, which
+consists of a class and a nonnegative tag number. ASN.1
+types are abstractly the same if and only if their tag
+numbers are the same. In other words, the name of an ASN.1
+type does not affect its abstract meaning, only the tag
+does. There are four classes of tag:
+
+ Universal, for types whose meaning is the same in all
+ applications; these types are only defined in
+ X.208.
+
+ Application, for types whose meaning is specific to an
+ application, such as X.500 directory services;
+ types in two different applications may have the
+ same application-specific tag and different
+ meanings.
+
+ Private, for types whose meaning is specific to a given
+ enterprise.
+
+ Context-specific, for types whose meaning is specific
+ to a given structured type; context-specific tags
+ are used to distinguish between component types
+ with the same underlying tag within the context of
+ a given structured type, and component types in
+ two different structured types may have the same
+ tag and different meanings.
+
+The types with universal tags are defined in X.208, which
+also gives the types' universal tag numbers. Types with
+other tags are defined in many places, and are always
+obtained by implicit or explicit tagging (see Section 2.3).
+Table 1 lists some ASN.1 types and their universal-class
+tags.
+
+ Type Tag number Tag number
+ (decimal) (hexadecimal)
+ INTEGER 2 02
+ BIT STRING 3 03
+ OCTET STRING 4 04
+ NULL 5 05
+ OBJECT IDENTIFIER 6 06
+ SEQUENCE and SEQUENCE OF 16 10
+ SET and SET OF 17 11
+ PrintableString 19 13
+ T61String 20 14
+ IA5String 22 16
+ UTCTime 23 17
+
+ Table 1. Some types and their universal-class tags.
+
+ASN.1 types and values are expressed in a flexible,
+programming-language-like notation, with the following
+special rules:
+
+ o Layout is not significant; multiple spaces and
+ line breaks can be considered as a single space.
+
+ o Comments are delimited by pairs of hyphens (--),
+ or a pair of hyphens and a line break.
+
+ o Identifiers (names of values and fields) and type
+ references (names of types) consist of upper- and
+ lower-case letters, digits, hyphens, and spaces;
+ identifiers begin with lower-case letters; type
+ references begin with upper-case letters.
+
+The following four subsections give an overview of simple
+types, structured types, implicitly and explicitly tagged
+types, and other types. Section 5 describes specific types
+in more detail.
+
+
+2.1 Simple types
+
+Simple types are those not consisting of components; they
+are the "atomic" types. ASN.1 defines several; the types
+that are relevant to the PKCS standards are the following:
+
+ BIT STRING, an arbitrary string of bits (ones and
+ zeroes).
+
+ IA5String, an arbitrary string of IA5 (ASCII)
+ characters.
+
+ INTEGER, an arbitrary integer.
+
+ NULL, a null value.
+
+ OBJECT IDENTIFIER, an object identifier, which is a
+ sequence of integer components that identify an
+ object such as an algorithm or attribute type.
+
+ OCTET STRING, an arbitrary string of octets (eight-bit
+ values).
+
+ PrintableString, an arbitrary string of printable
+ characters.
+
+ T61String, an arbitrary string of T.61 (eight-bit)
+ characters.
+
+ UTCTime, a "coordinated universal time" or Greenwich
+ Mean Time (GMT) value.
+
+Simple types fall into two categories: string types and non-
+string types. BIT STRING, IA5String, OCTET STRING,
+PrintableString, T61String, and UTCTime are string types.
+
+String types can be viewed, for the purposes of encoding, as
+consisting of components, where the components are
+substrings. This view allows one to encode a value whose
+length is not known in advance (e.g., an octet string value
+input from a file stream) with a constructed, indefinite-
+length encoding (see Section 3).
+
+The string types can be given size constraints limiting the
+length of values.
+
+
+2.2 Structured types
+
+Structured types are those consisting of components. ASN.1
+defines four, all of which are relevant to the PKCS
+standards:
+
+ SEQUENCE, an ordered collection of one or more types.
+
+ SEQUENCE OF, an ordered collection of zero or more
+ occurrences of a given type.
+
+ SET, an unordered collection of one or more types.
+
+ SET OF, an unordered collection of zero or more
+ occurrences of a given type.
+
+The structured types can have optional components, possibly
+with default values.
+
+
+2.3 Implicitly and explicitly tagged types
+
+Tagging is useful to distinguish types within an
+application; it is also commonly used to distinguish
+component types within a structured type. For instance,
+optional components of a SET or SEQUENCE type are typically
+given distinct context-specific tags to avoid ambiguity.
+
+There are two ways to tag a type: implicitly and explicitly.
+
+Implicitly tagged types are derived from other types by
+changing the tag of the underlying type. Implicit tagging is
+denoted by the ASN.1 keywords [class number] IMPLICIT (see
+Section 5.1).
+
+Explicitly tagged types are derived from other types by
+adding an outer tag to the underlying type. In effect,
+explicitly tagged types are structured types consisting of
+one component, the underlying type. Explicit tagging is
+denoted by the ASN.1 keywords [class number] EXPLICIT (see
+Section 5.2).
+
+The keyword [class number] alone is the same as explicit
+tagging, except when the "module" in which the ASN.1 type is
+defined has implicit tagging by default. ("Modules" are
+among the advanced features not described in this note.)
+
+For purposes of encoding, an implicitly tagged type is
+considered the same as the underlying type, except that the
+tag is different. An explicitly tagged type is considered
+like a structured type with one component, the underlying
+type. Implicit tags result in shorter encodings, but
+explicit tags may be necessary to avoid ambiguity if the tag
+of the underlying type is indeterminate (e.g., the
+underlying type is CHOICE or ANY).
+
+
+2.4 Other types
+
+Other types in ASN.1 include the CHOICE and ANY types. The
+CHOICE type denotes a union of one or more alternatives; the
+ANY type denotes an arbitrary value of an arbitrary type,
+where the arbitrary type is possibly defined in the
+registration of an object identifier or integer value.
+
+
+3. Basic Encoding Rules
+
+The Basic Encoding Rules for ASN.1, abbreviated BER, give
+one or more ways to represent any ASN.1 value as an octet
+string. (There are certainly other ways to represent ASN.1
+values, but BER is the standard for interchanging such
+values in OSI.)
+
+There are three methods to encode an ASN.1 value under BER,
+the choice of which depends on the type of value and whether
+the length of the value is known. The three methods are
+primitive, definite-length encoding; constructed, definite-
+length encoding; and constructed, indefinite-length
+encoding. Simple non-string types employ the primitive,
+definite-length method; structured types employ either of
+the constructed methods; and simple string types employ any
+of the methods, depending on whether the length of the value
+is known. Types derived by implicit tagging employ the
+method of the underlying type and types derived by explicit
+tagging employ the constructed methods.
+
+In each method, the BER encoding has three or four parts:
+
+ Identifier octets. These identify the class and tag
+ number of the ASN.1 value, and indicate whether
+ the method is primitive or constructed.
+
+ Length octets. For the definite-length methods, these
+ give the number of contents octets. For the
+ constructed, indefinite-length method, these
+ indicate that the length is indefinite.
+
+ Contents octets. For the primitive, definite-length
+ method, these give a concrete representation of
+ the value. For the constructed methods, these
+ give the concatenation of the BER encodings of the
+ components of the value.
+
+ End-of-contents octets. For the constructed, indefinite-
+ length method, these denote the end of the
+ contents. For the other methods, these are absent.
+
+The three methods of encoding are described in the following
+sections.
+
+
+3.1 Primitive, definite-length method
+
+This method applies to simple types and types derived from
+simple types by implicit tagging. It requires that the
+length of the value be known in advance. The parts of the
+BER encoding are as follows:
+
+Identifier octets. There are two forms: low tag number (for
+tag numbers between 0 and 30) and high tag number (for tag
+numbers 31 and greater).
+
+ Low-tag-number form. One octet. Bits 8 and 7 specify
+ the class (see Table 2), bit 6 has value "0,"
+ indicating that the encoding is primitive, and
+ bits 5-1 give the tag number.
+
+ Class Bit Bit
+ 8 7
+ universal 0 0
+ application 0 1
+ context-specific 1 0
+ private 1 1
+
+ Table 2. Class encoding in identifier octets.
+
+ High-tag-number form. Two or more octets. First octet
+ is as in low-tag-number form, except that bits 5-1
+ all have value "1." Second and following octets
+ give the tag number, base 128, most significant
+ digit first, with as few digits as possible, and
+ with the bit 8 of each octet except the last set
+ to "1."
+
+Length octets. There are two forms: short (for lengths
+between 0 and 127), and long definite (for lengths between 0
+and 21008-1).
+
+ Short form. One octet. Bit 8 has value "0" and bits 7-1
+ give the length.
+
+ Long form. Two to 127 octets. Bit 8 of first octet has
+ value "1" and bits 7-1 give the number of
+ additional length octets. Second and following
+ octets give the length, base 256, most significant
+ digit first.
+
+Contents octets. These give a concrete representation of the
+value (or the value of the underlying type, if the type is
+derived by implicit tagging). Details for particular types
+are given in Section 5.
+
+
+3.2 Constructed, definite-length method
+
+This method applies to simple string types, structured
+types, types derived simple string types and structured
+types by implicit tagging, and types derived from anything
+by explicit tagging. It requires that the length of the
+value be known in advance. The parts of the BER encoding are
+as follows:
+
+Identifier octets. As described in Section 3.1, except that
+bit 6 has value "1," indicating that the encoding is
+constructed.
+
+Length octets. As described in Section 3.1.
+
+Contents octets. The concatenation of the BER encodings of
+the components of the value:
+
+ o For simple string types and types derived from
+ them by implicit tagging, the concatenation of the
+ BER encodings of consecutive substrings of the
+ value (underlying value for implicit tagging).
+
+ o For structured types and types derived from them
+ by implicit tagging, the concatenation of the BER
+ encodings of components of the value (underlying
+ value for implicit tagging).
+
+ o For types derived from anything by explicit
+ tagging, the BER encoding of the underlying value.
+
+Details for particular types are given in Section 5.
+
+
+3.3 Constructed, indefinite-length method
+
+This method applies to simple string types, structured
+types, types derived simple string types and structured
+types by implicit tagging, and types derived from anything
+by explicit tagging. It does not require that the length of
+the value be known in advance. The parts of the BER encoding
+are as follows:
+
+Identifier octets. As described in Section 3.2.
+
+Length octets. One octet, 80.
+
+Contents octets. As described in Section 3.2.
+
+End-of-contents octets. Two octets, 00 00.
+
+Since the end-of-contents octets appear where an ordinary
+BER encoding might be expected (e.g., in the contents octets
+of a sequence value), the 00 and 00 appear as identifier and
+length octets, respectively. Thus the end-of-contents octets
+is really the primitive, definite-length encoding of a value
+with universal class, tag number 0, and length 0.
+
+
+4. Distinguished Encoding Rules
+
+The Distinguished Encoding Rules for ASN.1, abbreviated DER,
+are a subset of BER, and give exactly one way to represent
+any ASN.1 value as an octet string. DER is intended for
+applications in which a unique octet string encoding is
+needed, as is the case when a digital signature is computed
+on an ASN.1 value. DER is defined in Section 8.7 of X.509.
+
+DER adds the following restrictions to the rules given in
+Section 3:
+
+ 1. When the length is between 0 and 127, the short
+ form of length must be used
+
+ 2. When the length is 128 or greater, the long form
+ of length must be used, and the length must be
+ encoded in the minimum number of octets.
+
+ 3. For simple string types and implicitly tagged
+ types derived from simple string types, the
+ primitive, definite-length method must be
+ employed.
+
+ 4. For structured types, implicitly tagged types
+ derived from structured types, and explicitly
+ tagged types derived from anything, the
+ constructed, definite-length method must be
+ employed.
+
+Other restrictions are defined for particular types (such as
+BIT STRING, SEQUENCE, SET, and SET OF), and can be found in
+Section 5.
+
+
+5. Notation and encodings for some types
+
+This section gives the notation for some ASN.1 types and
+describes how to encode values of those types under both BER
+and DER.
+
+The types described are those presented in Section 2. They
+are listed alphabetically here.
+
+Each description includes ASN.1 notation, BER encoding, and
+DER encoding. The focus of the encodings is primarily on the
+contents octets; the tag and length octets follow Sections 3
+and 4. The descriptions also explain where each type is used
+in PKCS and related standards. ASN.1 notation is generally
+only for types, although for the type OBJECT IDENTIFIER,
+value notation is given as well.
+
+
+5.1 Implicitly tagged types
+
+An implicitly tagged type is a type derived from another
+type by changing the tag of the underlying type.
+
+Implicit tagging is used for optional SEQUENCE components
+with underlying type other than ANY throughout PKCS, and for
+the extendedCertificate alternative of PKCS #7's
+ExtendedCertificateOrCertificate type.
+
+ASN.1 notation:
+
+[[class] number] IMPLICIT Type
+
+class = UNIVERSAL | APPLICATION | PRIVATE
+
+where Type is a type, class is an optional class name, and
+number is the tag number within the class, a nonnegative
+integer.
+
+In ASN.1 "modules" whose default tagging method is implicit
+tagging, the notation [[class] number] Type is also
+acceptable, and the keyword IMPLICIT is implied. (See
+Section 2.3.) For definitions stated outside a module, the
+explicit inclusion of the keyword IMPLICIT is preferable to
+prevent ambiguity.
+
+If the class name is absent, then the tag is context-
+specific. Context-specific tags can only appear in a
+component of a structured or CHOICE type.
+
+Example: PKCS #8's PrivateKeyInfo type has an optional
+attributes component with an implicit, context-specific tag:
+
+PrivateKeyInfo ::= SEQUENCE {
+ version Version,
+ privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ privateKey PrivateKey,
+ attributes [0] IMPLICIT Attributes OPTIONAL }
+
+Here the underlying type is Attributes, the class is absent
+(i.e., context-specific), and the tag number within the
+class is 0.
+
+BER encoding. Primitive or constructed, depending on the
+underlying type. Contents octets are as for the BER encoding
+of the underlying value.
+
+Example: The BER encoding of the attributes component of a
+PrivateKeyInfo value is as follows:
+
+ o the identifier octets are 80 if the underlying
+ Attributes value has a primitive BER encoding and
+ a0 if the underlying Attributes value has a
+ constructed BER encoding
+
+ o the length and contents octets are the same as the
+ length and contents octets of the BER encoding of
+ the underlying Attributes value
+
+DER encoding. Primitive or constructed, depending on the
+underlying type. Contents octets are as for the DER encoding
+of the underlying value.
+
+
+5.2 Explicitly tagged types
+
+Explicit tagging denotes a type derived from another type by
+adding an outer tag to the underlying type.
+
+Explicit tagging is used for optional SEQUENCE components
+with underlying type ANY throughout PKCS, and for the
+version component of X.509's Certificate type.
+
+ASN.1 notation:
+
+[[class] number] EXPLICIT Type
+
+class = UNIVERSAL | APPLICATION | PRIVATE
+
+where Type is a type, class is an optional class name, and
+number is the tag number within the class, a nonnegative
+integer.
+
+If the class name is absent, then the tag is context-
+specific. Context-specific tags can only appear in a
+component of a SEQUENCE, SET or CHOICE type.
+
+In ASN.1 "modules" whose default tagging method is explicit
+tagging, the notation [[class] number] Type is also
+acceptable, and the keyword EXPLICIT is implied. (See
+Section 2.3.) For definitions stated outside a module, the
+explicit inclusion of the keyword EXPLICIT is preferable to
+prevent ambiguity.
+
+Example 1: PKCS #7's ContentInfo type has an optional
+content component with an explicit, context-specific tag:
+
+ContentInfo ::= SEQUENCE {
+ contentType ContentType,
+ content
+ [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+
+Here the underlying type is ANY DEFINED BY contentType, the
+class is absent (i.e., context-specific), and the tag number
+within the class is 0.
+
+Example 2: X.509's Certificate type has a version component
+with an explicit, context-specific tag, where the EXPLICIT
+keyword is omitted:
+
+Certificate ::= ...
+ version [0] Version DEFAULT v1988,
+...
+
+The tag is explicit because the default tagging method for
+the ASN.1 "module" in X.509 that defines the Certificate
+type is explicit tagging.
+
+BER encoding. Constructed. Contents octets are the BER
+encoding of the underlying value.
+
+Example: the BER encoding of the content component of a
+ContentInfo value is as follows:
+
+ o identifier octets are a0
+
+ o length octets represent the length of the BER
+ encoding of the underlying ANY DEFINED BY
+ contentType value
+
+ o contents octets are the BER encoding of the
+ underlying ANY DEFINED BY contentType value
+
+DER encoding. Constructed. Contents octets are the DER
+encoding of the underlying value.
+
+
+5.3 ANY
+
+The ANY type denotes an arbitrary value of an arbitrary
+type, where the arbitrary type is possibly defined in the
+registration of an object identifier or associated with an
+integer index.
+
+The ANY type is used for content of a particular content
+type in PKCS #7's ContentInfo type, for parameters of a
+particular algorithm in X.509's AlgorithmIdentifier type,
+and for attribute values in X.501's Attribute and
+AttributeValueAssertion types. The Attribute type is used by
+PKCS #6, #7, #8, #9 and #10, and the AttributeValueAssertion
+type is used in X.501 distinguished names.
+
+ASN.1 notation:
+
+ANY [DEFINED BY identifier]
+
+where identifier is an optional identifier.
+
+In the ANY form, the actual type is indeterminate.
+
+The ANY DEFINED BY identifier form can only appear in a
+component of a SEQUENCE or SET type for which identifier
+identifies some other component, and that other component
+has type INTEGER or OBJECT IDENTIFIER (or a type derived
+from either of those by tagging). In that form, the actual
+type is determined by the value of the other component,
+either in the registration of the object identifier value,
+or in a table of integer values.
+
+Example: X.509's AlgorithmIdentifier type has a component of
+type ANY:
+
+AlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY DEFINED BY algorithm OPTIONAL }
+
+Here the actual type of the parameter component depends on
+the value of the algorithm component. The actual type would
+be defined in the registration of object identifier values
+for the algorithm component.
+
+BER encoding. Same as the BER encoding of the actual value.
+
+Example: The BER encoding of the value of the parameter
+component is the BER encoding of the value of the actual
+type as defined in the registration of object identifier
+values for the algorithm component.
+
+DER encoding. Same as the DER encoding of the actual value.
+
+
+5.4 BIT STRING
+
+The BIT STRING type denotes an arbitrary string of bits
+(ones and zeroes). A BIT STRING value can have any length,
+including zero. This type is a string type.
+
+The BIT STRING type is used for digital signatures on
+extended certificates in PKCS #6's ExtendedCertificate type,
+for digital signatures on certificates in X.509's
+Certificate type, and for public keys in certificates in
+X.509's SubjectPublicKeyInfo type.
+
+ASN.1 notation:
+
+BIT STRING
+
+Example: X.509's SubjectPublicKeyInfo type has a component
+of type BIT STRING:
+
+SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm AlgorithmIdentifier,
+ publicKey BIT STRING }
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the first contents octet gives the number of bits
+by which the length of the bit string is less than the next
+multiple of eight (this is called the "number of unused
+bits"). The second and following contents octets give the
+value of the bit string, converted to an octet string. The
+conversion process is as follows:
+
+ 1. The bit string is padded after the last bit with
+ zero to seven bits of any value to make the length
+ of the bit string a multiple of eight. If the
+ length of the bit string is a multiple of eight
+ already, no padding is done.
+
+ 2. The padded bit string is divided into octets. The
+ first eight bits of the padded bit string become
+ the first octet, bit 8 to bit 1, and so on through
+ the last eight bits of the padded bit string.
+
+In a constructed encoding, the contents octets give the
+concatenation of the BER encodings of consecutive substrings
+of the bit string, where each substring except the last has
+a length that is a multiple of eight bits.
+
+Example: The BER encoding of the BIT STRING value
+"011011100101110111" can be any of the following, among
+others, depending on the choice of padding bits, the form of
+length octets, and whether the encoding is primitive or
+constructed:
+
+03 04 06 6e 5d c0 DER encoding
+
+03 04 06 6e 5d e0 padded with "100000"
+
+03 81 04 06 6e 5d c0 long form of length octets
+
+23 09 constructed encoding: "0110111001011101" + "11"
+ 03 03 00 6e 5d
+ 03 02 06 c0
+
+DER encoding. Primitive. The contents octects are as for a
+primitive BER encoding, except that the bit string is padded
+with zero-valued bits.
+
+Example: The DER encoding of the BIT STRING value
+"011011100101110111" is
+
+03 04 06 6e 5d c0
+
+
+5.5 CHOICE
+
+The CHOICE type denotes a union of one or more alternatives.
+
+The CHOICE type is used to represent the union of an
+extended certificate and an X.509 certificate in PKCS #7's
+ExtendedCertificateOrCertificate type.
+
+ASN.1 notation:
+
+CHOICE {
+ [identifier1] Type1,
+ ...,
+ [identifiern] Typen }
+
+where identifier1 , ..., identifiern are optional, distinct
+identifiers for the alternatives, and Type1, ..., Typen are
+the types of the alternatives. The identifiers are primarily
+for documentation; they do not affect values of the type or
+their encodings in any way.
+
+The types must have distinct tags. This requirement is
+typically satisfied with explicit or implicit tagging on
+some of the alternatives.
+
+Example: PKCS #7's ExtendedCertificateOrCertificate type is
+a CHOICE type:
+
+ExtendedCertificateOrCertificate ::= CHOICE {
+ certificate Certificate, -- X.509
+ extendedCertificate [0] IMPLICIT ExtendedCertificate
+}
+
+Here the identifiers for the alternatives are certificate
+and extendedCertificate, and the types of the alternatives
+are Certificate and [0] IMPLICIT ExtendedCertificate.
+
+BER encoding. Same as the BER encoding of the chosen
+alternative. The fact that the alternatives have distinct
+tags makes it possible to distinguish between their BER
+encodings.
+
+Example: The identifier octets for the BER encoding are 30
+if the chosen alternative is certificate, and a0 if the
+chosen alternative is extendedCertificate.
+
+DER encoding. Same as the DER encoding of the chosen
+alternative.
+
+
+5.6 IA5String
+
+The IA5String type denotes an arbtrary string of IA5
+characters. IA5 stands for International Alphabet 5, which
+is the same as ASCII. The character set includes non-
+printing control characters. An IA5String value can have any
+length, including zero. This type is a string type.
+
+The IA5String type is used in PKCS #9's electronic-mail
+address, unstructured-name, and unstructured-address
+attributes.
+
+ASN.1 notation:
+
+IA5String
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the contents octets give the characters in the IA5
+string, encoded in ASCII. In a constructed encoding, the
+contents octets give the concatenation of the BER encodings
+of consecutive substrings of the IA5 string.
+
+Example: The BER encoding of the IA5String value
+"test1@rsa.com" can be any of the following, among others,
+depending on the form of length octets and whether the
+encoding is primitive or constructed:
+
+16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d DER encoding
+
+16 81 0d long form of length octets
+ 74 65 73 74 31 40 72 73 61 2e 63 6f 6d
+
+36 13 constructed encoding: "test1" + "@" + "rsa.com"
+ 16 05 74 65 73 74 31
+ 16 01 40
+ 16 07 72 73 61 2e 63 6f 6d
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+Example: The DER encoding of the IA5String value
+"test1@rsa.com" is
+
+16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d
+
+
+5.7 INTEGER
+
+The INTEGER type denotes an arbitrary integer. INTEGER
+values can be positive, negative, or zero, and can have any
+magnitude.
+
+The INTEGER type is used for version numbers throughout
+PKCS, cryptographic values such as modulus, exponent, and
+primes in PKCS #1's RSAPublicKey and RSAPrivateKey types and
+PKCS #3's DHParameter type, a message-digest iteration count
+in PKCS #5's PBEParameter type, and version numbers and
+serial numbers in X.509's Certificate type.
+
+ASN.1 notation:
+
+INTEGER [{ identifier1(value1) ... identifiern(valuen) }]
+
+where identifier1, ..., identifiern are optional distinct
+identifiers and value1, ..., valuen are optional integer
+values. The identifiers, when present, are associated with
+values of the type.
+
+Example: X.509's Version type is an INTEGER type with
+identified values:
+
+Version ::= INTEGER { v1988(0) }
+
+The identifier v1988 is associated with the value 0. X.509's
+Certificate type uses the identifier v1988 to give a default
+value of 0 for the version component:
+
+Certificate ::= ...
+ version Version DEFAULT v1988,
+...
+
+BER encoding. Primitive. Contents octets give the value of
+the integer, base 256, in two's complement form, most
+significant digit first, with the minimum number of octets.
+The value 0 is encoded as a single 00 octet.
+
+Some example BER encodings (which also happen to be DER
+encodings) are given in Table 3.
+
+ Integer BER encoding
+ value
+ 0 02 01 00
+ 127 02 01 7F
+ 128 02 02 00 80
+ 256 02 02 01 00
+ -128 02 01 80
+ -129 02 02 FF 7F
+
+ Table 3. Example BER encodings of INTEGER values.
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+
+5.8 NULL
+
+The NULL type denotes a null value.
+
+The NULL type is used for algorithm parameters in several
+places in PKCS.
+
+ASN.1 notation:
+
+NULL
+
+BER encoding. Primitive. Contents octets are empty.
+
+Example: The BER encoding of a NULL value can be either of
+the following, as well as others, depending on the form of
+the length octets:
+
+05 00
+
+05 81 00
+
+DER encoding. Primitive. Contents octets are empty; the DER
+encoding of a NULL value is always 05 00.
+
+
+5.9 OBJECT IDENTIFIER
+
+The OBJECT IDENTIFIER type denotes an object identifier, a
+sequence of integer components that identifies an object
+such as an algorithm, an attribute type, or perhaps a
+registration authority that defines other object
+identifiers. An OBJECT IDENTIFIER value can have any number
+of components, and components can generally have any
+nonnegative value. This type is a non-string type.
+
+OBJECT IDENTIFIER values are given meanings by registration
+authorities. Each registration authority is responsible for
+all sequences of components beginning with a given sequence.
+A registration authority typically delegates responsibility
+for subsets of the sequences in its domain to other
+registration authorities, or for particular types of object.
+There are always at least two components.
+
+The OBJECT IDENTIFIER type is used to identify content in
+PKCS #7's ContentInfo type, to identify algorithms in
+X.509's AlgorithmIdentifier type, and to identify attributes
+in X.501's Attribute and AttributeValueAssertion types. The
+Attribute type is used by PKCS #6, #7, #8, #9, and #10, and
+the AttributeValueAssertion type is used in X.501
+distinguished names. OBJECT IDENTIFIER values are defined
+throughout PKCS.
+
+ASN.1 notation:
+
+OBJECT IDENTIFIER
+
+The ASN.1 notation for values of the OBJECT IDENTIFIER type
+is
+
+{ [identifier] component1 ... componentn }
+
+componenti = identifieri | identifieri (valuei) | valuei
+
+where identifier, identifier1, ..., identifiern are
+identifiers, and value1, ..., valuen are optional integer
+values.
+
+The form without identifier is the "complete" value with all
+its components; the form with identifier abbreviates the
+beginning components with another object identifier value.
+The identifiers identifier1, ..., identifiern are intended
+primarily for documentation, but they must correspond to the
+integer value when both are present. These identifiers can
+appear without integer values only if they are among a small
+set of identifiers defined in X.208.
+
+Example: The following values both refer to the object
+identifier assigned to RSA Data Security, Inc.:
+
+{ iso(1) member-body(2) 840 113549 }
+{ 1 2 840 113549 }
+
+(In this example, which gives ASN.1 value notation, the
+object identifier values are decimal, not hexadecimal.)
+Table 4 gives some other object identifier values and their
+meanings.
+
+ Object identifier value Meaning
+ { 1 2 } ISO member bodies
+ { 1 2 840 } US (ANSI)
+ { 1 2 840 113549 } RSA Data Security, Inc.
+ { 1 2 840 113549 1 } RSA Data Security, Inc. PKCS
+ { 2 5 } directory services (X.500)
+ { 2 5 8 } directory services-algorithms
+
+ Table 4. Some object identifier values and their meanings.
+
+BER encoding. Primitive. Contents octets are as follows,
+where value1, ..., valuen denote the integer values of the
+components in the complete object identifier:
+
+ 1. The first octet has value 40 * value1 + value2.
+ (This is unambiguous, since value1 is limited to
+ values 0, 1, and 2; value2 is limited to the range
+ 0 to 39 when value1 is 0 or 1; and, according to
+ X.208, n is always at least 2.)
+
+ 2. The following octets, if any, encode value3, ...,
+ valuen. Each value is encoded base 128, most
+ significant digit first, with as few digits as
+ possible, and the most significant bit of each
+ octet except the last in the value's encoding set
+ to "1."
+
+Example: The first octet of the BER encoding of RSA Data
+Security, Inc.'s object identifier is 40 * 1 + 2 = 42 =
+2a16. The encoding of 840 = 6 * 128 + 4816 is 86 48 and the
+encoding of 113549 = 6 * 1282 + 7716 * 128 + d16 is 86 f7
+0d. This leads to the following BER encoding:
+
+06 06 2a 86 48 86 f7 0d
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+
+5.10 OCTET STRING
+
+The OCTET STRING type denotes an arbitrary string of octets
+(eight-bit values). An OCTET STRING value can have any
+length, including zero. This type is a string type.
+
+The OCTET STRING type is used for salt values in PKCS #5's
+PBEParameter type, for message digests, encrypted message
+digests, and encrypted content in PKCS #7, and for private
+keys and encrypted private keys in PKCS #8.
+
+ASN.1 notation:
+
+OCTET STRING [SIZE ({size | size1..size2})]
+
+where size, size1, and size2 are optional size constraints.
+In the OCTET STRING SIZE (size) form, the octet string must
+have size octets. In the OCTET STRING SIZE (size1..size2)
+form, the octet string must have between size1 and size2
+octets. In the OCTET STRING form, the octet string can have
+any size.
+
+Example: PKCS #5's PBEParameter type has a component of type
+OCTET STRING:
+
+PBEParameter ::= SEQUENCE {
+ salt OCTET STRING SIZE(8),
+ iterationCount INTEGER }
+
+Here the size of the salt component is always eight octets.
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the contents octets give the value of the octet
+string, first octet to last octet. In a constructed
+encoding, the contents octets give the concatenation of the
+BER encodings of substrings of the OCTET STRING value.
+
+Example: The BER encoding of the OCTET STRING value 01 23 45
+67 89 ab cd ef can be any of the following, among others,
+depending on the form of length octets and whether the
+encoding is primitive or constructed:
+
+04 08 01 23 45 67 89 ab cd ef DER encoding
+
+04 81 08 01 23 45 67 89 ab cd ef long form of length octets
+
+24 0c constructed encoding: 01 ... 67 + 89 ... ef
+ 04 04 01 23 45 67
+ 04 04 89 ab cd ef
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+Example: The BER encoding of the OCTET STRING value 01 23 45
+67 89 ab cd ef is
+
+04 08 01 23 45 67 89 ab cd ef
+
+
+5.11 PrintableString
+
+The PrintableString type denotes an arbitrary string of
+printable characters from the following character set:
+
+ A, B, ..., Z
+ a, b, ..., z
+ 0, 1, ..., 9
+ (space) ' ( ) + , - . / : = ?
+
+This type is a string type.
+
+The PrintableString type is used in PKCS #9's challenge-
+password and unstructuerd-address attributes, and in several
+X.521 distinguished names attributes.
+
+ASN.1 notation:
+
+PrintableString
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the contents octets give the characters in the
+printable string, encoded in ASCII. In a constructed
+encoding, the contents octets give the concatenation of the
+BER encodings of consecutive substrings of the string.
+
+Example: The BER encoding of the PrintableString value "Test
+User 1" can be any of the following, among others, depending
+on the form of length octets and whether the encoding is
+primitive or constructed:
+
+13 0b 54 65 73 74 20 55 73 65 72 20 31 DER encoding
+
+13 81 0b long form of length octets
+ 54 65 73 74 20 55 73 65 72 20 31
+
+33 0f constructed encoding: "Test " + "User 1"
+ 13 05 54 65 73 74 20
+ 13 06 55 73 65 72 20 31
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+Example: The DER encoding of the PrintableString value "Test
+User 1" is
+
+13 0b 54 65 73 74 20 55 73 65 72 20 31
+
+
+5.12 SEQUENCE
+
+The SEQUENCE type denotes an ordered collection of one or
+more types.
+
+The SEQUENCE type is used throughout PKCS and related
+standards.
+
+ASN.1 notation:
+
+SEQUENCE {
+ [identifier1] Type1 [{OPTIONAL | DEFAULT value1}],
+ ...,
+ [identifiern] Typen [{OPTIONAL | DEFAULT valuen}]}
+
+where identifier1 , ..., identifiern are optional, distinct
+identifiers for the components, Type1, ..., Typen are the
+types of the components, and value1, ..., valuen are optional
+default values for the components. The identifiers are
+primarily for documentation; they do not affect values of
+the type or their encodings in any way.
+
+The OPTIONAL qualifier indicates that the value of a
+component is optional and need not be present in the
+sequence. The DEFAULT qualifier also indicates that the
+value of a component is optional, and assigns a default
+value to the component when the component is absent.
+
+The types of any consecutive series of components with the
+OPTIONAL or DEFAULT qualifier, as well as of any component
+immediately following that series, must have distinct tags.
+This requirement is typically satisfied with explicit or
+implicit tagging on some of the components.
+
+Example: X.509's Validity type is a SEQUENCE type with two
+components:
+
+Validity ::= SEQUENCE {
+ start UTCTime,
+ end UTCTime }
+
+Here the identifiers for the components are start and end,
+and the types of the components are both UTCTime.
+
+BER encoding. Constructed. Contents octets are the
+concatenation of the BER encodings of the values of the
+components of the sequence, in order of definition, with the
+following rules for components with the OPTIONAL and DEFAULT
+qualifiers:
+
+ o if the value of a component with the OPTIONAL or
+ DEFAULT qualifier is absent from the sequence,
+ then the encoding of that component is not
+ included in the contents octets
+
+ o if the value of a component with the DEFAULT
+ qualifier is the default value, then the encoding
+ of that component may or may not be included in
+ the contents octets
+
+DER encoding. Constructed. Contents octets are the same as
+the BER encoding, except that if the value of a component
+with the DEFAULT qualifier is the default value, the
+encoding of that component is not included in the contents
+octets.
+
+
+5.13 SEQUENCE OF
+
+The SEQUENCE OF type denotes an ordered collection of zero
+or more occurrences of a given type.
+
+The SEQUENCE OF type is used in X.501 distinguished names.
+
+ASN.1 notation:
+
+SEQUENCE OF Type
+
+where Type is a type.
+
+Example: X.501's RDNSequence type consists of zero or more
+occurences of the RelativeDistinguishedName type, most
+significant occurrence first:
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+BER encoding. Constructed. Contents octets are the
+concatenation of the BER encodings of the values of the
+occurrences in the collection, in order of occurence.
+
+DER encoding. Constructed. Contents octets are the
+concatenation of the DER encodings of the values of the
+occurrences in the collection, in order of occurence.
+
+
+5.14 SET
+
+The SET type denotes an unordered collection of one or more
+types.
+
+The SET type is not used in PKCS.
+
+ASN.1 notation:
+
+SET {
+ [identifier1] Type1 [{OPTIONAL | DEFAULT value1}],
+ ...,
+ [identifiern] Typen [{OPTIONAL | DEFAULT valuen}]}
+
+where identifier1, ..., identifiern are optional, distinct
+identifiers for the components, Type1, ..., Typen are the
+types of the components, and value1, ..., valuen are
+optional default values for the components. The identifiers
+are primarily for documentation; they do not affect values
+of the type or their encodings in any way.
+
+The OPTIONAL qualifier indicates that the value of a
+component is optional and need not be present in the set.
+The DEFAULT qualifier also indicates that the value of a
+component is optional, and assigns a default value to the
+component when the component is absent.
+
+The types must have distinct tags. This requirement is
+typically satisfied with explicit or implicit tagging on
+some of the components.
+
+BER encoding. Constructed. Contents octets are the
+concatenation of the BER encodings of the values of the
+components of the set, in any order, with the following
+rules for components with the OPTIONAL and DEFAULT
+qualifiers:
+
+ o if the value of a component with the OPTIONAL or
+ DEFAULT qualifier is absent from the set, then the
+ encoding of that component is not included in the
+ contents octets
+
+ o if the value of a component with the DEFAULT
+ qualifier is the default value, then the encoding
+ of that component may or may not be included in
+ the contents octets
+
+DER encoding. Constructed. Contents octets are the same as
+for the BER encoding, except that:
+
+ 1. If the value of a component with the DEFAULT
+ qualifier is the default value, the encoding of
+ that component is not included.
+
+ 2. There is an order to the components, namely
+ ascending order by tag.
+
+
+5.15 SET OF
+
+The SET OF type denotes an unordered collection of zero or
+more occurrences of a given type.
+
+The SET OF type is used for sets of attributes in PKCS #6,
+#7, #8, #9 and #10, for sets of message-digest algorithm
+identifiers, signer information, and recipient information
+in PKCS #7, and in X.501 distinguished names.
+
+ASN.1 notation:
+
+SET OF Type
+
+where Type is a type.
+
+Example: X.501's RelativeDistinguishedName type consists of
+zero or more occurrences of the AttributeValueAssertion
+type, where the order is unimportant:
+
+RelativeDistinguishedName ::=
+ SET OF AttributeValueAssertion
+
+BER encoding. Constructed. Contents octets are the
+concatenation of the BER encodings of the values of the
+occurrences in the collection, in any order.
+
+DER encoding. Constructed. Contents octets are the same as
+for the BER encoding, except that there is an order, namely
+ascending lexicographic order of BER encoding. Lexicographic
+comparison of two different BER encodings is done as
+follows: Logically pad the shorter BER encoding after the
+last octet with dummy octets that are smaller in value than
+any normal octet. Scan the BER encodings from left to right
+until a difference is found. The smaller-valued BER encoding
+is the one with the smaller-valued octet at the point of
+difference.
+
+
+5.16 T61String
+
+The T61String type denotes an arbtrary string of T.61
+characters. T.61 is an eight-bit extension to the ASCII
+character set. Special "escape" sequences specify the
+interpretation of subsequent character values as, for
+example, Japanese; the initial interpretation is Latin. The
+character set includes non-printing control characters. The
+T61String type allows only the Latin and Japanese character
+interepretations, and implementors' agreements for directory
+names exclude control characters [NIST92]. A T61String value
+can have any length, including zero. This type is a string
+type.
+
+The T61String type is used in PKCS #9's unstructured-address
+and challenge-password attributes, and in several X.521
+attributes.
+
+ASN.1 notation:
+
+T61String
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the contents octets give the characters in the
+T.61 string, encoded in ASCII. In a constructed encoding,
+the contents octets give the concatenation of the BER
+encodings of consecutive substrings of the T.61 string.
+
+Example: The BER encoding of the T61String value "cl'es
+publiques" (French for "public keys") can be any of the
+following, among others, depending on the form of length
+octets and whether the encoding is primitive or constructed:
+
+14 0f DER encoding
+ 63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73
+
+14 81 0f long form of length octets
+ 63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73
+
+34 15 constructed encoding: "cl'es" + " " + "publiques"
+ 14 05 63 6c c2 65 73
+ 14 01 20
+ 14 09 70 75 62 6c 69 71 75 65 73
+
+The eight-bit character c2 is a T.61 prefix that adds an
+acute accent (') to the next character.
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+Example: The DER encoding of the T61String value "cl'es
+publiques" is
+
+14 0f 63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73
+
+
+5.17 UTCTime
+
+The UTCTime type denotes a "coordinated universal time" or
+Greenwich Mean Time (GMT) value. A UTCTime value includes
+the local time precise to either minutes or seconds, and an
+offset from GMT in hours and minutes. It takes any of the
+following forms:
+
+YYMMDDhhmmZ
+YYMMDDhhmm+hh'mm'
+YYMMDDhhmm-hh'mm'
+YYMMDDhhmmssZ
+YYMMDDhhmmss+hh'mm'
+YYMMDDhhmmss-hh'mm'
+
+where:
+
+ YY is the least significant two digits of the year
+
+ MM is the month (01 to 12)
+
+ DD is the day (01 to 31)
+
+ hh is the hour (00 to 23)
+
+ mm are the minutes (00 to 59)
+
+ ss are the seconds (00 to 59)
+
+ Z indicates that local time is GMT, + indicates that
+ local time is later than GMT, and - indicates that
+ local time is earlier than GMT
+
+ hh' is the absolute value of the offset from GMT in
+ hours
+
+ mm' is the absolute value of the offset from GMT in
+ minutes
+
+This type is a string type.
+
+The UTCTime type is used for signing times in PKCS #9's
+signing-time attribute and for certificate validity periods
+in X.509's Validity type.
+
+ASN.1 notation:
+
+UTCTime
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the contents octets give the characters in the
+string, encoded in ASCII. In a constructed encoding, the
+contents octets give the concatenation of the BER encodings
+of consecutive substrings of the string. (The constructed
+encoding is not particularly interesting, since UTCTime
+values are so short, but the constructed encoding is
+permitted.)
+
+Example: The time this sentence was originally written was
+4:45:40 p.m. Pacific Daylight Time on May 6, 1991, which can
+be represented with either of the following UTCTime values,
+among others:
+
+"910506164540-0700"
+
+"910506234540Z"
+
+These values have the following BER encodings, among others:
+
+17 0d 39 31 30 35 30 36 32 33 34 35 34 30 5a
+
+17 11 39 31 30 35 30 36 31 36 34 35 34 30 2D 30 37 30
+ 30
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+
+6. An example
+
+This section gives an example of ASN.1 notation and DER
+encoding: the X.501 type Name.
+
+
+6.1 Abstract notation
+
+This section gives the ASN.1 notation for the X.501 type
+Name.
+
+Name ::= CHOICE {
+ RDNSequence }
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+RelativeDistinguishedName ::=
+ SET OF AttributeValueAssertion
+
+AttributeValueAssertion ::= SEQUENCE {
+ AttributeType,
+ AttributeValue }
+
+AttributeType ::= OBJECT IDENTIFIER
+
+AttributeValue ::= ANY
+
+The Name type identifies an object in an X.500 directory.
+Name is a CHOICE type consisting of one alternative:
+RDNSequence. (Future revisions of X.500 may have other
+alternatives.)
+
+The RDNSequence type gives a path through an X.500 directory
+tree starting at the root. RDNSequence is a SEQUENCE OF type
+consisting of zero or more occurences of
+RelativeDistinguishedName.
+
+The RelativeDistinguishedName type gives a unique name to an
+object relative to the object superior to it in the
+directory tree. RelativeDistinguishedName is a SET OF type
+consisting of zero or more occurrences of
+AttributeValueAssertion.
+
+The AttributeValueAssertion type assigns a value to some
+attribute of a relative distinguished name, such as country
+name or common name. AttributeValueAssertion is a SEQUENCE
+type consisting of two components, an AttributeType type and
+an AttributeValue type.
+
+The AttributeType type identifies an attribute by object
+identifier. The AttributeValue type gives an arbitrary
+attribute value. The actual type of the attribute value is
+determined by the attribute type.
+
+
+6.2 DER encoding
+
+This section gives an example of a DER encoding of a value
+of type Name, working from the bottom up.
+
+The name is that of the Test User 1 from the PKCS examples
+[Kal93]. The name is represented by the following path:
+
+ (root)
+ |
+ countryName = "US"
+ |
+ organizationName = "Example Organization"
+ |
+ commonName = "Test User 1"
+
+Each level corresponds to one RelativeDistinguishedName
+value, each of which happens for this name to consist of one
+AttributeValueAssertion value. The AttributeType value is
+before the equals sign, and the AttributeValue value (a
+printable string for the given attribute types) is after the
+equals sign.
+
+The countryName, organizationName, and commonUnitName are
+attribute types defined in X.520 as:
+
+attributeType OBJECT IDENTIFIER ::=
+ { joint-iso-ccitt(2) ds(5) 4 }
+
+countryName OBJECT IDENTIFIER ::= { attributeType 6 }
+organizationName OBJECT IDENTIFIER ::=
+ { attributeType 10 }
+commonUnitName OBJECT IDENTIFIER ::=
+ { attributeType 3 }
+
+
+6.2.1 AttributeType
+
+The three AttributeType values are OCTET STRING values, so
+their DER encoding follows the primitive, definite-length
+method:
+
+06 03 55 04 06 countryName
+
+06 03 55 04 0a organizationName
+
+06 03 55 04 03 commonName
+
+The identifier octets follow the low-tag form, since the tag
+is 6 for OBJECT IDENTIFIER. Bits 8 and 7 have value "0,"
+indicating universal class, and bit 6 has value "0,"
+indicating that the encoding is primitive. The length octets
+follow the short form. The contents octets are the
+concatenation of three octet strings derived from
+subidentifiers (in decimal): 40 * 2 + 5 = 85 = 5516; 4; and
+6, 10, or 3.
+
+
+6.2.2 AttributeValue
+
+The three AttributeValue values are PrintableString values,
+so their encodings follow the primitive, definite-length
+method:
+
+13 02 55 53 "US"
+
+13 14 "Example Organization"
+ 45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61
+ 74 69 6f 6e
+
+13 0b "Test User 1"
+ 54 65 73 74 20 55 73 65 72 20 31
+
+The identifier octets follow the low-tag-number form, since
+the tag for PrintableString, 19 (decimal), is between 0 and
+30. Bits 8 and 7 have value "0" since PrintableString is in
+the universal class. Bit 6 has value "0" since the encoding
+is primitive. The length octets follow the short form, and
+the contents octets are the ASCII representation of the
+attribute value.
+
+
+6.2.3 AttributeValueAssertion
+
+The three AttributeValueAssertion values are SEQUENCE
+values, so their DER encodings follow the constructed,
+definite-length method:
+
+30 09 countryName = "US"
+ 06 03 55 04 06
+ 13 02 55 53
+
+30 1b organizationName = "Example Organizaiton"
+ 06 03 55 04 0a
+ 13 14 ... 6f 6e
+
+30 12 commonName = "Test User 1"
+ 06 03 55 04 0b
+ 13 0b ... 20 31
+
+The identifier octets follow the low-tag-number form, since
+the tag for SEQUENCE, 16 (decimal), is between 0 and 30.
+Bits 8 and 7 have value "0" since SEQUENCE is in the
+universal class. Bit 6 has value "1" since the encoding is
+constructed. The length octets follow the short form, and
+the contents octets are the concatenation of the DER
+encodings of the attributeType and attributeValue
+components.
+
+
+6.2.4 RelativeDistinguishedName
+
+The three RelativeDistinguishedName values are SET OF
+values, so their DER encodings follow the constructed,
+definite-length method:
+
+31 0b
+ 30 09 ... 55 53
+
+31 1d
+ 30 1b ... 6f 6e
+
+31 14
+ 30 12 ... 20 31
+
+The identifier octets follow the low-tag-number form, since
+the tag for SET OF, 17 (decimal), is between 0 and 30. Bits
+8 and 7 have value "0" since SET OF is in the universal
+class Bit 6 has value "1" since the encoding is constructed.
+The lengths octets follow the short form, and the contents
+octets are the DER encodings of the respective
+AttributeValueAssertion values, since there is only one
+value in each set.
+
+
+6.2.5 RDNSequence
+
+The RDNSequence value is a SEQUENCE OF value, so its DER
+encoding follows the constructed, definite-length method:
+
+30 42
+ 31 0b ... 55 53
+ 31 1d ... 6f 6e
+ 31 14 ... 20 31
+
+The identifier octets follow the low-tag-number form, since
+the tag for SEQUENCE OF, 16 (decimal), is between 0 and 30.
+Bits 8 and 7 have value "0" since SEQUENCE OF is in the
+universal class. Bit 6 has value "1" since the encoding is
+constructed. The lengths octets follow the short form, and
+the contents octets are the concatenation of the DER
+encodings of the three RelativeDistinguishedName values, in
+order of occurrence.
+
+
+6.2.6 Name
+
+The Name value is a CHOICE value, so its DER encoding is the
+same as that of the RDNSequence value:
+
+30 42
+ 31 0b
+ 30 09
+ 06 03 55 04 06 attributeType = countryName
+ 13 02 55 53 attributeValue = "US"
+ 31 1d
+ 30 1b
+ 06 03 55 04 0a attributeType = organizationName
+ 13 14 attributeValue = "Example Organization"
+ 45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61
+ 74 69 6f 6e
+
+ 31 14
+ 30 12
+ 06 03 55 04 03 attributeType = commonName
+ 13 0b attributeValue = "Test User 1"
+ 54 65 73 74 20 55 73 65 72 20 31
+
+
+References
+
+PKCS #1 RSA Laboratories. PKCS #1: RSA Encryption
+ Standard. Version 1.5, November 1993.
+
+PKCS #3 RSA Laboratories. PKCS #3: Diffie-Hellman Key-
+ Agreement Standard. Version 1.4, November 1993.
+
+PKCS #5 RSA Laboratories. PKCS #5: Password-Based
+ Encryption Standard. Version 1.5, November 1993.
+
+PKCS #6 RSA Laboratories. PKCS #6: Extended-Certificate
+ Syntax Standard. Version 1.5, November 1993.
+
+PKCS #7 RSA Laboratories. PKCS #7: Cryptographic Message
+ Syntax Standard. Version 1.5, November 1993.
+
+PKCS #8 RSA Laboratories. PKCS #8: Private-Key Information
+ Syntax Standard. Version 1.2, November 1993.
+
+PKCS #9 RSA Laboratories. PKCS #9: Selected Attribute
+ Types. Version 1.1, November 1993.
+
+PKCS #10 RSA Laboratories. PKCS #10: Certification Request
+ Syntax Standard. Version 1.0, November 1993.
+
+X.200 CCITT. Recommendation X.200: Reference Model of
+ Open Systems Interconnection for CCITT
+ Applications. 1984.
+
+X.208 CCITT. Recommendation X.208: Specification of
+ Abstract Syntax Notation One (ASN.1). 1988.
+
+X.209 CCITT. Recommendation X.209: Specification of
+ Basic Encoding Rules for Abstract Syntax Notation
+ One (ASN.1). 1988.
+
+X.500 CCITT. Recommendation X.500: The
+ Directory--Overview of Concepts, Models and
+ Services. 1988.
+
+X.501 CCITT. Recommendation X.501: The Directory--
+ Models. 1988.
+
+X.509 CCITT. Recommendation X.509: The Directory--
+ Authentication Framework. 1988.
+
+X.520 CCITT. Recommendation X.520: The Directory--
+ Selected Attribute Types. 1988.
+
+[Kal93] Burton S. Kaliski Jr. Some Examples of the PKCS
+ Standards. RSA Laboratories, November 1993.
+
+[NIST92] NIST. Special Publication 500-202: Stable
+ Implementation Agreements for Open Systems
+ Interconnection Protocols. Part 11 (Directory
+ Services Protocols). December 1992.
+
+
+Revision history
+
+
+June 3, 1991 version
+
+The June 3, 1991 version is part of the initial public
+release of PKCS. It was published as NIST/OSI Implementors'
+Workshop document SEC-SIG-91-17.
+
+
+November 1, 1993 version
+
+The November 1, 1993 version incorporates several editorial
+changes, including the addition of a revision history. It is
+updated to be consistent with the following versions of the
+PKCS documents:
+
+ PKCS #1: RSA Encryption Standard. Version 1.5, November
+ 1993.
+
+ PKCS #3: Diffie-Hellman Key-Agreement Standard. Version
+ 1.4, November 1993.
+
+ PKCS #5: Password-Based Encryption Standard. Version
+ 1.5, November 1993.
+
+ PKCS #6: Extended-Certificate Syntax Standard. Version
+ 1.5, November 1993.
+
+ PKCS #7: Cryptographic Message Syntax Standard. Version
+ 1.5, November 1993.
+
+ PKCS #8: Private-Key Information Syntax Standard.
+ Version 1.2, November 1993.
+
+ PKCS #9: Selected Attribute Types. Version 1.1,
+ November 1993.
+
+ PKCS #10: Certification Request Syntax Standard.
+ Version 1.0, November 1993.
+
+The following substantive changes were made:
+
+ Section 5: Description of T61String type is added.
+
+ Section 6: Names are changed, consistent with other
+ PKCS examples.
+
+
+Author's address
+
+Burton S. Kaliski Jr., Ph.D.
+Chief Scientist
+RSA Laboratories (415) 595-7703
+100 Marine Parkway (415) 595-4126 (fax)
+Redwood City, CA 94065 USA burt@rsa.com
diff --git a/crypto/heimdal/doc/mdate-sh b/crypto/heimdal/doc/mdate-sh
new file mode 100755
index 000000000000..37171f21fbd9
--- /dev/null
+++ b/crypto/heimdal/doc/mdate-sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# Get the extended ls output of the file or directory.
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+ set - x`ls -L -l -d $1`
+else
+ set - x`ls -l -d $1`
+fi
+# The month is at least the fourth argument
+# (3 shifts here, the next inside the loop).
+shift
+shift
+shift
+
+# Find the month. Next argument is day, followed by the year or time.
+month=
+until test $month
+do
+ shift
+ case $1 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+ esac
+done
+
+day=$2
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+ *:*) set `date`; eval year=\$$#
+ case $2 in
+ Jan) nummonthtod=1;;
+ Feb) nummonthtod=2;;
+ Mar) nummonthtod=3;;
+ Apr) nummonthtod=4;;
+ May) nummonthtod=5;;
+ Jun) nummonthtod=6;;
+ Jul) nummonthtod=7;;
+ Aug) nummonthtod=8;;
+ Sep) nummonthtod=9;;
+ Oct) nummonthtod=10;;
+ Nov) nummonthtod=11;;
+ Dec) nummonthtod=12;;
+ esac
+ # For the first six month of the year the time notation can also
+ # be used for files modified in the last year.
+ if (expr $nummonth \> $nummonthtod) > /dev/null;
+ then
+ year=`expr $year - 1`
+ fi;;
+ *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
diff --git a/crypto/heimdal/doc/misc.texi b/crypto/heimdal/doc/misc.texi
new file mode 100644
index 000000000000..e926536ef97d
--- /dev/null
+++ b/crypto/heimdal/doc/misc.texi
@@ -0,0 +1,62 @@
+@node Things in search for a better place, Kerberos 4 issues, Setting up a realm, Top
+@chapter Things in search for a better place
+
+@section Making things work on Ciscos
+
+Modern versions of Cisco IOS has some support for authenticating via
+Kerberos 5. This can be used both to verify passwords via a ticket
+exchange Kerberos 5 (boring), and to use Kerberos authenticated telnet
+to access your router (less boring). The following has been tested on
+IOS 11.2(12), things might be different with other versions. Old
+versions are known to have bugs.
+
+To make this work, you will first have to configure your router to use
+Kerberos (this is explained in the documentation). A sample
+configuration looks like the following:
+
+@example
+aaa new-model
+aaa authentication login default krb5-telnet krb5 enable
+aaa authorization exec krb5-instance
+kerberos local-realm FOO.SE
+kerberos srvtab entry host/router.foo.se 0 891725446 4 1 8 012345678901234567
+kerberos server FOO.SE 10.0.0.1
+kerberos instance map admin 15
+@end example
+
+This tells you (among other things) that the when logging in, the router
+should try to authenticate with kerberized telnet, and if that fails try
+to verify a plain text password via a Kerberos ticket exchange (as
+opposed to a local database or RADIUS or something similar), and if that
+fails try the local enable password. If you're not careful when you
+specify the `login default' authentication mechanism, you might not be
+able to login. The `instance map' and `authorization exec' lines says
+that people with `admin' instances should be given `enabled' shells when
+logging in.
+
+To make the Heimdal KDC produce tickets that the Cisco can decode you
+might have to turn on the @samp{encode_as_rep_as_tgs_rep} flag in the
+KDC. You will also have to specify that the router can't handle anything
+but @samp{des-cbc-crc}. There currently isn't an easy way to do
+this. The best you can do is to dump your database (with @samp{kadmin -l
+dump}), remove all entries for keys other than @samp{des-cbc-crc}, and
+then reloading the database (@samp{kadmin -l load}). An example should
+clarify this. You should have something like (again, truncated):
+@example
+host/router.foo.se@@FOO.SE 4:0:1:...:-:... - - - - - - - 126
+@end example
+Change this to:
+@example
+host/router.foo.se@@FOO.SE 4:0:1:...:- - - - - - - - 126
+@end example
+
+This all fine and so, but unless you have an IOS version with encryption
+(available only in the U.S) it doesn't really solve any problems. Sure
+you don't have to send your password over the wire, but since the telnet
+connection isn't protected it's still possible for someone to steal your
+session. This won't be fixed until someone adds integrity to the telnet
+protocol.
+
+A working solution would be to hook up a machine with a real operating
+system to the console of the Cisco and then use it as a backwards
+terminal server.
diff --git a/crypto/heimdal/doc/setup.texi b/crypto/heimdal/doc/setup.texi
new file mode 100644
index 000000000000..a43eb7e81e36
--- /dev/null
+++ b/crypto/heimdal/doc/setup.texi
@@ -0,0 +1,247 @@
+@node Setting up a realm, Things in search for a better place, Building and Installing, Top
+@chapter Setting up a realm
+
+A
+@cindex realm
+realm is an administrative domain. The name of a Kerberos realm is
+usually the Internet domain name in uppercase. Call your realm the same
+as your Internet domain name if you do not have strong reasons for not
+doing so. It will make life easier for you and everyone else.
+
+@section Configuration file
+
+To setup a realm you will first have to create a configuration file:
+@file{/etc/krb5.conf}. The @file{krb5.conf} file can contain many
+configuration options, some of which are described here.
+
+There is a sample @file{krb5.conf} supplied with the distribution.
+
+The configuration file is a hierarchical structure consisting of
+sections, each containing a list of bindings (either variable
+assignments or subsections). A section starts with
+@samp{[section-name]}. A binding consists of a left hand side, an equal
+(@samp{=}) and a right hand side (the left hand side tag must be
+separated from the equal with some whitespace.) Subsections has a
+@samp{@{} as the first non-whitespace character after the equal. All
+other bindings are treated as variable assignments. The value of a
+variable extends to the end of the line.
+
+@example
+[section1]
+ a-subsection = @{
+ var = value1
+ other-var = value with @{@}
+ sub-sub-section = @{
+ var = 123
+ @}
+ @}
+ var = some other value
+[section2]
+ var = yet another value
+@end example
+
+In this manual, names of sections and bindings will be given as strings
+separated by slashes (@samp{/}). The @samp{other-var} variable will thus
+be @samp{section1/a-subsection/other-var}.
+
+For in-depth information about the contents of the config file, refer to
+the @file{krb5.conf} manual page. Some of the more important sections
+are briefly described here.
+
+The @samp{libdefaults} section contains a list of library configuration
+parameters, such as the default realm and the timeout for kdc
+responses. The @samp{realms} section contains information about specific
+realms, such as where they hide their KDC. This section serves the same
+purpose as the Kerberos 4 @file{krb.conf} file, but can contain more
+information. Finally the @samp{domain_realm} section contains a list of
+mappings from domains to realms, equivalent to the Kerberos 4
+@file{krb.realms} file.
+
+To continue with the realm setup, you will have to create a config file,
+with contents similar to the following.
+
+@example
+[libdefaults]
+ default_realm = MY.REALM
+[realms]
+ MY.REALM = @{
+ kdc = my.kdc
+ @}
+[domain_realm]
+ .my.domain = MY.REALM
+
+@end example
+
+If you use a realm name equal to your domain name, you can omit the
+@samp{libdefaults}, and @samp{domain_realm}, sections. If you have a
+SRV-record for your realm, or your kerberos server has CNAME called
+@samp{kerberos.my.realm}, you can omit the @samp{realms} section too.
+
+@section Creating the database
+
+The database library will look for the database in @file{/var/heimdal},
+so you should probably create that directory.
+
+The keys of all the principals are stored in the database. If you
+choose to, these can be encrypted with a master key. You do not have to
+remember this key (or password), but just to enter it once and it will
+be stored in a file (@file{/var/heimdal/m-key}). If you want to have a
+master key, run @samp{kstash} to create this master key:
+
+@example
+# kstash
+Master key:
+Verifying password - Master key:
+@end example
+
+To initialise the database use the @code{kadmin} program, with the
+@samp{-l} option (to enable local database mode). First issue a
+@kbd{init MY.REALM} command. This will create the database and insert
+default principals for that realm. You can have more than one realm in
+one database, so @samp{init} does not destroy any old database.
+
+Before creating the database, @samp{init} will ask you some questions
+about max ticket lifetimes.
+
+After creating the database you should probably add yourself to it. You
+do this with the @samp{add} command. It takes as argument the name of a
+principal. The principal should contain a realm, so if you haven't setup
+a default realm, you will need to explicitly include the realm.
+
+@example
+# kadmin -l
+kadmin> init MY.REALM
+Realm max ticket life [unlimited]:
+Realm max renewable ticket life [unlimited]:
+kadmin> add me
+Max ticket life [unlimited]:
+Max renewable life [unlimited]:
+Attributes []:
+Password:
+Verifying password - Password:
+@end example
+
+Now start the KDC and try getting a ticket.
+
+@example
+# kdc &
+# kinit me
+me@@MY.REALMS's Password:
+# klist
+Credentials cache: /tmp/krb5cc_0
+ Principal: me@@MY.REALM
+
+ Issued Expires Principal
+Aug 25 07:25:55 Aug 25 17:25:55 krbtgt/MY.REALM@@MY.REALM
+@end example
+
+If you are curious you can use the @samp{dump} command to list all the
+entries in the database. It should look something similar to the
+following example (note that the entries here are truncated for
+typographical reasons):
+
+@smallexample
+kadmin> dump
+me@@MY.REALM 1:0:1:0b01d3cb7c293b57:-:0:7:8aec316b9d1629e3baf8 ...
+kadmin/admin@@MY.REALM 1:0:1:e5c8a2675b37a443:-:0:7:cb913ebf85 ...
+krbtgt/MY.REALM@@MY.REALM 1:0:1:52b53b61c875ce16:-:0:7:c8943be ...
+kadmin/changepw@@MY.REALM 1:0:1:f48c8af2b340e9fb:-:0:7:e3e6088 ...
+@end smallexample
+
+@section keytabs
+
+To extract a service ticket from the database and put it in a keytab you
+need to first create the principal in the database with @samp{ank}
+(using the @kbd{--random} flag to get a random password) and then
+extract it with @samp{ext_keytab}.
+
+@example
+kadmin> add --random host/my.host.name
+Max ticket life [unlimited]:
+Max renewable life [unlimited]:
+Attributes []:
+kadmin> ext host/my.host.name
+# ktutil list
+Version Type Principal
+ 1 des-cbc-md5 host/my.host.name@@MY.REALM
+ 1 des-cbc-md4 host/my.host.name@@MY.REALM
+ 1 des-cbc-crc host/my.host.name@@MY.REALM
+ 1 des3-cbc-sha1 host/my.host.name@@MY.REALM
+@end example
+
+@section Remote administration
+
+The administration server, @samp{kadmind}, is started by @samp{inetd}
+and you should add a line similar to the one below to your
+@file{/etc/inetd.conf}.
+
+@example
+kerberos-adm stream tcp nowait root /usr/heimdal/libexec/kadmind kadmind
+@end example
+
+You might need to add @samp{kerberos-adm} to your @file{/etc/services}
+as 749/tcp.
+
+Access to the admin server is controlled by an acl-file, (default
+@file{/var/heimdal/kadmind.acl}.) The lines in the access file, has the
+following syntax:
+@smallexample
+principal [priv1,priv2,...]
+@end smallexample
+
+The privileges you can assign to a principal are: @samp{add},
+@samp{change-password} (or @samp{cpw} for short), @samp{delete},
+@samp{get}, @samp{list}, and @samp{modify}, or the special privilege
+@samp{all}. All of these roughly corresponds to the different commands
+in @samp{kadmin}.
+
+@section Password changing
+
+To allow users to change their passwords, you should run @samp{kpasswdd}.
+It is not run from @samp{inetd}.
+
+You might need to add @samp{kpasswd} to your @file{/etc/services} as
+464/udp.
+
+@subsection Password quality assurance
+
+It is important that users have good passwords, both to make it harder
+to guess them and to avoid off-line attacks (pre-authentication provides
+some defense against off-line attacks). To ensure that the users choose
+good passwords, you can enable password quality controls in
+@samp{kpasswdd}. The controls themselves are done in a shared library
+that is used by @samp{kpasswdd}. To configure in these controls, add
+lines similar to the following to your @file{/etc/krb5.conf}:
+
+@example
+[password_quality]
+ check_library = @var{library}
+ check_function = @var{function}
+@end example
+
+The function @var{function} in the shared library @var{library} will be
+called for proposed new passwords. The function should be declared as:
+
+@example
+const char *
+function(krb5_context context, krb5_principal principal, krb5_data *pwd);
+@end example
+
+The function should verify that @var{pwd} is a good password for
+@var{principal} and if so return @code{NULL}. If it is deemed to be of
+low quality, it should return a string explaining why that password
+should not be used.
+
+Code for a password quality checking function that uses the cracklib
+library can be found in @file{kpasswd/sample_password_check.c} in the
+source code distribution. It requires the cracklib library built with
+the patch available at
+@url{ftp://ftp.pdc.kth.se/pub/krb/src/cracklib.patch}.
+
+If no password quality checking function is configured, it is only
+verified that it is at least six characters of length.
+
+@section Testing clients and servers
+
+Now you should be able to run all the clients and servers. Refer to the
+appropriate man pages for information on how to use them.
diff --git a/crypto/heimdal/doc/standardisation/draft-brezak-win2k-krb-rc4-hmac-01.txt b/crypto/heimdal/doc/standardisation/draft-brezak-win2k-krb-rc4-hmac-01.txt
new file mode 100644
index 000000000000..a97ef9d191e0
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-brezak-win2k-krb-rc4-hmac-01.txt
@@ -0,0 +1,412 @@
+CAT working group M. Swift
+Internet Draft J. Brezak
+Document: draft-brezak-win2k-krb-rc4-hmac-01.txt Microsoft
+Category: Informational October 1999
+
+
+ The Windows 2000 RC4-HMAC Kerberos encryption type
+
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of RFC2026 [1]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts. Internet-Drafts are
+ draft documents valid for a maximum of six months and may be
+ updated, replaced, or obsoleted by other documents at any time. It
+ is inappropriate to use Internet- Drafts as reference material or to
+ cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html.
+
+1. Abstract
+
+ The Windows 2000 implementation of Kerberos introduces a new
+ encryption type based on the RC4 encryption algorithm and using an
+ MD5 HMAC for checksum. This is offered as an alternative to using
+ the existing DES based encryption types.
+
+ The RC4-HMAC encryption types are used to ease upgrade of existing
+ Windows NT environments, provide strong crypto (128-bit key
+ lengths), and provide exportable (meet United States government
+ export restriction requirements) encryption.
+
+ The Windows 2000 implementation of Kerberos contains new encryption
+ and checksum types for two reasons: for export reasons early in the
+ development process, 56 bit DES encryption could not be exported,
+ and because upon upgrade from Windows NT 4.0 to Windows 2000,
+ accounts will not have the appropriate DES keying material to do the
+ standard DES encryption. Furthermore, 3DES is not available for
+ export, and there was a desire to use a single flavor of encryption
+ in the product for both US and international products.
+
+ As a result, there are two new encryption types and one new checksum
+ type introduced in Windows 2000.
+
+
+2. Conventions used in this document
+
+
+
+Swift Category - Informational 1
+
+ Windows 2000 RC4-HMAC Kerberos E-Type October 1999
+
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in
+ this document are to be interpreted as described in RFC-2119 [2].
+
+3. Key Generation
+
+ On upgrade from existing Windows NT domains, the user accounts would
+ not have a DES based key available to enable the use of DES base
+ encryption types specified in RFC 1510. The key used for RC4-HMAC is
+ the same as the existing Windows NT key (NT Password Hash) for
+ compatibility reasons. Once the account password is changed, the DES
+ based keys are created and maintained. Once the DES keys are
+ available DES based encryption types can be used with Kerberos.
+
+ The RC4-HMAC String to key function is defined as follow:
+
+ String2Key(password)
+
+ K = MD4(UNICODE(password))
+
+ The RC4-HMAC keys are generated by using the Windows UNICODE version
+ of the password. Each Windows UNICODE character is encoded in
+ little-endian format of 2 octets each. Then performing an MD4 [6]
+ hash operation on just the UNICODE characters of the password (not
+ including the terminating zero octets).
+
+4. Basic Operations
+
+ The MD5 HMAC function is defined in [3]. It is used in this
+ encryption type for checksum operations. Refer to [3] for details on
+ its operation. In this document this function is referred to as
+ HMAC(Key, Data) returning the checksum using the specified key on
+ the data.
+
+ The basic MD5 hash operation is used in this encryption type and
+ defined in [7]. In this document this function is referred to as
+ MD5(Data) returning the checksum of the data.
+
+ The basic RC4 encryption operation is used in this encryption type
+ and defined in [8]. In this document the function is referred to as
+ RC4(Key, Data) returning the encrypted data using the specified key
+ on the data.
+
+ These encryption types use key derivation as defined in [9] (RFC-
+ 1510BIS) in Section titled "Key Derivation". With each message, the
+ message type (T) is used as a component of the keying material.
+
+ All strings in this document are ASCII unless otherwise specified.
+ The lengths of ASCII encoded character strings include the trailing
+ terminator character (0).
+
+ The concat(a,b,c,...) function will return the logical concatenation
+ (left to right) of the values of the arguments.
+
+Swift Category - Informational 2
+
+ Windows 2000 RC4-HMAC Kerberos E-Type October 1999
+
+
+
+ The nonce(n) function returns a pseudo-random number of "n" octets.
+
+5. Checksum Types
+
+ There is one checksum type used in this encryption type. The
+ Kerberos constant for this type is:
+ #define KERB_CHECKSUM_HMAC_MD5 (-138)
+
+ The function is defined as follows:
+
+ K - is the Key
+ T - the message type, encoded as a little-endian four byte integer
+
+ CHKSUM(K, T, data)
+
+ Ksign = HMAC(K, "signature key") //includes zero octet at end
+ tmp = MD5(concat(T, data))
+ CHKSUM = HMAC(Ksign, tmp)
+
+
+6. Encryption Types
+
+ There are two encryption types used in these encryption types. The
+ Kerberos constants for these types are:
+ #define KERB_ETYPE_RC4_HMAC 23
+ #define KERB_ETYPE_RC4_HMAC_EXP 24
+
+ The basic encryption function is defined as follow:
+
+ T = the message type, encoded as a little-endian four byte integer.
+
+ ENCRYPT(K, T, data)
+ if (K.enctype == KERB_ETYPE_RC4_HMAC_EXP)
+ L = concat("fortybits", T) //includes zero octet at
+ //end of string constant
+ Else
+ L = T
+ Ksign = HMAC(K,L)
+ Confounder = nonce(8) // get an 8 octet nonce for a confounder
+ Checksum = HMAC(Ksign, concat(Confounder, data))
+ Ke = Ksign
+ if (K.enctype == KERB_ETYPE_RC4_HMAC_EXP)
+ memset(&Ke[7], 0x0ab, 9)
+ Ke2 = HMAC(Ke, Checksum)
+ data = RC4(Ke2, data)
+
+ The header field on the encrypted data in KDC messages is:
+
+ typedef struct _RC4_MDx_HEADER {
+ UCHAR Checksum[16];
+ UCHAR Confounder[8];
+ } RC4_MDx_HEADER, *PRC4_MDx_HEADER;
+
+Swift Category - Informational 3
+
+ Windows 2000 RC4-HMAC Kerberos E-Type October 1999
+
+
+
+ The character constant "fortybits" evolved from the time when a 40-
+ bit key length was all that was exportable from the United States.
+ It is now used to recognize that the key length is of "exportable"
+ length. In this description, the key size is actually 56-bits.
+
+7. Key Strength Negotiation
+
+ A Kerberos client and server can negotiate over key length if they
+ are using mutual authentication. If the client is unable to perform
+ full strength encryption, it may propose a key in the "subkey" field
+ of the authenticator, using a weaker encryption type. The server
+ must then either return the same key or suggest its own key in the
+ subkey field of the AP reply message. The key used to encrypt data
+ is derived from the key returned by the server. If the client is
+ able to perform strong encryption but the server is not, it may
+ propose a subkey in the AP reply without first being sent a subkey
+ in the authenticator.
+
+8. GSSAPI Kerberos V5 Mechanism Type
+
+8.1 Mechanism Specific Changes
+
+ The GSSAPI per-message tokens also require new checksum and
+ encryption types. The GSS-API per-message tokens must be changed to
+ support these new encryption types (See [5] Section 1.2.2). The
+ sealing algorithm identifier (SEAL_ALG) for an RC4 based encryption
+ is:
+ Byte 4..5 SEAL_ALG 0x10 0x00 - RC4
+
+ The signing algorithm identifier (SGN_ALG) for MD5 HMAC is:
+ Byte 2..3 SGN ALG 0x11 0x00 - HMAC
+
+ The only support quality of protection is:
+ #define GSS_KRB5_INTEG_C_QOP_DEFAULT 0x0
+
+ In addition, when using an RC4 based encryption type, the sequence
+ number is sent in big-endian rather than little-endian order.
+
+8.2 GSSAPI Checksum Type
+
+ The GSSAPI checksum type and algorithm is defined in Section 5. Only
+ the first 8 octets of the checksum are used. The resulting checksum
+ is stored in the SGN_CKSUM field (See [5] Section 1.2) for
+ GSS_GetMIC() and GSS_Wrap(conf_flag=FALSE).
+
+8.3 GSSAPI Encryption Types
+
+ There are two encryption types for GSSAPI message tokens, one that
+ is 128 bits in strength, and one that is 56 bits in strength as
+ defined in Section 6.
+
+
+
+Swift Category - Informational 4
+
+ Windows 2000 RC4-HMAC Kerberos E-Type October 1999
+
+
+ All padding is rounded up to 1 byte. One byte is needed to say that
+ there is 1 byte of padding. The DES based mechanism type uses 8 byte
+ padding. See [5] Section 1.2.2.3.
+
+ The encryption mechanism used for GSS based messages is as follow:
+
+ T = the message type, encoded as a little-endian four byte integer.
+
+ GSS-ENCRYPT(K, T, data)
+ IV = SND_SEQ
+ K = XOR(K, 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0)
+ if (K.enctype == KERB_ETYPE_RC4_HMAC_EXP)
+ L = concat("fortybits", T) //includes zero octet at end
+ else
+ L = T
+ Ksign = HMAC(K, L)
+ Ke = Ksign
+ if (K.enctype == KERB_ETYPE_RC4_HMAC_EXP)
+ memset(&Ke[7], 0x0ab, 9)
+ Ke2 = HMAC(Ke, IV)
+ Data = RC4(Ke2, data)
+ SND_SEQ = RC4(Ke, seq#)
+
+ The sequence number (SND_SEQ) and IV are used as defined in [5]
+ Section 1.2.2.
+
+ The character constant "fortybits" evolved from the time when a 40-
+ bit key length was all that was exportable from the United States.
+ It is now used to recognize that the key length is of "exportable"
+ length. In this description, the key size is actually 56-bits.
+
+8. Security Considerations
+
+ Care must be taken in implementing this encryption type because it
+ uses a stream cipher. If a different IV isnÆt used in each direction
+ when using a session key, the encryption is weak. By using the
+ sequence number as an IV, this is avoided.
+
+9. References
+
+ 1 Bradner, S., "The Internet Standards Process -- Revision 3", BCP
+ 9, RFC 2026, October 1996.
+
+ 2 Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997
+
+ 3 Krawczyk, H., Bellare, M., Canetti, R.,"HMAC: Keyed-Hashing for
+ Message Authentication", RFC 2104, February 1997
+
+ 4 Kohl, J., Neuman, C., "The Kerberos Network Authentication
+ Service (V5)", RFC 1510, September 1993
+
+
+
+Swift Category - Informational 5
+
+ Windows 2000 RC4-HMAC Kerberos E-Type October 1999
+
+
+
+ 5 Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC-1964,
+ June 1996
+
+ 6 R. Rivest, "The MD4 Message-Digest Algorithm", RFC-1320, April
+ 1992
+
+ 7 R. Rivest, "The MD5 Message-Digest Algorithm", RFC-1321, April
+ 1992
+
+ 8 RC4 is a proprietary encryption algorithm available under license
+ from RSA Data Security Inc. For licensing information,
+ contact:
+ RSA Data Security, Inc.
+ 100 Marine Parkway
+ Redwood City, CA 94065-1031
+
+ 9 Neuman, C., Kohl, J., Ts'o, T., "The Kerberos Network
+ Authentication Service (V5)", draft-ietf-cat-kerberos-revisions-
+ 04.txt, June 25, 1999
+
+
+10. Author's Addresses
+
+ Mike Swift
+ Microsoft
+ One Microsoft Way
+ Redmond, Washington
+ Email: mikesw@microsoft.com
+
+ John Brezak
+ Microsoft
+ One Microsoft Way
+ Redmond, Washington
+ Email: jbrezak@microsoft.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Swift Category - Informational 6
+
+ Windows 2000 RC4-HMAC Kerberos E-Type October 1999
+
+
+
+11. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph
+ are included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Swift Category - Informational 7
+ \ No newline at end of file
diff --git a/crypto/heimdal/doc/standardisation/draft-foo b/crypto/heimdal/doc/standardisation/draft-foo
new file mode 100644
index 000000000000..8174d4678f8d
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-foo
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+Network Working Group Assar Westerlund
+<draft-ietf-cat-krb5-ipv6.txt> SICS
+Internet-Draft October, 1997
+Expire in six months
+
+ Kerberos over IPv6
+
+Status of this Memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its areas,
+ and its working groups. Note that other groups may also distribute
+ working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet- Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ To view the entire list of current Internet-Drafts, please check the
+ "1id-abstracts.txt" listing contained in the Internet-Drafts Shadow
+ Directories on ftp.is.co.za (Africa), ftp.nordu.net (Europe),
+ munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
+ ftp.isi.edu (US West Coast).
+
+ Distribution of this memo is unlimited. Please send comments to the
+ <cat-ietf@mit.edu> mailing list.
+
+Abstract
+
+ This document specifies the address types and transport types
+ necessary for using Kerberos [RFC1510] over IPv6 [RFC1883].
+
+Specification
+
+ IPv6 addresses are 128-bit (16-octet) quantities, encoded in MSB
+ order. The type of IPv6 addresses is twenty-four (24).
+
+ The following addresses (see [RFC1884]) MUST not appear in any
+ Kerberos packet:
+
+ the Unspecified Address
+ the Loopback Address
+ Link-Local addresses
+
+ IPv4-mapped IPv6 addresses MUST be represented as addresses of type
+ 2.
+
+
+
+
+Westerlund [Page 1]
+
+Internet Draft Kerberos over IPv6 October, 1997
+
+
+ Communication with the KDC over IPv6 MUST be done as in section 8.2.1
+ of [RFC1510].
+
+Discussion
+
+ [RFC1510] suggests using the address family constants in
+ <sys/socket.h> from BSD. This cannot be done for IPv6 as these
+ numbers have diverged and are different on different BSD-derived
+ systems. [RFC2133] does not either specify a value for AF_INET6.
+ Thus a value has to be decided and the implementations have to
+ convert between the value used in Kerberos HostAddress and the local
+ AF_INET6.
+
+ There are a few different address types in IPv6, see [RFC1884]. Some
+ of these are used for quite special purposes and it makes no sense to
+ include them in Kerberos packets.
+
+ It is necessary to represent IPv4-mapped addresses as Internet
+ addresses (type 2) to be compatible with Kerberos implementations
+ that only support IPv4.
+
+Security considerations
+
+ This memo does not introduce any known security considerations in
+ addition to those mentioned in [RFC1510].
+
+References
+
+ [RFC1510] Kohl, J. and Neuman, C., "The Kerberos Network
+ Authentication Service (V5)", RFC 1510, September 1993.
+
+ [RFC1883] Deering, S., Hinden, R., "Internet Protocol, Version 6
+ (IPv6) Specification", RFC 1883, December 1995.
+
+ [RFC1884] Hinden, R., Deering, S., "IP Version 6 Addressing
+ Architecture", RFC 1884, December 1995.
+
+ [RFC2133] Gilligan, R., Thomson, S., Bound, J., Stevens, W., "Basic
+ Socket Interface Extensions for IPv6", RFC2133, April 1997.
+
+Author's Address
+
+ Assar Westerlund
+ Swedish Institute of Computer Science
+ Box 1263
+ S-164 29 KISTA
+ Sweden
+
+
+
+
+Westerlund [Page 2]
+
+Internet Draft Kerberos over IPv6 October, 1997
+
+
+ Phone: +46-8-7521526
+ Fax: +46-8-7517230
+ EMail: assar@sics.se
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Westerlund [Page 3]
+
diff --git a/crypto/heimdal/doc/standardisation/draft-foo.ms b/crypto/heimdal/doc/standardisation/draft-foo.ms
new file mode 100644
index 000000000000..62b109afa52c
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-foo.ms
@@ -0,0 +1,136 @@
+.pl 10.0i
+.po 0
+.ll 7.2i
+.lt 7.2i
+.nr LL 7.2i
+.nr LT 7.2i
+.ds LF Westerlund
+.ds RF [Page %]
+.ds CF
+.ds LH Internet Draft
+.ds RH October, 1997
+.ds CH Kerberos over IPv6
+.hy 0
+.ad l
+.in 0
+.ta \n(.luR
+Network Working Group Assar Westerlund
+<draft-ietf-cat-krb5-ipv6.txt> SICS
+Internet-Draft October, 1997
+Expire in six months
+
+.ce
+Kerberos over IPv6
+
+.ti 0
+Status of this Memo
+
+.in 3
+This document is an Internet-Draft. Internet-Drafts are working
+documents of the Internet Engineering Task Force (IETF), its
+areas, and its working groups. Note that other groups may also
+distribute working documents as Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum of six
+months and may be updated, replaced, or obsoleted by other
+documents at any time. It is inappropriate to use Internet-
+Drafts as reference material or to cite them other than as
+"work in progress."
+
+To view the entire list of current Internet-Drafts, please check
+the "1id-abstracts.txt" listing contained in the Internet-Drafts
+Shadow Directories on ftp.is.co.za (Africa), ftp.nordu.net
+(Europe), munnari.oz.au (Pacific Rim), ds.internic.net (US East
+Coast), or ftp.isi.edu (US West Coast).
+
+Distribution of this memo is unlimited. Please send comments to the
+<cat-ietf@mit.edu> mailing list.
+
+.ti 0
+Abstract
+
+.in 3
+This document specifies the address types and transport types
+necessary for using Kerberos [RFC1510] over IPv6 [RFC1883].
+
+.ti 0
+Specification
+
+.in 3
+IPv6 addresses are 128-bit (16-octet) quantities, encoded in MSB
+order. The type of IPv6 addresses is twenty-four (24).
+
+The following addresses (see [RFC1884]) MUST not appear in any
+Kerberos packet:
+
+the Unspecified Address
+.br
+the Loopback Address
+.br
+Link-Local addresses
+
+IPv4-mapped IPv6 addresses MUST be represented as addresses of type 2.
+
+Communication with the KDC over IPv6 MUST be done as in section
+8.2.1 of [RFC1510].
+
+.ti 0
+Discussion
+
+.in 3
+[RFC1510] suggests using the address family constants in
+<sys/socket.h> from BSD. This cannot be done for IPv6 as these
+numbers have diverged and are different on different BSD-derived
+systems. [RFC2133] does not either specify a value for AF_INET6.
+Thus a value has to be decided and the implementations have to convert
+between the value used in Kerberos HostAddress and the local AF_INET6.
+
+There are a few different address types in IPv6, see [RFC1884]. Some
+of these are used for quite special purposes and it makes no sense to
+include them in Kerberos packets.
+
+It is necessary to represent IPv4-mapped addresses as Internet
+addresses (type 2) to be compatible with Kerberos implementations that
+only support IPv4.
+
+.ti 0
+Security considerations
+
+.in 3
+This memo does not introduce any known security considerations in
+addition to those mentioned in [RFC1510].
+
+.ti 0
+References
+
+.in 3
+[RFC1510] Kohl, J. and Neuman, C., "The Kerberos Network
+Authentication Service (V5)", RFC 1510, September 1993.
+
+[RFC1883] Deering, S., Hinden, R., "Internet Protocol, Version 6
+(IPv6) Specification", RFC 1883, December 1995.
+
+[RFC1884] Hinden, R., Deering, S., "IP Version 6 Addressing
+Architecture", RFC 1884, December 1995.
+
+[RFC2133] Gilligan, R., Thomson, S., Bound, J., Stevens, W., "Basic
+Socket Interface Extensions for IPv6", RFC2133, April 1997.
+
+.ti 0
+Author's Address
+
+Assar Westerlund
+.br
+Swedish Institute of Computer Science
+.br
+Box 1263
+.br
+S-164 29 KISTA
+.br
+Sweden
+
+Phone: +46-8-7521526
+.br
+Fax: +46-8-7517230
+.br
+EMail: assar@sics.se
diff --git a/crypto/heimdal/doc/standardisation/draft-foo2 b/crypto/heimdal/doc/standardisation/draft-foo2
new file mode 100644
index 000000000000..0fa695f640f8
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-foo2
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+Network Working Group Assar Westerlund
+<draft-ietf-cat-krb5-tcp.txt> SICS
+Internet-Draft Johan Danielsson
+November, 1997 PDC, KTH
+Expire in six months
+
+ Kerberos over TCP
+
+Status of this Memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its areas,
+ and its working groups. Note that other groups may also distribute
+ working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet- Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ To view the entire list of current Internet-Drafts, please check the
+ "1id-abstracts.txt" listing contained in the Internet-Drafts Shadow
+ Directories on ftp.is.co.za (Africa), ftp.nordu.net (Europe),
+ munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
+ ftp.isi.edu (US West Coast).
+
+ Distribution of this memo is unlimited. Please send comments to the
+ <cat-ietf@mit.edu> mailing list.
+
+Abstract
+
+ This document specifies how the communication should be done between
+ a client and a KDC using Kerberos [RFC1510] with TCP as the transport
+ protocol.
+
+Specification
+
+ This draft specifies an extension to section 8.2.1 of RFC1510.
+
+ A Kerberos server MAY accept requests on TCP port 88 (decimal).
+
+ The data sent from the client to the KDC should consist of 4 bytes
+ containing the length, in network byte order, of the Kerberos
+ request, followed by the request (AS-REQ or TGS-REQ) itself. The
+ reply from the KDC should consist of the length of the reply packet
+ (4 bytes, network byte order) followed by the packet itself (AS-REP,
+ TGS-REP, or KRB-ERROR).
+
+
+
+
+Westerlund, Danielsson [Page 1]
+
+Internet Draft Kerberos over TCP November, 1997
+
+
+ C->S: Open connection to TCP port 88 at the server
+ C->S: length of request
+ C->S: AS-REQ or TGS-REQ
+ S->C: length of reply
+ S->C: AS-REP, TGS-REP, or KRB-ERROR
+
+Discussion
+
+ Even though the preferred way of sending kerberos packets is over UDP
+ there are several occasions when it's more practical to use TCP.
+
+ Mainly, it's usually much less cumbersome to get TCP through
+ firewalls than UDP.
+
+ In theory, there's no reason for having explicit length fields, that
+ information is already encoded in the ASN1 encoding of the Kerberos
+ packets. But having explicit lengths makes it unnecessary to have to
+ decode the ASN.1 encoding just to know how much data has to be read.
+
+ Another way of signaling the end of the request of the reply would be
+ to do a half-close after the request and a full-close after the
+ reply. This does not work well with all kinds of firewalls.
+
+Security considerations
+
+ This memo does not introduce any known security considerations in
+ addition to those mentioned in [RFC1510].
+
+References
+
+ [RFC1510] Kohl, J. and Neuman, C., "The Kerberos Network
+ Authentication Service (V5)", RFC 1510, September 1993.
+
+Authors' Addresses
+
+ Assar Westerlund
+ Swedish Institute of Computer Science
+ Box 1263
+ S-164 29 KISTA
+ Sweden
+
+ Phone: +46-8-7521526
+ Fax: +46-8-7517230
+ EMail: assar@sics.se
+
+ Johan Danielsson
+ PDC, KTH
+ S-100 44 STOCKHOLM
+
+
+
+Westerlund, Danielsson [Page 2]
+
+Internet Draft Kerberos over TCP November, 1997
+
+
+ Sweden
+
+ Phone: +46-8-7907885
+ Fax: +46-8-247784
+ EMail: joda@pdc.kth.se
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Westerlund, Danielsson [Page 3]
+
diff --git a/crypto/heimdal/doc/standardisation/draft-foo2.ms b/crypto/heimdal/doc/standardisation/draft-foo2.ms
new file mode 100644
index 000000000000..7e0fa0a6281b
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-foo2.ms
@@ -0,0 +1,145 @@
+.pl 10.0i
+.po 0
+.ll 7.2i
+.lt 7.2i
+.nr LL 7.2i
+.nr LT 7.2i
+.ds LF Westerlund, Danielsson
+.ds RF [Page %]
+.ds CF
+.ds LH Internet Draft
+.ds RH November, 1997
+.ds CH Kerberos over TCP
+.hy 0
+.ad l
+.in 0
+.ta \n(.luR
+.nf
+Network Working Group Assar Westerlund
+<draft-ietf-cat-krb5-tcp.txt> SICS
+Internet-Draft Johan Danielsson
+November, 1997 PDC, KTH
+Expire in six months
+.fi
+
+.ce
+Kerberos over TCP
+
+.ti 0
+Status of this Memo
+
+.in 3
+This document is an Internet-Draft. Internet-Drafts are working
+documents of the Internet Engineering Task Force (IETF), its
+areas, and its working groups. Note that other groups may also
+distribute working documents as Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum of six
+months and may be updated, replaced, or obsoleted by other
+documents at any time. It is inappropriate to use Internet-
+Drafts as reference material or to cite them other than as
+"work in progress."
+
+To view the entire list of current Internet-Drafts, please check
+the "1id-abstracts.txt" listing contained in the Internet-Drafts
+Shadow Directories on ftp.is.co.za (Africa), ftp.nordu.net
+(Europe), munnari.oz.au (Pacific Rim), ds.internic.net (US East
+Coast), or ftp.isi.edu (US West Coast).
+
+Distribution of this memo is unlimited. Please send comments to the
+<cat-ietf@mit.edu> mailing list.
+
+.ti 0
+Abstract
+
+.in 3
+This document specifies how the communication should be done between a
+client and a KDC using Kerberos [RFC1510] with TCP as the transport
+protocol.
+
+.ti 0
+Specification
+
+This draft specifies an extension to section 8.2.1 of RFC1510.
+
+A Kerberos server MAY accept requests on TCP port 88 (decimal).
+
+The data sent from the client to the KDC should consist of 4 bytes
+containing the length, in network byte order, of the Kerberos request,
+followed by the request (AS-REQ or TGS-REQ) itself. The reply from
+the KDC should consist of the length of the reply packet (4 bytes,
+network byte order) followed by the packet itself (AS-REP, TGS-REP, or
+KRB-ERROR).
+
+.nf
+C->S: Open connection to TCP port 88 at the server
+C->S: length of request
+C->S: AS-REQ or TGS-REQ
+S->C: length of reply
+S->C: AS-REP, TGS-REP, or KRB-ERROR
+.fi
+
+.ti 0
+Discussion
+
+Even though the preferred way of sending kerberos packets is over UDP
+there are several occasions when it's more practical to use TCP.
+
+Mainly, it's usually much less cumbersome to get TCP through firewalls
+than UDP.
+
+In theory, there's no reason for having explicit length fields, that
+information is already encoded in the ASN1 encoding of the Kerberos
+packets. But having explicit lengths makes it unnecessary to have to
+decode the ASN.1 encoding just to know how much data has to be read.
+
+Another way of signaling the end of the request of the reply would be
+to do a half-close after the request and a full-close after the reply.
+This does not work well with all kinds of firewalls.
+
+.ti 0
+Security considerations
+
+.in 3
+This memo does not introduce any known security considerations in
+addition to those mentioned in [RFC1510].
+
+.ti 0
+References
+
+.in 3
+[RFC1510] Kohl, J. and Neuman, C., "The Kerberos Network
+Authentication Service (V5)", RFC 1510, September 1993.
+
+.ti 0
+Authors' Addresses
+
+Assar Westerlund
+.br
+Swedish Institute of Computer Science
+.br
+Box 1263
+.br
+S-164 29 KISTA
+.br
+Sweden
+
+Phone: +46-8-7521526
+.br
+Fax: +46-8-7517230
+.br
+EMail: assar@sics.se
+
+Johan Danielsson
+.br
+PDC, KTH
+.br
+S-100 44 STOCKHOLM
+.br
+Sweden
+
+Phone: +46-8-7907885
+.br
+Fax: +46-8-247784
+.br
+EMail: joda@pdc.kth.se
diff --git a/crypto/heimdal/doc/standardisation/draft-foo3 b/crypto/heimdal/doc/standardisation/draft-foo3
new file mode 100644
index 000000000000..2b8b7bb5775c
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-foo3
@@ -0,0 +1,227 @@
+
+
+
+
+
+
+Network Working Group Assar Westerlund
+<draft-ietf-cat-krb5-firewalls.txt> SICS
+Internet-Draft Johan Danielsson
+November, 1997 PDC, KTH
+Expire in six months
+
+ Kerberos vs firewalls
+
+Status of this Memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its areas,
+ and its working groups. Note that other groups may also distribute
+ working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet- Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ To view the entire list of current Internet-Drafts, please check the
+ "1id-abstracts.txt" listing contained in the Internet-Drafts Shadow
+ Directories on ftp.is.co.za (Africa), ftp.nordu.net (Europe),
+ munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
+ ftp.isi.edu (US West Coast).
+
+ Distribution of this memo is unlimited. Please send comments to the
+ <cat-ietf@mit.edu> mailing list.
+
+Abstract
+
+Introduction
+
+ Kerberos[RFC1510] is a protocol for authenticating parties
+ communicating over insecure networks.
+
+ Firewalling is a technique for achieving an illusion of security by
+ putting restrictions on what kinds of packets and how these are sent
+ between the internal (so called "secure") network and the global (or
+ "insecure") Internet.
+
+Definitions
+
+ client: the user, process, and host acquiring tickets from the KDC
+ and authenticating itself to the kerberised server.
+
+ KDC: the Kerberos Key Distribution Center
+
+
+
+
+Westerlund, Danielsson [Page 1]
+
+Internet Draft Kerberos vs firewalls November, 1997
+
+
+ Kerberised server: the server using Kerberos to authenticate the
+ client, for example telnetd.
+
+Firewalls
+
+ A firewall is usually placed between the "inside" and the "outside"
+ networks, and is supposed to protect the inside from the evils on the
+ outside. There are different kinds of firewalls. The main
+ differences are in the way they forward packets.
+
+ o+ The most straight forward type is the one that just imposes
+ restrictions on incoming packets. Such a firewall could be
+ described as a router that filters packets that match some
+ criteria.
+
+ o+ They may also "hide" some or all addresses on the inside of the
+ firewall, replacing the addresses in the outgoing packets with the
+ address of the firewall (aka network address translation, or NAT).
+ NAT can also be used without any packet filtering, for instance
+ when you have more than one host sharing a single address (for
+ example, with a dialed-in PPP connection).
+
+ There are also firewalls that does NAT both on the inside and the
+ outside (a server on the inside will see this as a connection from
+ the firewall).
+
+ o+ A third type is the proxy type firewall, that parses the contents
+ of the packets, basically acting as a server to the client, and as
+ a client to the server (man-in-the-middle). If Kerberos is to be
+ used with this kind of firewall, a protocol module that handles
+ KDC requests has to be written.
+
+ This type of firewall might also cause extra trouble when used with
+ kerberised versions of protocols that the proxy understands, in
+ addition to the ones mentioned below. This is the case with the FTP
+ Security Extensions [RFC2228], that adds a new set of commands to the
+ FTP protocol [RFC959], for integrity, confidentiality, and privacy
+ protecting commands. When transferring data, the FTP protocol uses a
+ separate data channel, and an FTP proxy will have to look out for
+ commands that start a data transfer. If all commands are encrypted,
+ this is impossible. A protocol that doesn't suffer from this is the
+ Telnet Authentication Option [RFC1416] that does all authentication
+ and encryption in-bound.
+
+Scenarios
+
+ Here the different scenarios we have considered are described, the
+ problems they introduce and the proposed ways of solving them.
+
+
+
+Westerlund, Danielsson [Page 2]
+
+Internet Draft Kerberos vs firewalls November, 1997
+
+
+ Combinations of these can also occur.
+
+ Client behind firewall
+
+ This is the most typical and common scenario. First of all the
+ client needs some way of communicating with the KDC. This can be
+ done with whatever means and is usually much simpler when the KDC is
+ able to communicate over TCP.
+
+ Apart from that, the client needs to be sure that the ticket it will
+ acquire from the KDC can be used to authenticate to a server outside
+ its firewall. For this, it needs to add the address(es) of potential
+ firewalls between itself and the KDC/server, to the list of its own
+ addresses when requesting the ticket. We are not aware of any
+ protocol for determining this set of addresses, thus this will have
+ to be manually configured in the client.
+
+ The client could also request a ticket with no addresses, but some
+ KDCs and servers might not accept such a ticket.
+
+ With the ticket in possession, communication with the kerberised
+ server will not need to be any different from communicating between a
+ non-kerberised client and server.
+
+ Kerberised server behind firewall
+
+ The kerberised server does not talk to the KDC at all so nothing
+ beyond normal firewall-traversal techniques for reaching the server
+ itself needs to be applied.
+
+ The kerberised server needs to be able to retrieve the original
+ address (before its firewall) that the request was sent for. If this
+ is done via some out-of-band mechanism or it's directly able to see
+ it doesn't matter.
+
+ KDC behind firewall
+
+ The same restrictions applies for a KDC as for any other server.
+
+Specification
+
+Security considerations
+
+ This memo does not introduce any known security considerations in
+ addition to those mentioned in [RFC1510].
+
+References
+
+
+
+
+Westerlund, Danielsson [Page 3]
+
+Internet Draft Kerberos vs firewalls November, 1997
+
+
+ [RFC959] Postel, J. and Reynolds, J., "File Transfer Protocol (FTP)",
+ RFC 969, October 1985
+
+ [RFC1416] Borman, D., "Telnet Authentication Option", RFC 1416,
+ February 1993.
+
+ [RFC1510] Kohl, J. and Neuman, C., "The Kerberos Network
+ Authentication Service (V5)", RFC 1510, September 1993.
+
+ [RFC2228] Horowitz, M. and Lunt, S., "FTP Security Extensions",
+ RFC2228, October 1997.
+
+Authors' Addresses
+
+ Assar Westerlund
+ Swedish Institute of Computer Science
+ Box 1263
+ S-164 29 KISTA
+ Sweden
+
+ Phone: +46-8-7521526
+ Fax: +46-8-7517230
+ EMail: assar@sics.se
+
+ Johan Danielsson
+ PDC, KTH
+ S-100 44 STOCKHOLM
+ Sweden
+
+ Phone: +46-8-7907885
+ Fax: +46-8-247784
+ EMail: joda@pdc.kth.se
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Westerlund, Danielsson [Page 4]
+
diff --git a/crypto/heimdal/doc/standardisation/draft-foo3.ms b/crypto/heimdal/doc/standardisation/draft-foo3.ms
new file mode 100644
index 000000000000..c024ca355cd4
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-foo3.ms
@@ -0,0 +1,260 @@
+.\" even if this file is called .ms, it's using the me macros.
+.\" to format try something like `nroff -me'
+.\" level 2 heading
+.de HH
+.$p "\\$2" "" "\\$1"
+.$0 "\\$2"
+..
+.\" make sure footnotes produce the right thing with nroff
+.ie t \
+\{\
+.ds { \v'-0.4m'\x'\\n(0x=0*-0.2m'\s-3
+.ds } \s0\v'0.4m'
+.\}
+.el \
+\{\
+.ds { [
+.ds } ]
+.\}
+.ds * \\*{\\n($f\\*}\k*
+.\" page footer
+.fo 'Westerlund, Danielsson''[Page %]'
+.\" date
+.ds RH \*(mo, 19\n(yr
+.\" left margin
+.nr lm 6
+.\" heading indent per level
+.nr si 3n
+.\" footnote indent
+.nr fi 0
+.\" paragraph indent
+.nr po 0
+.\" don't hyphenate
+.hy 0
+.\" left adjustment
+.ad l
+.\" indent 0
+.in 0
+.\" line length 16cm and page length 25cm (~10 inches)
+.ll 16c
+.pl 25c
+.ta \n(.luR
+.nf
+Network Working Group Assar Westerlund
+<draft-ietf-cat-krb5-firewalls.txt> SICS
+Internet-Draft Johan Danielsson
+\*(RH PDC, KTH
+Expire in six months
+.fi
+
+.\" page header, has to be set here so it won't appear on page 1
+.he 'Internet Draft'Kerberos vs firewalls'\*(RH'
+.ce
+.b "Kerberos vs firewalls"
+
+.HH 1 "Status of this Memo"
+.lp
+This document is an Internet-Draft. Internet-Drafts are working
+documents of the Internet Engineering Task Force (IETF), its areas,
+and its working groups. Note that other groups may also distribute
+working documents as Internet-Drafts.
+.lp
+Internet-Drafts are draft documents valid for a maximum of six months
+and may be updated, replaced, or obsoleted by other documents at any
+time. It is inappropriate to use Internet- Drafts as reference
+material or to cite them other than as \*(lqwork in progress.\*(rq
+.lp
+To view the entire list of current Internet-Drafts, please check the
+\*(lq1id-abstracts.txt\*(rq listing contained in the Internet-Drafts
+Shadow Directories on ftp.is.co.za (Africa), ftp.nordu.net (Europe),
+munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
+ftp.isi.edu (US West Coast).
+.lp
+Distribution of this memo is unlimited. Please send comments to the
+<cat-ietf@mit.edu> mailing list.
+.HH 1 "Abstract"
+.lp
+Kerberos and firewalls both deal with security, but doesn't get along
+very well. This memo discusses ways to use Kerberos in a firewalled
+environment.
+.HH 1 "Introduction"
+.lp
+Kerberos[RFC1510]
+.(d
+[RFC1510]
+Kohl, J. and Neuman, C., \*(lqThe Kerberos Network Authentication
+Service (V5)\*(rq, RFC 1510, September 1993.
+.)d
+is a protocol for authenticating parties communicating over insecure
+networks. Firewalling is a technique for achieving an illusion of
+security by putting restrictions on what kinds of packets and how
+these are sent between the internal (so called \*(lqsecure\*(rq)
+network and the global (or \*(lqinsecure\*(rq) Internet. The problems
+with firewalls are many, but to name a few:
+.np
+Firewalls usually doesn't allow people to use UDP. The reason for this
+is that UDP is (by firewall advocates) considered insecure. This
+belief is probably based on the fact that many \*(lqinsecure\*(rq
+protocols (like NFS) use UDP. UDP packets are also considered easy to
+fake.
+.np
+Firewalls usually doesn't allow people to connect to arbitrary ports,
+such as the ports used when talking to the KDC.
+.np
+In many non-computer organisations, the computer staff isn't what
+you'd call \*(lqwizards\*(rq; a typical case is an academic
+institution, where someone is taking care of the computers part time,
+and is doing research the rest of the time. Adding a complex device
+like a firewall to an environment like this, often leads to poorly run
+systems that is more a hindrance for the legitimate users than to
+possible crackers.
+.lp
+The easiest way to deal with firewalls is to ignore them, however in
+some cases this just isn't possible. You might have users that are
+stuck behind a firewall, but also has to access your system, or you
+might find yourself behind a firewall, for instance when out
+travelling.
+.lp
+To make it possible for people to use Kerberos from behind a firewall,
+there are several things to consider.
+.(q
+.i
+Add things to do when stuck behind a firewall, like talking about the
+problem with local staff, making them open some port in the firewall,
+using some other port, or proxy.
+.r
+.)q
+.HH 1 "Firewalls"
+.lp
+A firewall is usually placed between the \*(lqinside\*(rq and the
+\*(lqoutside\*(rq networks, and is supposed to protect the inside from the
+evils on the outside. There are different kinds of firewalls. The
+main differences are in the way they forward (or doesn't) packets.
+.ip \(bu
+The most straight forward type is the one that just imposes
+restrictions on incoming packets. Such a firewall could be described
+as a router that filters packets that match some criteria.
+.ip \(bu
+They may also \*(lqhide\*(rq some or all addresses on the inside of the
+firewall, replacing the addresses in the outgoing packets with the
+address of the firewall (aka network address translation, or NAT). NAT
+can also be used without any packet filtering, for instance when you
+have more than one host sharing a single address (e.g with a dialed-in
+PPP connection).
+.ip
+There are also firewalls that does NAT both on the inside and the
+outside (a server on the inside will see this as a connection from the
+firewall).
+.ip \(bu
+A third type is the proxy type firewall, that parses the contents of
+the packets, basically acting as a server to the client, and as a
+client to the server (man-in-the-middle). If Kerberos is to be used
+with this kind of firewall, a protocol module that handles KDC
+requests has to be written\**.
+.(f
+\**Instead of writing a new module for Kerberos, it can be possible to
+hitch a ride on some other protocol, that's already beeing handled by
+the proxy.
+.)f
+.lp
+The last type of firewall might also cause extra trouble when used
+with kerberised versions of protocols that the proxy understands, in
+addition to the ones mentioned below. This is the case with the FTP
+Security Extensions [RFC2228],
+.(d
+[RFC2228]
+Horowitz, M. and Lunt, S., \*(lqFTP Security Extensions\*(rq, RFC2228,
+October 1997.
+.)d
+that adds a new set of commands to the FTP protocol [RFC959],
+.(d
+[RFC959] Postel, J. and Reynolds, J., \*(lqFile Transfer Protocol
+(FTP)\*(rq, RFC 969, October 1985
+.)d
+for integrity, confidentiality, and privacy protecting commands, and
+data. When transferring data, the FTP protocol uses a separate data
+channel, and an FTP proxy will have to look out for commands that
+start a data transfer. If all commands are encrypted, this is
+impossible. A protocol that doesn't suffer from this is the Telnet
+Authentication Option [RFC1416]
+.(d
+[RFC1416]
+Borman, D., \*(lqTelnet Authentication Option\*(rq, RFC 1416, February
+1993.
+.)d
+that does all
+authentication and encryption in-bound.
+.HH 1 "Scenarios"
+.lp
+Here the different scenarios we have considered are described, the
+problems they introduce and the proposed ways of solving them.
+Combinations of these can also occur.
+.HH 2 "Client behind firewall"
+.lp
+This is the most typical and common scenario. First of all the client
+needs some way of communicating with the KDC. This can be done with
+whatever means and is usually much simpler when the KDC is able to
+communicate over TCP.
+.lp
+Apart from that, the client needs to be sure that the ticket it will
+acquire from the KDC can be used to authenticate to a server outside
+its firewall. For this, it needs to add the address(es) of potential
+firewalls between itself and the KDC/server, to the list of its own
+addresses when requesting the ticket. We are not aware of any
+protocol for determining this set of addresses, thus this will have to
+be manually configured in the client.
+.lp
+The client could also request a ticket with no addresses. This is not
+a recommended way to solve this problem. The address was put into the
+ticket to make it harder to use a stolen ticket. A ticket without
+addresses will therefore be less \*(lqsecure.\*(rq RFC1510 also says that
+the KDC may refuse to issue, and the server may refuse to accept an
+address-less ticket.
+.lp
+With the ticket in possession, communication with the kerberised
+server will not need to be any different from communicating between a
+non-kerberised client and server.
+.HH 2 "Kerberised server behind firewall"
+.lp
+The kerberised server does not talk to the KDC at all, so nothing
+beyond normal firewall-traversal techniques for reaching the server
+itself needs to be applied.
+.lp
+If the firewall rewrites the clients address, the server will have to
+use some other (possibly firewall specific) protocol to retrieve the
+original address. If this is not possible, the address field will have
+to be ignored. This has the same effect as if there were no addresses
+in the ticket (see the discussion above).
+.HH 2 "KDC behind firewall"
+.lp
+The KDC is in this respect basically just like any other server.
+.\" .uh "Specification"
+.HH 1 "Security considerations"
+.lp
+Since the whole network behind a NAT-type firewall looks like one
+computer from the outside, any security added by the addresses in the
+ticket will be lost.
+.HH 1 "References"
+.lp
+.pd
+.HH 1 "Authors' Addresses"
+.lp
+.nf
+Assar Westerlund
+Swedish Institute of Computer Science
+Box 1263
+S-164 29 KISTA
+.sp
+Phone: +46-8-7521526
+Fax: +46-8-7517230
+EMail: assar@sics.se
+.sp 2
+Johan Danielsson
+Center for Parallel Computers
+KTH
+S-100 44 STOCKHOLM
+.sp
+Phone: +46-8-7906356
+Fax: +46-8-247784
+EMail: joda@pdc.kth.se
+.fi \ No newline at end of file
diff --git a/crypto/heimdal/doc/standardisation/draft-horowitz-key-derivation-01.txt b/crypto/heimdal/doc/standardisation/draft-horowitz-key-derivation-01.txt
new file mode 100644
index 000000000000..4dcff486b936
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-horowitz-key-derivation-01.txt
@@ -0,0 +1,244 @@
+Network Working Group M. Horowitz
+<draft-horowitz-key-derivation-01.txt> Cygnus Solutions
+Internet-Draft March, 1997
+
+
+ Key Derivation for Authentication, Integrity, and Privacy
+
+Status of this Memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its areas,
+ and its working groups. Note that other groups may also distribute
+ working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as ``work in progress.''
+
+ To learn the current status of any Internet-Draft, please check the
+ ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
+ Directories on ds.internic.net (US East Coast), nic.nordu.net
+ (Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific
+ Rim).
+
+ Distribution of this memo is unlimited. Please send comments to the
+ author.
+
+Abstract
+
+ Recent advances in cryptography have made it desirable to use longer
+ cryptographic keys, and to make more careful use of these keys. In
+ particular, it is considered unwise by some cryptographers to use the
+ same key for multiple purposes. Since most cryptographic-based
+ systems perform a range of functions, such as authentication, key
+ exchange, integrity, and encryption, it is desirable to use different
+ cryptographic keys for these purposes.
+
+ This RFC does not define a particular protocol, but defines a set of
+ cryptographic transformations for use with arbitrary network
+ protocols and block cryptographic algorithm.
+
+
+Deriving Keys
+
+ In order to use multiple keys for different functions, there are two
+ possibilities:
+
+ - Each protocol ``key'' contains multiple cryptographic keys. The
+ implementation would know how to break up the protocol ``key'' for
+ use by the underlying cryptographic routines.
+
+ - The protocol ``key'' is used to derive the cryptographic keys.
+ The implementation would perform this derivation before calling
+
+
+
+Horowitz [Page 1]
+
+Internet Draft Key Derivation March, 1997
+
+
+ the underlying cryptographic routines.
+
+ In the first solution, the system has the opportunity to provide
+ separate keys for different functions. This has the advantage that
+ if one of these keys is broken, the others remain secret. However,
+ this comes at the cost of larger ``keys'' at the protocol layer. In
+ addition, since these ``keys'' may be encrypted, compromising the
+ cryptographic key which is used to encrypt them compromises all the
+ component keys. Also, the not all ``keys'' are used for all possible
+ functions. Some ``keys'', especially those derived from passwords,
+ are generated from limited amounts of entropy. Wasting some of this
+ entropy on cryptographic keys which are never used is unwise.
+
+ The second solution uses keys derived from a base key to perform
+ cryptographic operations. By carefully specifying how this key is
+ used, all of the advantages of the first solution can be kept, while
+ eliminating some disadvantages. In particular, the base key must be
+ used only for generating the derived keys, and this derivation must
+ be non-invertible and entropy-preserving. Given these restrictions,
+ compromise of one derived keys does not compromise the other subkeys.
+ Attack of the base key is limited, since it is only used for
+ derivation, and is not exposed to any user data.
+
+ Since the derived key has as much entropy as the base keys (if the
+ cryptosystem is good), password-derived keys have the full benefit of
+ all the entropy in the password.
+
+ To generate a derived key from a base key:
+
+ Derived Key = DK(Base Key, Well-Known Constant)
+
+ where
+
+ DK(Key, Constant) = n-truncate(E(Key, Constant))
+
+ In this construction, E(Key, Plaintext) is a block cipher, Constant
+ is a well-known constant defined by the protocol, and n-truncate
+ truncates its argument by taking the first n bits; here, n is the key
+ size of E.
+
+ If the output of E is is shorter than n bits, then some entropy in
+ the key will be lost. If the Constant is smaller than the block size
+ of E, then it must be padded so it may be encrypted. If the Constant
+ is larger than the block size, then it must be folded down to the
+ block size to avoid chaining, which affects the distribution of
+ entropy.
+
+ In any of these situations, a variation of the above construction is
+ used, where the folded Constant is encrypted, and the resulting
+ output is fed back into the encryption as necessary (the | indicates
+ concatentation):
+
+ K1 = E(Key, n-fold(Constant))
+ K2 = E(Key, K1)
+
+
+
+Horowitz [Page 2]
+
+Internet Draft Key Derivation March, 1997
+
+
+ K3 = E(Key, K2)
+ K4 = ...
+
+ DK(Key, Constant) = n-truncate(K1 | K2 | K3 | K4 ...)
+
+ n-fold is an algorithm which takes m input bits and ``stretches''
+ them to form n output bits with no loss of entropy, as described in
+ [Blumenthal96]. In this document, n-fold is always used to produce n
+ bits of output, where n is the key size of E.
+
+ If the size of the Constant is not equal to the block size of E, then
+ the Constant must be n-folded to the block size of E. This number is
+ used as input to E. If the block size of E is less than the key
+ size, then the output from E is taken as input to a second invocation
+ of E. This process is repeated until the number of bits accumulated
+ is greater than or equal to the key size of E. When enough bits have
+ been computed, the first n are taken as the derived key.
+
+ Since the derived key is the result of one or more encryptions in the
+ base key, deriving the base key from the derived key is equivalent to
+ determining the key from a very small number of plaintext/ciphertext
+ pairs. Thus, this construction is as strong as the cryptosystem
+ itself.
+
+
+Deriving Keys from Passwords
+
+ When protecting information with a password or other user data, it is
+ necessary to convert an arbitrary bit string into an encryption key.
+ In addition, it is sometimes desirable that the transformation from
+ password to key be difficult to reverse. A simple variation on the
+ construction in the prior section can be used:
+
+ Key = DK(n-fold(Password), Well-Known Constant)
+
+ The n-fold algorithm is reversible, so recovery of the n-fold output
+ is equivalent to recovery of Password. However, recovering the n-
+ fold output is difficult for the same reason recovering the base key
+ from a derived key is difficult.
+
+
+
+ Traditionally, the transformation from plaintext to ciphertext, or
+ vice versa, is determined by the cryptographic algorithm and the key.
+ A simple way to think of derived keys is that the transformation is
+ determined by the cryptographic algorithm, the constant, and the key.
+
+ For interoperability, the constants used to derive keys for different
+ purposes must be specified in the protocol specification. The
+ constants must not be specified on the wire, or else an attacker who
+ determined one derived key could provide the associated constant and
+ spoof data using that derived key, rather than the one the protocol
+ designer intended.
+
+
+
+
+Horowitz [Page 3]
+
+Internet Draft Key Derivation March, 1997
+
+
+ Determining which parts of a protocol require their own constants is
+ an issue for the designer of protocol using derived keys.
+
+
+Security Considerations
+
+ This entire document deals with security considerations relating to
+ the use of cryptography in network protocols.
+
+
+Acknowledgements
+
+ I would like to thank Uri Blumenthal, Hugo Krawczyk, and Bill
+ Sommerfeld for their contributions to this document.
+
+
+References
+
+ [Blumenthal96] Blumenthal, U., "A Better Key Schedule for DES-Like
+ Ciphers", Proceedings of PRAGOCRYPT '96, 1996.
+
+
+Author's Address
+
+ Marc Horowitz
+ Cygnus Solutions
+ 955 Massachusetts Avenue
+ Cambridge, MA 02139
+
+ Phone: +1 617 354 7688
+ Email: marc@cygnus.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Horowitz [Page 4]
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-gssv2-08.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-gssv2-08.txt
new file mode 100644
index 000000000000..ccba35eeb4ab
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-gssv2-08.txt
@@ -0,0 +1,62 @@
+
+
+A new Request for Comments is now available in online RFC libraries.
+
+
+ RFC 2078
+
+ Title: Generic Security Service Application Program
+ Interface, Version 2
+ Author: J. Linn
+ Date: January 1997
+ Mailbox: John.Linn@ov.com
+ Pages: 85
+ Characters: 185990
+ Obsoletes: 1508
+
+ URL: ftp://ds.internic.net/rfc/rfc2078.txt
+
+
+This memo revises RFC-1508, making specific, incremental changes in
+response to implementation experience and liaison requests. It is
+intended, therefore, that this memo or a successor version thereto
+will become the basis for subsequent progression of the GSS-API
+specification on the standards track. This document is a product of
+the Common Authentication Technology Working Group.
+
+This is now a Proposed Standard Protocol.
+
+This document specifies an Internet standards track protocol for the
+Internet community, and requests discussion and suggestions for
+improvements. Please refer to the current edition of the "Internet
+Official Protocol Standards" (STD 1) for the standardization state and
+status of this protocol. Distribution of this memo is unlimited.
+
+This announcement is sent to the IETF list and the RFC-DIST list.
+Requests to be added to or deleted from the IETF distribution list
+should be sent to IETF-REQUEST@CNRI.RESTON.VA.US. Requests to be
+added to or deleted from the RFC-DIST distribution list should
+be sent to RFC-DIST-REQUEST@ISI.EDU.
+
+Details on obtaining RFCs via FTP or EMAIL may be obtained by sending
+an EMAIL message to rfc-info@ISI.EDU with the message body
+help: ways_to_get_rfcs. For example:
+
+ To: rfc-info@ISI.EDU
+ Subject: getting rfcs
+
+ help: ways_to_get_rfcs
+
+Requests for special distribution should be addressed to either the
+author of the RFC in question, or to admin@DS.INTERNIC.NET. Unless
+specifically noted otherwise on the RFC itself, all RFCs are for
+unlimited distribution.
+
+Submissions for Requests for Comments should be sent to
+RFC-EDITOR@ISI.EDU. Please consult RFC 1543, Instructions to RFC
+Authors, for further information.
+
+
+Joyce K. Reynolds and Mary Kennedy
+USC/Information Sciences Institute
+
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-gssv2-cbind-04.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-gssv2-cbind-04.txt
new file mode 100644
index 000000000000..518f4c63d171
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-gssv2-cbind-04.txt
@@ -0,0 +1,6188 @@
+
+ Internet draft J.Wray
+ IETF Common Authentication Technology WG Digital Equipment Corporation
+ <draft-ietf-cat-gssv2-cbind-04.txt> March 1997
+
+
+
+ Generic Security Service API Version 2 : C-bindings
+
+
+ 1. STATUS OF THIS MEMO
+
+ This document is an Internet Draft. Internet Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its Areas, and
+ its Working Groups. Note that other groups may also distribute working
+ documents as Internet Drafts. Internet Drafts are draft documents valid
+ for a maximum of six months. Internet Drafts may be updated, replaced,
+ or obsoleted by other documents at any time. It is not appropriate to
+ use Internet Drafts as reference material or to cite them other than as
+ a "working draft" or "work in progress." Please check the I-D abstract
+ listing contained in each Internet Draft directory to learn the current
+ status of this or any other Internet Draft.
+
+ Comments on this document should be sent to "cat-ietf@MIT.EDU", the IETF
+ Common Authentication Technology WG discussion list.
+
+
+ 2. ABSTRACT
+
+ This draft document specifies C language bindings for Version 2 of the
+ Generic Security Service Application Program Interface (GSSAPI), which
+ is described at a language-independent conceptual level in other drafts
+ [GSSAPI]. It revises RFC-1509, making specific incremental changes in
+ response to implementation experience and liaison requests. It is
+ intended, therefore, that this draft or a successor version thereof will
+ become the basis for subsequent progression of the GSS-API specification
+ on the standards track.
+
+ The Generic Security Service Application Programming Interface provides
+ security services to its callers, and is intended for implementation
+ atop a variety of underlying cryptographic mechanisms. Typically,
+ GSSAPI callers will be application protocols into which security
+ enhancements are integrated through invocation of services provided by
+ the GSSAPI. The GSSAPI allows a caller application to authenticate a
+ principal identity associated with a peer application, to delegate
+ rights to a peer, and to apply security services such as confidentiality
+ and integrity on a per-message basis.
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 1]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 3. INTRODUCTION
+
+ The Generic Security Service Application Programming Interface [GSSAPI]
+ provides security services to calling applications. It allows a
+ communicating application to authenticate the user associated with
+ another application, to delegate rights to another application, and to
+ apply security services such as confidentiality and integrity on a per-
+ message basis.
+
+ There are four stages to using the GSSAPI:
+
+ (a) The application acquires a set of credentials with which it may
+ prove its identity to other processes. The application's
+ credentials vouch for its global identity, which may or may not be
+ related to any local username under which it may be running.
+
+ (b) A pair of communicating applications establish a joint security
+ context using their credentials. The security context is a pair
+ of GSSAPI data structures that contain shared state information,
+ which is required in order that per-message security services may
+ be provided. Examples of state that might be shared between
+ applications as part of a security context are cryptographic keys,
+ and message sequence numbers. As part of the establishment of a
+ security context, the context initiator is authenticated to the
+ responder, and may require that the responder is authenticated in
+ turn. The initiator may optionally give the responder the right
+ to initiate further security contexts, acting as an agent or
+ delegate of the initiator. This transfer of rights is termed
+ delegation, and is achieved by creating a set of credentials,
+ similar to those used by the initiating application, but which may
+ be used by the responder.
+
+ To establish and maintain the shared information that makes up the
+ security context, certain GSSAPI calls will return a token data
+ structure, which is a cryptographically protected opaque data
+ type. The caller of such a GSSAPI routine is responsible for
+ transferring the token to the peer application, encapsulated if
+ necessary in an application-application protocol. On receipt of
+ such a token, the peer application should pass it to a
+ corresponding GSSAPI routine which will decode the token and
+ extract the information, updating the security context state
+ information accordingly.
+
+ (c) Per-message services are invoked to apply either:
+
+ (i) integrity and data origin authentication, or
+
+ (ii) confidentiality, integrity and data origin authentication
+
+ to application data, which are treated by GSSAPI as arbitrary
+ octet-strings. An application transmitting a message that it
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 2]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ wishes to protect will call the appropriate GSSAPI routine
+ (gss_get_mic or gss_wrap) to apply protection, specifying the
+ appropriate security context, and send the resulting token to the
+ receiving application. The receiver will pass the received token
+ (and, in the case of data protected by gss_get_mic, the
+ accompanying message-data) to the corresponding decoding routine
+ (gss_verify_mic or gss_unwrap) to remove the protection and
+ validate the data.
+
+ (d) At the completion of a communications session (which may extend
+ across several transport connections), each application calls a
+ GSSAPI routine to delete the security context. Multiple contexts
+ may also be used (either successively or simultaneously) within a
+ single communications association, at the option of the
+ applications.
+
+
+ 4. GSSAPI ROUTINES
+
+ This section lists the routines that make up the GSSAPI, and offers a
+ brief description of the purpose of each routine. Detailed descriptions
+ of each routine are listed in alphabetical order in section 7.
+
+ Table 4-1 GSSAPI Credential-management Routines
+
+ ROUTINE SECTION FUNCTION
+
+ gss_acquire_cred 7.2 Assume a global identity;
+ Obtain a GSSAPI credential
+ handle for pre-existing
+ credentials.
+
+ gss_add_cred 7.3 Construct credentials
+ incrementally
+
+ gss_inquire_cred 7.21 Obtain information about
+ a credential.
+
+ gss_inquire_cred_by_mech 7.22 Obtain per-mechanism information
+ about a credential.
+
+ gss_release_cred 7.27 Discard a credential handle.
+
+
+
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 3]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Table 4-2 GSSAPI Context-level Routines
+
+ ROUTINE SECTION FUNCTION
+
+ gss_init_sec_context 7.19 Initiate a security context
+ with a peer application
+
+
+ gss_accept_sec_context 7.1 Accept a security context
+ initiated by a peer
+ application
+
+ gss_delete_sec_context 7.9 Discard a security context
+
+ gss_process_context_token 7.25 Process a token on a security
+ context from a peer
+ application
+
+ gss_context_time 7.7 Determine for how long a
+ context will remain valid
+
+ gss_inquire_context 7.20 Obtain information about a
+ security context
+
+ gss_wrap_size_limit 7.33 Determine token-size limit for
+ gss_wrap on a context
+
+ gss_export_sec_context 7.14 Transfer a security context to
+ another process
+
+ gss_import_sec_context 7.17 Import a transferred context
+
+
+
+
+ Table 4-3 GSSAPI Per-message Routines
+
+ ROUTINE SECTION FUNCTION
+
+ gss_get_mic 7.15 Calculate a cryptographic
+ Message Integrity Code (MIC)
+ for a message; integrity service
+
+ gss_verify_mic 7.32 Check a MIC against a message;
+ verify integrity of a received
+ message
+
+ gss_wrap 7.36 Attach a MIC to a message, and
+ optionally encrypt the message
+ content; confidentiality service
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 4]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ gss_unwrap 7.31 Verify a message with attached
+ MIC, and decrypt message
+ content if necessary.
+
+
+
+
+ Table 4-4 GSSAPI Name manipulation Routines
+
+ ROUTINE SECTION FUNCTION
+
+ gss_import_name 7.16 Convert a contiguous string name
+ to internal-form
+
+ gss_display_name 7.10 Convert internal-form name
+ to text
+
+ gss_compare_name 7.6 Compare two internal-form names
+
+ gss_release_name 7.28 Discard an internal-form name
+
+ gss_inquire_names_for_mech 7.24 List the name-types supported
+ by a specified mechanism
+
+ gss_inquire_mechs_for_name 7.23 List mechanisms that support
+ a given nametype
+
+ gss_canonicalize_name 7.5 Convert an internal name to
+ an MN.
+
+ gss_export_name 7.13 Convert an MN to export form
+
+ gss_duplicate_name 7.12 Create a copy of an internal name
+
+
+
+
+ Table 4-5 GSSAPI Miscellaneous Routines
+
+ ROUTINE SECTION FUNCTION
+
+ gss_display_status 7.11 Convert a GSSAPI status code
+ to text
+
+ gss_indicate_mechs 7.18 Determine available underlying
+ authentication mechanisms
+
+ gss_release_buffer 7.26 Discard a buffer
+
+ gss_release_oid_set 7.29 Discard a set of object
+ identifiers
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 5]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ gss_create_empty_oid_set 7.8 Create a set containing no
+ object identifiers
+
+ gss_add_oid_set_member 7.4 Add an object identifier to
+ a set
+
+ gss_test_oid_set_member 7.30 Determines whether an object
+ identifier is a member of a set
+
+
+
+
+
+ Individual GSSAPI implementations may augment these routines by
+ providing additional mechanism-specific routines if required
+ functionality is not available from the generic forms. Applications are
+ encouraged to use the generic routines wherever possible on portability
+ grounds.
+
+
+ 5. DATA TYPES AND CALLING CONVENTIONS
+
+ The following conventions are used by the GSSAPI C-language bindings:
+
+ 5.1. Integer types
+
+ GSSAPI uses the following integer data type:
+
+ OM_uint32 32-bit unsigned integer
+
+ Where guaranteed minimum bit-count is important, this portable data type
+ is used by the GSSAPI routine definitions. Individual GSSAPI
+ implementations will include appropriate typedef definitions to map this
+ type onto a built-in data type. If the platform supports the X/Open
+ xom.h header file, the OM_uint32 definition contained therein should be
+ used; the GSSAPI header file in Appendix A contains logic that will
+ detect the prior inclusion of xom.h, and will not attempt to re-declare
+ OM_uint32. If the X/Open header file is not available on the platform,
+ the GSSAPI implementation should use the smallest natural unsigned
+ integer type that provides at least 32 bits of precision.
+
+ 5.2. String and similar data
+
+ Many of the GSSAPI routines take arguments and return values that
+ describe contiguous octet-strings. All such data is passed between the
+ GSSAPI and the caller using the gss_buffer_t data type. This data type
+ is a pointer to a buffer descriptor, which consists of a length field
+ that contains the total number of bytes in the datum, and a value field
+ which contains a pointer to the actual datum:
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 6]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ typedef struct gss_buffer_desc_struct {
+ size_t length;
+ void *value;
+ } gss_buffer_desc, *gss_buffer_t;
+
+ Storage for data returned to the application by a GSSAPI routine using
+ the gss_buffer_t conventions is allocated by the GSSAPI routine. The
+ application may free this storage by invoking the gss_release_buffer
+ routine. Allocation of the gss_buffer_desc object is always the
+ responsibility of the application; unused gss_buffer_desc objects may
+ be initialized to the value GSS_C_EMPTY_BUFFER.
+
+ 5.2.1. Opaque data types
+
+ Certain multiple-word data items are considered opaque data types at the
+ GSSAPI, because their internal structure has no significance either to
+ the GSSAPI or to the caller. Examples of such opaque data types are the
+ input_token parameter to gss_init_sec_context (which is opaque to the
+ caller), and the input_message parameter to gss_wrap (which is opaque to
+ the GSSAPI). Opaque data is passed between the GSSAPI and the
+ application using the gss_buffer_t datatype.
+
+ 5.2.2. Character strings
+
+ Certain multiple-word data items may be regarded as simple ISO Latin-1
+ character strings. Examples are the printable strings passed to
+ gss_import_name via the input_name_buffer parameter. Some GSSAPI
+ routines also return character strings. All such character strings are
+ passed between the application and the GSSAPI implementation using the
+ gss_buffer_t datatype, which is a pointer to a gss_buffer_desc object.
+
+ When a gss_buffer_desc object describes a printable string, the length
+ field of the gss_buffer_desc should only count printable characters
+ within the string. In particular, a trailing NUL character should NOT
+ be included in the length count, nor should either the GSSAPI
+ implementation or the application assume the presence of an uncounted
+ trailing NUL.
+
+ 5.3. Object Identifiers
+
+ Certain GSSAPI procedures take parameters of the type gss_OID, or Object
+ identifier. This is a type containing ISO-defined tree-structured
+ values, and is used by the GSSAPI caller to select an underlying
+ security mechanism and to specify namespaces. A value of type gss_OID
+ has the following structure:
+
+ typedef struct gss_OID_desc_struct {
+ OM_uint32 length;
+ void *elements;
+ } gss_OID_desc, *gss_OID;
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 7]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ The elements field of this structure points to the first byte of an
+ octet string containing the ASN.1 BER encoding of the value portion of
+ the normal BER TLV encoding of the gss_OID. The length field contains
+ the number of bytes in this value. For example, the gss_OID value
+ corresponding to {iso(1) identified-organization(3) icd-ecma(12)
+ member-company(2) dec(1011) cryptoAlgorithms(7) DASS(5)}, meaning the
+ DASS X.509 authentication mechanism, has a length field of 7 and an
+ elements field pointing to seven octets containing the following octal
+ values: 53,14,2,207,163,7,5. GSSAPI implementations should provide
+ constant gss_OID values to allow applications to request any supported
+ mechanism, although applications are encouraged on portability grounds
+ to accept the default mechanism. gss_OID values should also be provided
+ to allow applications to specify particular name types (see section
+ 5.10). Applications should treat gss_OID_desc values returned by GSSAPI
+ routines as read-only. In particular, the application should not
+ attempt to deallocate them with free(). The gss_OID_desc datatype is
+ equivalent to the X/Open OM_object_identifier datatype[XOM].
+
+ 5.4. Object Identifier Sets
+
+ Certain GSSAPI procedures take parameters of the type gss_OID_set. This
+ type represents one or more object identifiers (section 5.3). A
+ gss_OID_set object has the following structure:
+
+ typedef struct gss_OID_set_desc_struct {
+ size_t count;
+ gss_OID elements;
+ } gss_OID_set_desc, *gss_OID_set;
+
+ The count field contains the number of OIDs within the set. The
+ elements field is a pointer to an array of gss_OID_desc objects, each of
+ which describes a single OID. gss_OID_set values are used to name the
+ available mechanisms supported by the GSSAPI, to request the use of
+ specific mechanisms, and to indicate which mechanisms a given credential
+ supports.
+
+ All OID sets returned to the application by GSSAPI are dynamic objects
+ (the gss_OID_set_desc, the "elements" array of the set, and the
+ "elements" array of each member OID are all dynamically allocated), and
+ this storage must be deallocated by the application using the
+ gss_release_oid_set() routine.
+
+
+ 5.5. Credentials
+
+ A credential handle is a caller-opaque atomic datum that identifies a
+ GSSAPI credential data structure. It is represented by the caller-
+ opaque type gss_cred_id_t, which should be implemented as a pointer or
+ arithmetic type. If a pointer implementation is chosen, care must be
+ taken to ensure that two gss_cred_id_t values may be compared with the
+ == operator.
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 8]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSSAPI credentials can contain mechanism-specific principal
+ authentication data for multiple mechanisms. A GSSAPI credential is
+ composed of a set of credential-elements, each of which is applicable to
+ a single mechanism. A credential may contain at most one credential-
+ element for each supported mechanism. A credential-element identifies
+ the data needed by a single mechanism to authenticate a single
+ principal, and conceptually contains two credential-references that
+ describing the actual mechanism-specific authentication data, one to be
+ used by GSSAPI for initiating contexts, and one to be used for
+ accepting contexts. For mechanisms that do not distinguish between
+ acceptor and initiator credentials, both references would point to the
+ same underlying mechanism-specific authentication data.
+
+ Credentials describe a set of mechanism-specific principals, and give
+ their holder the ability to act as any of those principals. All
+ principal identities asserted by a single GSSAPI credential should
+ belong to the same entity, although enforcement of this property is an
+ implementation-specific matter. The GSSAPI does not make the actual
+ credentials available to applications; instead a credential handle is
+ used to identify a particular credential, held internally by GSSAPI.
+ The combination of GSSAPI credential handle and mechanism identifies the
+ principal whose identity will be asserted by the credential when used
+ with that mechanism.
+
+ The gss_init_sec_context and gss_accept_sec_context routines allow the
+ value GSS_C_NO_CREDENTIAL to be specified as their credential handle
+ parameter. This special credential-handle indicates a desire by the
+ application to act as a default principal. While individual GSSAPI
+ implementations are free to determine such default behavior as
+ appropriate to the mechanism, the following default behavior by these
+ routines is recommended for portability:
+
+ (a) gss_init_sec_context
+
+ (i) If there is only a single principal capable of initiating
+ security contexts for the chosen mechanism that the
+ application is authorized to act on behalf of, then that
+ principal shall be used, otherwise
+
+ (ii) If the platform maintains a concept of a default network-
+ identity for the chosen mechanism, and if the application is
+ authorized to act on behalf of that identity for the purpose
+ of initiating security contexts, then the principal
+ corresponding to that identity shall be used, otherwise
+
+ (iii) If the platform maintains a concept of a default local
+ identity, and provides a means to map local identities into
+ network-identities for the chosen mechanism, and if the
+ application is authorized to act on behalf of the network-
+ identity image of the default local identity for the purpose
+ of initiating security contexts using the chosen mechanism,
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 9]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ then the principal corresponding to that identity shall be
+ used, otherwise
+
+ (iv) A user-configurable default identity should be used.
+
+ (b) gss_accept_sec_context
+
+ (i) If there is only a single authorized principal identity
+ capable of accepting security contexts for the chosen
+ mechanism, then that principal shall be used, otherwise
+
+ (ii) If the mechanism can determine the identity of the target
+ principal by examining the context-establishment token, and
+ if the accepting application is authorized to act as that
+ principal for the purpose of accepting security contexts
+ using the chosen mechanism, then that principal identity
+ shall be used, otherwise
+
+ (iii) If the mechanism supports context acceptance by any
+ principal, and if mutual authentication was not requested,
+ any principal that the application is authorized to accept
+ security contexts under using the chosen mechanism may be
+ used, otherwise
+
+ (iv) A user-configurable default identity shall be used.
+
+ The purpose of the above rules is to allow security contexts to be
+ established by both initiator and acceptor using the default behavior
+ wherever possible. Applications requesting default behavior are likely
+ to be more portable across mechanisms and platforms than ones that use
+ gss_acquire_cred to request a specific identity.
+
+ 5.6. Contexts
+
+ The gss_ctx_id_t data type contains a caller-opaque atomic value that
+ identifies one end of a GSSAPI security context. It should be
+ implemented as a pointer or arithmetic type. If a pointer type is
+ chosen, care should be taken to ensure that two gss_ctx_id_t values may
+ be compared with the == operator.
+
+ The security context holds state information about each end of a peer
+ communication, including cryptographic state information.
+
+ 5.7. Authentication tokens
+
+ A token is a caller-opaque type that GSSAPI uses to maintain
+ synchronization between the context data structures at each end of a
+ GSSAPI security context. The token is a cryptographically protected
+ octet-string, generated by the underlying mechanism at one end of a
+ GSSAPI security context for use by the peer mechanism at the other end.
+ Encapsulation (if required) and transfer of the token are the
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 10]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ responsibility of the peer applications. A token is passed between the
+ GSSAPI and the application using the gss_buffer_t conventions.
+
+ 5.8. Interprocess tokens
+
+ Certain GSSAPI routines are intended to transfer data between processes
+ in multi-process programs. These routines use a caller-opaque octet-
+ string, generated by the GSSAPI in one process for use by the GSSAPI in
+ another process. The calling application is responsible for
+ transferring such tokens between processes in an OS-specific manner.
+ Note that, while GSSAPI implementors are encouraged to avoid placing
+ sensitive information within interprocess tokens, or to
+ cryptographically protect them, many implementations will be unable to
+ avoid placing key material or other sensitive data within them. It is
+ the application's responsibility to ensure that interprocess tokens are
+ protected in transit, and transferred only to processes that are
+ trustworthy. An interprocess token is passed between the GSSAPI and the
+ application using the gss_buffer_t conventions.
+
+ 5.9. Status values
+
+ One or more status codes are returned by each GSSAPI routine. Two
+ distinct sorts of status codes are returned. These are termed GSS
+ status codes and Mechanism status codes.
+
+ 5.9.1. GSS status codes
+
+ GSSAPI routines return GSS status codes as their OM_uint32 function
+ value. These codes indicate errors that are independent of the
+ underlying mechanism(s) used to provide the security service. The
+ errors that can be indicated via a GSS status code are either generic
+ API routine errors (errors that are defined in the GSS-API
+ specification) or calling errors (errors that are specific to these
+ language bindings).
+
+ A GSS status code can indicate a single fatal generic API error from the
+ routine and a single calling error. In addition, supplementary status
+ information may be indicated via the setting of bits in the
+ supplementary info field of a GSS status code.
+
+ These errors are encoded into the 32-bit GSS status code as follows:
+
+ MSB LSB
+ |------------------------------------------------------------|
+ | Calling Error | Routine Error | Supplementary Info |
+ |------------------------------------------------------------|
+ Bit 31 24 23 16 15 0
+
+
+ Hence if a GSS-API routine returns a GSS status code whose upper 16 bits
+ contain a non-zero value, the call failed. If the calling error field
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 11]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ is non-zero, the invoking application's call of the routine was
+ erroneous. Calling errors are defined in table 5-1. If the routine
+ error field is non-zero, the routine failed for one of the routine-
+ specific reasons listed below in table 5-2. Whether or not the upper 16
+ bits indicate a failure or a success, the routine may indicate
+ additional information by setting bits in the supplementary info field
+ of the status code. The meaning of individual bits is listed below in
+ table 5-3.
+
+ Table 5-1 Calling Errors
+
+ Name Value in Meaning
+ Field
+ GSS_S_CALL_INACCESSIBLE_READ 1 A required input
+ parameter could
+ not be read.
+ GSS_S_CALL_INACCESSIBLE_WRITE 2 A required output
+ parameter could
+ not be written.
+ GSS_S_CALL_BAD_STRUCTURE 3 A parameter was
+ malformed
+
+
+
+
+ Table 5-2 Routine Errors
+
+ Name Value in Meaning
+ Field
+
+ GSS_S_BAD_MECH 1 An unsupported mechanism was
+ requested
+ GSS_S_BAD_NAME 2 An invalid name was supplied
+ GSS_S_BAD_NAMETYPE 3 A supplied name was of an
+ unsupported type
+ GSS_S_BAD_BINDINGS 4 Incorrect channel bindings
+ were supplied
+ GSS_S_BAD_STATUS 5 An invalid status code was
+ supplied
+ GSS_S_BAD_SIG 6 A token had an invalid
+ GSS_S_BAD_MIC MIC
+ GSS_S_NO_CRED 7 No credentials were supplied,
+ or the credentials were
+ unavailable or inaccessible.
+ GSS_S_NO_CONTEXT 8 No context has been
+ established
+ GSS_S_DEFECTIVE_TOKEN 9 A token was invalid
+ GSS_S_DEFECTIVE_CREDENTIAL 10 A credential was invalid
+ GSS_S_CREDENTIALS_EXPIRED 11 The referenced credentials
+ have expired
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 12]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_S_CONTEXT_EXPIRED 12 The context has expired
+ GSS_S_FAILURE 13 Miscellaneous failure
+ (see text)
+ GSS_S_BAD_QOP 14 The quality-of-protection
+ requested could not be
+ provide
+ GSS_S_UNAUTHORIZED 15 The operation is forbidden by
+ local security policy
+ GSS_S_UNAVAILABLE 16 The operation or option is not
+ available
+ GSS_S_DUPLICATE_ELEMENT 17 The requested credential element
+ already exists
+ GSS_S_NAME_NOT_MN 18 The provided name was not a
+ mechanism name.
+
+
+
+
+
+ Table 5-3 Supplementary Status Bits
+
+ Name Bit Number Meaning
+ GSS_S_CONTINUE_NEEDED 0 (LSB) The routine must be called
+ again to complete its function.
+ See routine documentation for
+ detailed description.
+ GSS_S_DUPLICATE_TOKEN 1 The token was a duplicate of
+ an earlier token
+ GSS_S_OLD_TOKEN 2 The token's validity period
+ has expired
+ GSS_S_UNSEQ_TOKEN 3 A later token has already been
+ processed
+ GSS_S_GAP_TOKEN 4 An expected per-message token
+ was not received
+
+
+ The routine documentation also uses the name GSS_S_COMPLETE, which is a
+ zero value, to indicate an absence of any API errors or supplementary
+ information bits.
+
+ All GSS_S_xxx symbols equate to complete OM_uint32 status codes, rather
+ than to bitfield values. For example, the actual value of the symbol
+ GSS_S_BAD_NAMETYPE (value 3 in the routine error field) is 3 << 16.
+
+ The macros GSS_CALLING_ERROR(), GSS_ROUTINE_ERROR() and
+ GSS_SUPPLEMENTARY_INFO() are provided, each of which takes a GSS status
+ code and removes all but the relevant field. For example, the value
+ obtained by applying GSS_ROUTINE_ERROR to a status code removes the
+ calling errors and supplementary info fields, leaving only the routine
+ errors field. The values delivered by these macros may be directly
+ compared with a GSS_S_xxx symbol of the appropriate type. The macro
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 13]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_ERROR() is also provided, which when applied to a GSS status code
+ returns a non-zero value if the status code indicated a calling or
+ routine error, and a zero value otherwise. All macros defined by GSS-
+ API evaluate their argument(s) exactly once.
+
+ A GSS-API implementation may choose to signal calling errors in a
+ platform-specific manner instead of, or in addition to the routine
+ value; routine errors and supplementary info should be returned via
+ routine status values only.
+
+ 5.9.2. Mechanism-specific status codes
+
+ GSS-API routines return a minor_status parameter, which is used to
+ indicate specialized errors from the underlying security mechanism.
+ This parameter may contain a single mechanism-specific error, indicated
+ by a OM_uint32 value.
+
+ The minor_status parameter will always be set by a GSS-API routine, even
+ if it returns a calling error or one of the generic API errors indicated
+ above as fatal, although most other output parameters may remain unset
+ in such cases. However, output parameters that are expected to return
+ pointers to storage allocated by a routine must always be set by the
+ routine, even in the event of an error, although in such cases the GSS-
+ API routine may elect to set the returned parameter value to NULL to
+ indicate that no storage was actually allocated. Any length field
+ associated with such pointers (as in a gss_buffer_desc structure) should
+ also be set to zero in such cases.
+
+ The GSS status code GSS_S_FAILURE is used to indicate that the
+ underlying mechanism detected an error for which no specific GSS status
+ code is defined. The mechanism status code will provide more details
+ about the error.
+
+ 5.10. Names
+
+ A name is used to identify a person or entity. GSS-API authenticates
+ the relationship between a name and the entity claiming the name.
+
+ Since different authentication mechanisms may employ different
+ namespaces for identifying their principals, GSSAPI's naming support is
+ necessarily complex in multi-mechanism environments (or even in some
+ single-mechanism environments where the underlying mechanism supports
+ multiple namespaces).
+
+ Two distinct representations are defined for names:
+
+ (a) An internal form. This is the GSSAPI "native" format for names,
+ represented by the implementation-specific gss_name_t type. It is
+ opaque to GSSAPI callers. A single gss_name_t object may contain
+ multiple names from different namespaces, but all names should
+ refer to the same entity. An example of such an internal name
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 14]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ would be the name returned from a call to the gss_inquire_cred
+ routine, when applied to a credential containing credential
+ elements for multiple authentication mechanisms employing
+ different namespaces. This gss_name_t object will contain a
+ distinct name for the entity for each authentication mechanism.
+
+ For GSSAPI implementations supporting multiple namespaces, objects
+ of type gss_name_t must contain sufficient information to
+ determine the namespace to which each primitive name belongs.
+
+ (b) Mechanism-specific contiguous octet-string forms. A format
+ capable of containing a single name (from a single namespace).
+ Contiguous string names are always accompanied by an object
+ identifier specifying the namespace to which the name belongs, and
+ their format is dependent on the authentication mechanism that
+ employs the name. Many, but not all, contiguous string names will
+ be printable, and may therefore be used by GSSAPI applications for
+ communication with their users.
+
+ Routines (gss_import_name and gss_display_name) are provided to convert
+ names between contiguous string representations and the internal
+ gss_name_t type. gss_import_name may support multiple syntaxes for each
+ supported namespace, allowing users the freedom to choose a preferred
+ name representation. gss_display_name should use an implementation-
+ chosen printable syntax for each supported name-type.
+
+ If an application calls gss_display_name(), passing the internal name
+ resulting from a call to gss_import_name(), there is no guarantee the
+ the resulting contiguous string name will be the same as the original
+ imported string name. Nor do name-space identifiers necessarily survive
+ unchanged after a journey through the internal name-form. An example of
+ this might be a mechanism that authenticates X.500 names, but provides
+ an algorithmic mapping of Internet DNS names into X.500. That
+ mechanism's implementation of gss_import_name() might, when presented
+ with a DNS name, generate an internal name that contained both the
+ original DNS name and the equivalent X.500 name. Alternatively, it might
+ only store the X.500 name. In the latter case, gss_display_name() would
+ most likely generate a printable X.500 name, rather than the original
+ DNS name.
+
+ The process of authentication delivers to the context acceptor an
+ internal name. Since this name has been authenticated by a single
+ mechanism, it contains only a single name (even if the internal name
+ presented by the context initiator to gss_init_sec_context had multiple
+ components). Such names are termed internal mechanism names, or "MN"s
+ and the names emitted by gss_accept_sec_context() are always of this
+ type. Since some applications may require MNs without wanting to incur
+ the overhead of an authentication operation, a second function,
+ gss_canonicalize_name(), is provided to convert a general internal name
+ into an MN.
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 15]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Comparison of internal-form names may be accomplished via the
+ gss_compare_name() routine, which returns true if the two names being
+ compared refer to the same entity. This removes the need for the
+ application program to understand the syntaxes of the various printable
+ names that a given GSS-API implementation may support. Since GSSAPI
+ assumes that all primitive names contained within a given internal name
+ refer to the same entity, gss_compare_name() can return true if the two
+ names have at least one primitive name in common. If the implementation
+ embodies knowledge of equivalence relationships between names taken from
+ different namespaces, this knowledge may also allow successful
+ comparison of internal names containing no overlapping primitive
+ elements.
+
+ When used in large access control lists, the overhead of invoking
+ gss_import_name() and gss_compare_name() on each name from the ACL may
+ be prohibitive. As an alternative way of supporting this case, GSSAPI
+ defines a special form of the contiguous string name which may be
+ compared directly (e.g. with memcmp()). Contigous names suitable for
+ comparison are generated by the gss_export_name() routine, which
+ requires an MN as input. Exported names may be re-imported by the
+ gss_import_name() routine, and the resulting internal name will also be
+ an MN. The gss_OID constant GSS_C_NT_EXPORT_NAME indentifies the
+ "export name" type, and the value of this constant is given in Appendix
+ A. Structurally, an exported name object consists of a header
+ containing an OID identifying the mechanism that authenticated the name,
+ and a trailer containing the name itself, where the syntax of the
+ trailer is defined by the individual mechanism specification. The
+ precise format of an export name is defined in the language-independent
+ GSSAPI specification [GSSAPI].
+
+ Note that the results obtained by using gss_compare_name() will in
+ general be different from those obtained by invoking
+ gss_canonicalize_name() and gss_export_name(), and then comparing the
+ exported names. The first series of operation determines whether two
+ (unauthenticated) names identify the same principal; the second whether
+ a particular mechanism would authenticate them as the same principal.
+ These two operations will in general give the same results only for MNs.
+
+ The gss_name_t datatype should be implemented as a pointer type. To
+ allow the compiler to aid the application programmer by performing
+ type-checking, the use of (void *) is discouraged. A pointer to an
+ implementation-defined type is the preferred choice.
+
+ Storage is allocated by routines that return gss_name_t values. A
+ procedure, gss_release_name, is provided to free storage associated with
+ an internal-form name.
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 16]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 5.11. Channel Bindings
+
+ GSS-API supports the use of user-specified tags to identify a given
+ context to the peer application. These tags are intended to be used to
+ identify the particular communications channel that carries the context.
+ Channel bindings are communicated to the GSS-API using the following
+ structure:
+
+ typedef struct gss_channel_bindings_struct {
+ OM_uint32 initiator_addrtype;
+ gss_buffer_desc initiator_address;
+ OM_uint32 acceptor_addrtype;
+ gss_buffer_desc acceptor_address;
+ gss_buffer_desc application_data;
+ } *gss_channel_bindings_t;
+
+ The initiator_addrtype and acceptor_addrtype fields denote the type of
+ addresses contained in the initiator_address and acceptor_address
+ buffers. The address type should be one of the following:
+
+ GSS_C_AF_UNSPEC Unspecified address type
+ GSS_C_AF_LOCAL Host-local address type
+ GSS_C_AF_INET Internet address type (e.g. IP)
+ GSS_C_AF_IMPLINK ARPAnet IMP address type
+ GSS_C_AF_PUP pup protocols (eg BSP) address type
+ GSS_C_AF_CHAOS MIT CHAOS protocol address type
+ GSS_C_AF_NS XEROX NS address type
+ GSS_C_AF_NBS nbs address type
+ GSS_C_AF_ECMA ECMA address type
+ GSS_C_AF_DATAKIT datakit protocols address type
+ GSS_C_AF_CCITT CCITT protocols
+ GSS_C_AF_SNA IBM SNA address type
+ GSS_C_AF_DECnet DECnet address type
+ GSS_C_AF_DLI Direct data link interface address type
+ GSS_C_AF_LAT LAT address type
+ GSS_C_AF_HYLINK NSC Hyperchannel address type
+ GSS_C_AF_APPLETALK AppleTalk address type
+ GSS_C_AF_BSC BISYNC 2780/3780 address type
+ GSS_C_AF_DSS Distributed system services address type
+ GSS_C_AF_OSI OSI TP4 address type
+ GSS_C_AF_X25 X25
+ GSS_C_AF_NULLADDR No address specified
+
+ Note that these symbols name address families rather than specific
+ addressing formats. For address families that contain several
+ alternative address forms, the initiator_address and acceptor_address
+ fields must contain sufficient information to determine which address
+ form is used. When not otherwise specified, addresses should be
+ specified in network byte-order (that is, native byte-ordering for the
+ address family).
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 17]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Conceptually, the GSS-API concatenates the initiator_addrtype,
+ initiator_address, acceptor_addrtype, acceptor_address and
+ application_data to form an octet string. The mechanism calculates a
+ MIC over this octet string, and binds the MIC to the context
+ establishment token emitted by gss_init_sec_context. The same bindings
+ are presented by the context acceptor to gss_accept_sec_context, and a
+ MIC is calculated in the same way. The calculated MIC is compared with
+ that found in the token, and if the MICs differ, gss_accept_sec_context
+ will return a GSS_S_BAD_BINDINGS error, and the context will not be
+ established. Some mechanisms may include the actual channel binding
+ data in the token (rather than just a MIC); applications should
+ therefore not use confidential data as channel-binding components.
+ Individual mechanisms may impose additional constraints on addresses and
+ address types that may appear in channel bindings. For example, a
+ mechanism may verify that the initiator_address field of the channel
+ bindings presented to gss_init_sec_context contains the correct network
+ address of the host system. Portable applications should therefore
+ ensure that they either provide correct information for the address
+ fields, or omit addressing information, specifying GSS_C_AF_NULLADDR as
+ the address-types.
+
+ 5.12. Optional parameters
+
+ Various parameters are described as optional. This means that they
+ follow a convention whereby a default value may be requested. The
+ following conventions are used for omitted parameters. These
+ conventions apply only to those parameters that are explicitly
+ documented as optional.
+
+ 5.12.1. gss_buffer_t types
+
+ Specify GSS_C_NO_BUFFER as a value. For an input parameter this
+ signifies that default behavior is requested, while for an output
+ parameter it indicates that the information that would be returned via
+ the parameter is not required by the application.
+
+ 5.12.2. Integer types (input)
+
+ Individual parameter documentation lists values to be used to indicate
+ default actions.
+
+ 5.12.3. Integer types (output)
+
+ Specify NULL as the value for the pointer.
+
+ 5.12.4. Pointer types
+
+ Specify NULL as the value.
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 18]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 5.12.5. Object IDs
+
+ Specify GSS_C_NO_OID as the value.
+
+ 5.12.6. Object ID Sets
+
+ Specify GSS_C_NO_OID_SET as the value.
+
+ 5.12.7. Channel Bindings
+
+ Specify GSS_C_NO_CHANNEL_BINDINGS to indicate that channel bindings are
+ not to be used.
+
+
+ 6. ADDITIONAL CONTROLS
+
+ This section discusses the optional services that a context initiator
+ may request of the GSS-API at context establishment. Each of these
+ services is requested by setting a flag in the req_flags input parameter
+ to gss_init_sec_context.
+
+ The optional services currently defined are:
+
+ Delegation - The (usually temporary) transfer of rights from initiator
+ to acceptor, enabling the acceptor to authenticate itself as an
+ agent of the initiator.
+
+ Mutual Authentication - In addition to the initiator authenticating its
+ identity to the context acceptor, the context acceptor should also
+ authenticate itself to the initiator.
+
+ Replay detection - In addition to providing message integrity services,
+ gss_get_mic and gss_wrap should include message numbering
+ information to enable gss_verify_mic and gss_unwrap to detect if a
+ message has been duplicated.
+
+ Out-of-sequence detection - In addition to providing message integrity
+ services, gss_get_mic and gss_wrap should include message
+ sequencing information to enable gss_verify_mic and gss_unwrap to
+ detect if a message has been received out of sequence.
+
+ Anonymous authentication - The establishment of the security context
+ should not reveal the initiator's identity to the context
+ acceptor.
+
+ Any currently undefined bits within such flag arguments should be
+ ignored by GSS-API implementations when presented by an application, and
+ should be set to zero when returned to the application by the GSS-API
+ implementation.
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 19]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Some mechanisms may not support all optional services, and some
+ mechanisms may only support some services in conjunction with others.
+ Both gss_init_sec_context and gss_accept_sec_context inform the
+ applications which services will be available from the context when the
+ establishment phase is complete, via the ret_flags output parameter. In
+ general, if the security mechanism is capable of providing a requested
+ service, it should do so, even if additional services must be enabled in
+ order to provide the requested service. If the mechanism is incapable
+ of providing a requested service, it should proceed without the service,
+ leaving the application to abort the context establishment process if it
+ considers the requested service to be mandatory.
+
+ Some mechanisms may specify that support for some services is optional,
+ and that implementors of the mechanism need not provide it. This is
+ most commonly true of the confidentiality service, often because of
+ legal restrictions on the use of data-encryption, but may apply to any
+ of the services. Such mechanisms are required to send at least one
+ token from acceptor to initiator during context establishment when the
+ initiator indicates a desire to use such a service, so that the
+ initiating GSSAPI can correctly indicate whether the service is
+ supported by the acceptor's GSSAPI.
+
+ 6.1. Delegation
+
+ The GSS-API allows delegation to be controlled by the initiating
+ application via a boolean parameter to gss_init_sec_context(), the
+ routine that establishes a security context. Some mechanisms do not
+ support delegation, and for such mechanisms attempts by an application
+ to enable delegation are ignored.
+
+ The acceptor of a security context for which the initiator enabled
+ delegation will receive (via the delegated_cred_handle parameter of
+ gss_accept_sec_context) a credential handle that contains the delegated
+ identity, and this credential handle may be used to initiate subsequent
+ GSSAPI security contexts as an agent or delegate of the initiator. If
+ the original initiator's identity is "A" and the delegate's identity is
+ "B", then, depending on the underlying mechanism, the identity embodied
+ by the delegated credential may be either "A" or "B acting for A".
+
+ For many mechanisms that support delegation, a simple boolean does not
+ provide enough control. Examples of additional aspects of delegation
+ control that a mechanism might provide to an application are duration of
+ delegation, network addresses from which delegation is valid, and
+ constraints on the tasks that may be performed by a delegate. Such
+ controls are presently outside the scope of the GSS-API. GSS-API
+ implementations supporting mechanisms offering additional controls
+ should provide extension routines that allow these controls to be
+ exercised (perhaps by modifying the initiator's GSS-API credential prior
+ to its use in establishing a context). However, the simple delegation
+ control provided by GSS-API should always be able to over-ride other
+ mechanism-specific delegation controls - If the application instructs
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 20]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ gss_init_sec_context() that delegation is not desired, then the
+ implementation must not permit delegation to occur. This is an
+ exception to the general rule that a mechanism may enable services even
+ if they are not requested - delegation may only be provide at the
+ explicit request of the application.
+
+ 6.2. Mutual authentication
+
+ Usually, a context acceptor will require that a context initiator
+ authenticate itself so that the acceptor may make an access-control
+ decision prior to performing a service for the initiator. In some
+ cases, the initiator may also request that the acceptor authenticate
+ itself. GSS-API allows the initiating application to request this
+ mutual authentication service by setting a flag when calling
+ gss_init_sec_context.
+
+ The initiating application is informed as to whether or not mutual
+ authentication is being requested of the context acceptor. Note that
+ some mechanisms may not support mutual authentication, and other
+ mechanisms may always perform mutual authentication, whether or not the
+ initiating application requests it. In particular, mutual
+ authentication my be required by some mechanisms in order to support
+ replay or out-of-sequence message detection, and for such mechanisms a
+ request for either of these services will automatically enable mutual
+ authentication.
+
+ 6.3. Replay and out-of-sequence detection
+
+ The GSS-API may provide detection of mis-ordered message once a security
+ context has been established. Protection may be applied to messages by
+ either application, by calling either gss_get_mic or gss_wrap, and
+ verified by the peer application by calling gss_verify_mic or
+ gss_unwrap.
+
+ gss_get_mic calculates a cryptographic checksum of an application
+ message, and returns that checksum in a token. The application should
+ pass both the token and the message to the peer application, which
+ presents them to gss_verify_mic.
+
+ gss_wrap calculates a cryptographic checksum of an application message,
+ and places both the checksum and the message inside a single token. The
+ application should pass the token to the peer application, which
+ presents it to gss_unwrap to extract the message and verify the
+ checksum.
+
+ Either pair of routines may be capable of detecting out-of-sequence
+ message delivery, or duplication of messages. Details of such mis-
+ ordered messages are indicated through supplementary status bits in the
+ major status code returned by gss_verify_mic or gss_unwrap. The
+ relevant supplementary bits are:
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 21]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_S_DUPLICATE_TOKEN - The token is a duplicate of one that has already
+ been received and processed. Contexts that do not claim to
+ provide replay detection may still set this bit if the duplicate
+ message is processed immediately after the original, with no
+ intervening messages.
+
+ GSS_S_OLD_TOKEN - The token is too old to determine whether or not it is
+ a duplicate. Contexts supporting out-of-sequence detection but
+ not replay detection should always set this bit if
+ GSS_S_UNSEQ_TOKEN is set; contexts that support replay detection
+ should only set this bit if the token is so old that it cannot be
+ checked for duplication.
+
+ GSS_S_UNSEQ_TOKEN - A later token has already been processed.
+
+ GSS_S_GAP_TOKEN - An earlier token has not yet been received.
+
+ A mechanism need not maintain a list of all tokens that have been
+ processed in order to support these status codes. A typical mechanism
+ might retain information about only the most recent "N" tokens
+ processed, allowing it to distinguish duplicates and missing tokens
+ within the most recent "N" messages; the receipt of a token older than
+ the most recent "N" would result in a GSS_S_OLD_TOKEN status.
+
+ 6.4. Anonymous Authentication
+
+ In certain situations, an application may wish to initiate the
+ authentication process to authenticate a peer, without revealing its own
+ identity. As an example, consider an application providing access to a
+ database containing medical information, and offering unrestricted
+ access to the service. A client of such a service might wish to
+ authenticate the service (in order to establish trust in any information
+ retrieved from it), but might not wish the service to be able to obtain
+ the client's identity (perhaps due to privacy concerns about the
+ specific inquiries, or perhaps simply to avoid being placed on mailing-
+ lists).
+
+ In normal use of the GSS-API, the initiator's identity is made available
+ to the acceptor as a result of the context establishment process.
+ However, context initiators may request that their identity not be
+ revealed to the context acceptor. Many mechanisms do not support
+ anonymous authentication, and for such mechanisms the request will not
+ be honored. An authentication token will be still be generated, but the
+ application is always informed if a requested service is unavailable,
+ and has the option to abort context establishment if anonymity is valued
+ above the other security services that would require a context to be
+ established.
+
+ In addition to informing the application that a context is established
+ anonymously (via the ret_flags outputs from gss_init_sec_context and
+ gss_accept_sec_context), the optional src_name output from
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 22]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ gss_accept_sec_context and gss_inquire_context will, for such contexts,
+ return a reserved internal-form name, defined by the implementation.
+ When presented to gss_display_name, this reserved internal-form name
+ will result in a printable name that is syntactically distinguishable
+ from any valid principal name supported by the implementation,
+ associated with a name-type object identifier with the value
+ GSS_C_NT_ANONYMOUS, whose value us given in Appendix A. The printable
+ form of an anonymous name should be chosen such that it implies
+ anonymity, since this name may appear in, for example, audit logs. For
+ example, the string "<anonymous>" might be a good choice, if no valid
+ printable names supported by the implementation can begin with "<" and
+ end with ">".
+
+ 6.5. Confidentiality
+
+ If a context supports the confidentiality service, gss_wrap may be used
+ to encrypt application messages. Messages are selectively encrypted,
+ under the control of the conf_req_flag input parameter to gss_wrap.
+
+ 6.6. Inter-process context transfer
+
+ GSSAPI V2 provides routines (gss_export_sec_context and
+ gss_import_sec_context) which allow a security context to be transferred
+ between processes on a single machine. The most common use for such a
+ feature is a client-server design where the server is implemented as a
+ single process that accepts incoming security contexts, which then
+ launches child processes to deal with the data on these contexts. In
+ such a design, the child processes must have access to the security
+ context data structure created within the parent by its call to
+ gss_accept_sec_context so that they can use per-message protection
+ services and delete the security context when the communication session
+ ends.
+
+ Since the security context data structure is expected to contain
+ sequencing information, it is impractical in general to share a context
+ between processes. Thus GSSAPI provides a call (gss_export_sec_context)
+ that the process which currently owns the context can call to declare
+ that it has no intention to use the context subsequently, and to create
+ an inter-process token containing information needed by the adopting
+ process to successfully import the context. After successful completion
+ of this call, the original security context is made inaccessible to the
+ calling process by GSSAPI, and any context handles referring to this
+ context are no longer valid. The originating process transfers the
+ inter-process token to the adopting process, which passes it to
+ gss_import_sec_context, and a fresh gss_ctx_id_t is created such that it
+ is functionally identical to the original context.
+
+ The inter-process token may contain sensitive data from the original
+ security context (including cryptographic keys). Applications using
+ inter-process tokens to transfer security contexts must take appropriate
+ steps to protect these tokens in transit.
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 23]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Implementations are not required to support the inter-process transfer
+ of security contexts. The ability to transfer a security context is
+ indicated when the context is created, by gss_init_sec_context or
+ gss_accept_sec_context setting the GSS_C_TRANS_FLAG bit in their
+ ret_flags parameter.
+
+
+ 6.7. The use of incomplete contexts
+
+ Some mechanisms may allow the per-message services to be used before the
+ context establishment process is complete. For example, a mechanism may
+ include sufficient information in its initial context-level token for
+ the context acceptor to immediately decode messages protected with
+ gss_wrap or gss_get_mic. For such a mechanism, the initiating
+ application need not wait until subsequent context-level tokens have
+ been sent and received before invoking the per-message protection
+ services.
+
+ The ability of a context to provide per-message services in advance of
+ complete context establishment is indicated by the setting of the
+ GSS_C_PROT_READY_FLAG bit in the ret_flags parameter from
+ gss_init_sec_context and gss_accept_sec_context. Applications wishing
+ to use per-message protection services on partially-established contexts
+ should check this flag before attempting to invoke gss_wrap or
+ gss_get_mic.
+
+
+
+ 7. GSS-API routine descriptions
+
+ In addition to the explicit major status codes documented here, the code
+ GSS_S_FAILURE may be returned by any routine, indicating an
+ implementation-specific or mechanism-specific error condition, further
+ details of which are reported via the minor_status parameter.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 24]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 7.1. gss_accept_sec_context
+
+ OM_uint32 gss_accept_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ const gss_channel_bindings_t
+ input_chan_bindings,
+ const gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t * delegated_cred_handle)
+
+ Purpose:
+
+ Allows a remotely initiated security context between the application and
+ a remote peer to be established. The routine may return a output_token
+ which should be transferred to the peer application, where the peer
+ application will present it to gss_init_sec_context. If no token need
+ be sent, gss_accept_sec_context will indicate this by setting the length
+ field of the output_token argument to zero. To complete the context
+ establishment, one or more reply tokens may be required from the peer
+ application; if so, gss_accept_sec_context will return a status flag of
+ GSS_S_CONTINUE_NEEDED, in which case it should be called again when the
+ reply token is received from the peer application, passing the token to
+ gss_accept_sec_context via the input_token parameters.
+
+ Portable applications should be constructed to use the token length and
+ return status to determine whether a token needs to be sent or waited
+ for. Thus a typical portable caller should always invoke
+ gss_accept_sec_context within a loop:
+
+ gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
+ ...
+
+ do {
+ receive_token_from_peer(input_token);
+ maj_stat = gss_accept_sec_context(&min_stat,
+ &context_hdl,
+ cred_hdl,
+ input_token,
+ input_bindings,
+ &client_name,
+ &mech_type,
+ output_token,
+ &ret_flags,
+ &time_rec,
+ &deleg_cred);
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 25]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ if (GSS_ERROR(maj_stat)) {
+ report_error(maj_stat, min_stat);
+ };
+ if (output_token->length != 0) {
+ send_token_to_peer(output_token);
+ gss_release_buffer(&min_stat,
+ output_token)
+ };
+ if (GSS_ERROR(maj_stat)) {
+ if (context_hdl != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&min_stat,
+ &context_hdl,
+ GSS_C_NO_BUFFER);
+ break;
+ };
+ } while (maj_stat & GSS_S_CONTINUE_NEEDED);
+
+
+ Whenever the routine returns a major status that includes the value
+ GSS_S_CONTINUE_NEEDED, the context is not fully established and the
+ following restrictions apply to the output parameters:
+
+ (a) The value returned via the time_rec parameter is undefined
+
+ (b) Unless the accompanying ret_flags parameter contains the bit
+ GSS_C_PROT_READY_FLAG, indicating that per-message services may be
+ applied in advance of a successful completion status, the value
+ returned via the mech_type parameter may be undefined until the
+ routine returns a major status value of GSS_S_COMPLETE.
+
+ (c) The values of the GSS_C_DELEG_FLAG, GSS_C_MUTUAL_FLAG,
+ GSS_C_REPLAY_FLAG, GSS_C_SEQUENCE_FLAG, GSS_C_CONF_FLAG,
+ GSS_C_INTEG_FLAG and GSS_C_ANON_FLAG bits returned via the
+ ret_flags parameter should contain the values that the
+ implementation expects would be valid if context establishment
+ were to succeed.
+
+ The values of the GSS_C_PROT_READY_FLAG and GSS_C_TRANS_FLAG bits
+ within ret_flags should indicate the actual state at the time
+ gss_accept_sec_context returns, whether or not the context is
+ fully established.
+
+ Although this requires that GSSAPI implementations set the
+ GSS_C_PROT_READY_FLAG in the final ret_flags returned to a caller
+ (i.e. when accompanied by a GSS_S_COMPLETE status code),
+ applications should not rely on this behavior as the flag was not
+ defined in Version 1 of the GSSAPI. Instead, applications should
+ be prepared to use per-message services after a successful context
+ establishment, according to the GSS_C_INTEG_FLAG and
+ GSS_C_CONF_FLAG values.
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 26]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ All other bits within the ret_flags argument should be set to
+ zero.
+
+
+ While the routine returns GSS_S_CONTINUE_NEEDED, the values returned via
+ the ret_flags argument indicate the services that the implementation
+ expects to be available from the established context.
+
+ If the initial call of gss_accept_sec_context() fails, the
+ implementation should not create a context object, and should leave the
+ value of the context_handle parameter set to GSS_C_NO_CONTEXT to
+ indicate this. In the event of a failure on a subsequent call, the
+ implementation is permitted to delete the "half-built" security context
+ (in which case it should set the context_handle parameter to
+ GSS_C_NO_CONTEXT), but the preferred behavior is to leave the security
+ context (and the context_handle parameter) untouched for the application
+ to delete (using gss_delete_sec_context).
+
+ Parameters:
+
+ context_handle gss_ctx_id_t, read/modify
+ context handle for new context. Supply
+ GSS_C_NO_CONTEXT for first call; use value
+ returned in subsequent calls. Once
+ gss_accept_sec_context() has returned a value
+ via this parameter, resources have been assigned
+ to the corresponding context, and must be
+ freed by the application after use with a call
+ to gss_delete_sec_context().
+
+
+ acceptor_cred_handle gss_cred_id_t, read
+ Credential handle claimed by context acceptor.
+ Specify GSS_C_NO_CREDENTIAL to accept the
+ context as a default principal. If
+ GSS_C_NO_CREDENTIAL is specified, but no
+ default acceptor principal is defined,
+ GSS_S_NO_CRED will be returned.
+
+ input_token_buffer buffer, opaque, read
+ token obtained from remote application.
+
+ input_chan_bindings channel bindings, read, optional
+ Application-specified bindings. Allows
+ application to securely bind channel
+ identification information to the security
+ context. If channel bindings are not
+ used, specify GSS_C_NO_CHANNEL_BINDINGS.
+
+ src_name gss_name_t, modify, optional
+ Authenticated name of context initiator.
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 27]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ After use, this name should be deallocated by
+ passing it to gss_release_name(). If not
+ required, specify NULL.
+
+ mech_type Object ID, modify, optional
+ Security mechanism used. The returned
+ OID value will be a pointer into static
+ storage, and should be treated as read-only
+ by the caller (in particular, it does not
+ need to be freed). If not required, specify
+ NULL.
+
+ output_token buffer, opaque, modify
+ Token to be passed to peer application. If the
+ length field of the returned token buffer is 0,
+ then no token need be passed to the peer
+ application. If a non-zero length field is
+ returned, the associated storage must be freed
+ after use by the application with a call to
+ gss_release_buffer().
+
+ ret_flags bit-mask, modify, optional
+ Contains various independent flags, each of
+ which indicates that the context supports a
+ specific service option. If not needed,
+ specify NULL. Symbolic names are
+ provided for each flag, and the symbolic names
+ corresponding to the required flags
+ should be logically-ANDed with the ret_flags
+ value to test whether a given option is
+ supported by the context. The flags are:
+ GSS_C_DELEG_FLAG
+ True - Delegated credentials are available
+ via the delegated_cred_handle
+ parameter
+ False - No credentials were delegated
+ GSS_C_MUTUAL_FLAG
+ True - Remote peer asked for mutual
+ authentication
+ False - Remote peer did not ask for mutual
+ authentication
+ GSS_C_REPLAY_FLAG
+ True - replay of protected messages
+ will be detected
+ False - replayed messages will not be
+ detected
+ GSS_C_SEQUENCE_FLAG
+ True - out-of-sequence protected
+ messages will be detected
+ False - out-of-sequence messages will not
+ be detected
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 28]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_C_CONF_FLAG
+ True - Confidentiality service may be invoked
+ by calling the gss_wrap routine
+ False - No confidentiality service (via
+ gss_wrap) available. gss_wrap will
+ provide message encapsulation,
+ data-origin authentication and
+ integrity services only.
+ GSS_C_INTEG_FLAG
+ True - Integrity service may be invoked by
+ calling either gss_get_mic or gss_wrap
+ routines.
+ False - Per-message integrity service
+ unavailable.
+ GSS_C_ANON_FLAG
+ True - The initiator does not wish to
+ be authenticated; the src_name
+ parameter (if requested) contains
+ an anonymous internal name.
+ False - The initiator has been
+ authenticated normally.
+ GSS_C_PROT_READY_FLAG
+ True - Protection services (as specified
+ by the states of the GSS_C_CONF_FLAG
+ and GSS_C_INTEG_FLAG) are available
+ if the accompanying major status return
+ value is either GSS_S_COMPLETE or
+ GSS_S_CONTINUE_NEEDED.
+ False - Protection services (as specified
+ by the states of the GSS_C_CONF_FLAG
+ and GSS_C_INTEG_FLAG) are available
+ only if the accompanying major status
+ return value is GSS_S_COMPLETE.
+ GSS_C_TRANS_FLAG
+ True - The resultant security context may
+ be transferred to other processes via
+ a call to gss_export_sec_context().
+ False - The security context is not
+ transferrable.
+ All other bits should be set to zero.
+
+ time_rec Integer, modify, optional
+ number of seconds for which the context
+ will remain valid. Specify NULL if not required.
+
+ delegated_cred_handle
+ gss_cred_id_t, modify, optional
+ credential handle for credentials received from
+ context initiator. Only valid if deleg_flag in
+ ret_flags is true, in which case an explicit
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 29]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ credential handle (i.e. not GSS_C_NO_CREDENTIAL)
+ will be returned; if deleg_flag is false,
+ gss_accept_context() will set this parameter to
+ GSS_C_NO_CREDENTIAL. If a credential handle is
+ returned, the associated resources must be released
+ by the application after use with a call to
+ gss_release_cred(). Specify NULL if not required.
+
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTINUE_NEEDED Indicates that a token from the peer application
+ is required to complete the context, and that
+ gss_accept_sec_context must be called again with that
+ token.
+
+ GSS_S_DEFECTIVE_TOKEN Indicates that consistency checks performed on the
+ input_token failed.
+
+ GSS_S_DEFECTIVE_CREDENTIAL Indicates that consistency checks performed
+ on the credential failed.
+
+ GSS_S_NO_CRED The supplied credentials were not valid for context
+ acceptance, or the credential handle did not reference
+ any credentials.
+
+ GSS_S_CREDENTIALS_EXPIRED The referenced credentials have expired.
+
+ GSS_S_BAD_BINDINGS The input_token contains different channel bindings
+ to those specified via the input_chan_bindings
+ parameter.
+
+ GSS_S_NO_CONTEXT Indicates that the supplied context handle did not
+ refer to a valid context.
+
+ GSS_S_BAD_SIG The input_token contains an invalid MIC.
+
+ GSS_S_OLD_TOKEN The input_token was too old. This is a fatal error
+ during context establishment.
+
+ GSS_S_DUPLICATE_TOKEN The input_token is valid, but is a duplicate of a
+ token already processed. This is a fatal error during
+ context establishment.
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 30]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_S_BAD_MECH The received token specified a mechanism that is not
+ supported by the implementation or the provided
+ credential.
+
+
+
+
+
+
+
+ 7.2. gss_acquire_cred
+
+
+ OM_uint32 gss_acquire_cred (
+ OM_uint32 * minor_status,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ const gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t * output_cred_handle,
+ gss_OID_set * actual_mechs,
+ OM_uint32 * time_rec)
+
+ Purpose:
+
+ Allows an application to acquire a handle for a pre-existing credential
+ by name. GSS-API implementations must impose a local access-control
+ policy on callers of this routine to prevent unauthorized callers from
+ acquiring credentials to which they are not entitled. This routine is
+ not intended to provide a ``login to the network'' function, as such a
+ function would involve the creation of new credentials rather than
+ merely acquiring a handle to existing credentials. Such functions, if
+ required, should be defined in implementation-specific extensions to the
+ API.
+
+ If desired_name is GSS_C_NO_NAME, the call is interpreted as a request
+ for a credential handle that will invoke default behavior when passed to
+ gss_init_sec_context() (if cred_usage is GSS_C_INITIATE or GSS_C_BOTH)
+ or gss_accept_sec_context() (if cred_usage is GSS_C_ACCEPT or
+ GSS_C_BOTH).
+
+ This routine is expected to be used primarily by context acceptors,
+ since implementations are likely to provide mechanism-specific ways of
+ obtaining GSS-API initiator credentials from the system login process.
+ Some implementations may therefore not support the acquisition of
+ GSS_C_INITIATE or GSS_C_BOTH credentials via gss_acquire_cred for any
+ name other than an empty name.
+
+ If credential acquisition is time-consuming for a mechanism, the
+ mechanism may chooses to delay the actual acquisition until the
+ credential is required (e.g. by gss_init_sec_context or
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 31]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ gss_accept_sec_context). Such mechanism-specific implementation
+ decisions should be invisible to the calling application; thus a call of
+ gss_inquire_cred immediately following the call of gss_acquire_cred must
+ return valid credential data, and may therefore incur the overhead of a
+ deferred credential acquisition.
+
+ Parameters:
+
+ desired_name gss_name_t, read
+ Name of principal whose credential
+ should be acquired
+
+ time_req Integer, read, optional
+ number of seconds that credentials
+ should remain valid. Specify GSS_C_INDEFINITE
+ to request that the credentials have the maximum
+ permitted lifetime.
+
+ desired_mechs Set of Object IDs, read, optional
+ set of underlying security mechanisms that
+ may be used. GSS_C_NO_OID_SET may be used
+ to obtain an implementation-specific default.
+
+ cred_usage gss_cred_usage_t, read
+ GSS_C_BOTH - Credentials may be used
+ either to initiate or accept
+ security contexts.
+ GSS_C_INITIATE - Credentials will only be
+ used to initiate security
+ contexts.
+ GSS_C_ACCEPT - Credentials will only be used to
+ accept security contexts.
+
+ output_cred_handle gss_cred_id_t, modify
+ The returned credential handle. Resources
+ associated with this credential handle must
+ be released by the application after use
+ with a call to gss_release_cred().
+
+ actual_mechs Set of Object IDs, modify, optional
+ The set of mechanisms for which the
+ credential is valid. Storage associated
+ with the returned OID-set must be released by
+ the application after use with a call to
+ gss_release_oid_set(). Specify NULL if not
+ required.
+
+ time_rec Integer, modify, optional
+ Actual number of seconds for which the
+ returned credentials will remain valid. If the
+ implementation does not support expiration of
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 32]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ credentials, the value GSS_C_INDEFINITE will
+ be returned. Specify NULL if not required
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_MECH Unavailable mechanism requested
+
+ GSS_S_BAD_NAMETYPE Type contained within desired_name parameter is not
+ supported
+
+ GSS_S_BAD_NAME Value supplied for desired_name parameter is ill-
+ formed.
+
+ GSS_S_CREDENTIALS_EXPIRED The credentials could not be acquired because
+ they have expired.
+
+ GSS_S_NO_CRED No credentials were found for the specified name.
+
+
+
+
+
+
+
+ 7.3. gss_add_cred
+
+
+ OM_uint32 gss_add_cred (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t input_cred_handle,
+ const gss_name_t desired_name,
+ const gss_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t * output_cred_handle,
+ gss_OID_set * actual_mechs,
+ OM_uint32 * initiator_time_rec,
+ OM_uint32 * acceptor_time_rec)
+
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 33]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Purpose:
+
+ Adds a credential-element to a credential. The credential-element is
+ identified by the name of the principal to which it refers. GSSAPI
+ implementations must impose a local access-control policy on callers of
+ this routine to prevent unauthorized callers from acquiring credential-
+ elements to which they are not entitled. This routine is not intended to
+ provide a ``login to the network'' function, as such a function would
+ involve the creation of new mechanism-specific authentication data,
+ rather than merely acquiring a GSSAPI handle to existing data. Such
+ functions, if required, should be defined in implementation-specific
+ extensions to the API.
+
+ This routine is expected to be used primarily by context acceptors,
+ since implementations are likely to provide mechanism-specific ways of
+ obtaining GSS-API initiator credentials from the system login process.
+ Some implementations may therefore not support the acquisition of
+ GSS_C_INITIATE or GSS_C_BOTH credentials via gss_acquire_cred.
+
+ If credential acquisition is time-consuming for a mechanism, the
+ mechanism may chooses to delay the actual acquisition until the
+ credential is required (e.g. by gss_init_sec_context or
+ gss_accept_sec_context). Such mechanism-specific implementation
+ decisions should be invisible to the calling application; thus a call of
+ gss_inquire_cred immediately following the call of gss_acquire_cred must
+ return valid credential data, and may therefore incur the overhead of a
+ deferred credential acquisition.
+
+ This routine can be used to either create a new credential containing
+ all credential-elements of the original in addition to the newly-acquire
+ credential-element, or to add the new credential-element to an existing
+ credential. If NULL is specified for the output_cred_handle parameter
+ argument, the new credential-element will be added to the credential
+ identified by input_cred_handle; if a valid pointer is specified for the
+ output_cred_handle parameter, a new credential and handle will be
+ created.
+
+ If GSS_C_NO_CREDENTIAL is specified as the input_cred_handle, the
+ gss_add_cred will create its output_cred_handle based on default
+ behavior. That is, the call will have the same effect as if the
+ application had first made a call to gss_acquire_cred(), specifying the
+ same usage and passing GSS_C_NO_NAME as the desired_name parameter to
+ obtain an explicit credential handle embodying default behavior, passed
+ this credential handle to gss_add_cred(), and finally called
+ gss_release_cred() on the first credential handle.
+
+ If GSS_C_NO_CREDENTIAL is specified as the input_cred_handle parameter,
+ a non-NULL output_cred_handle must be supplied.
+
+ Parameters:
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 34]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ input_cred_handle gss_cred_id_t, read, optional
+ The credential to which a credential-element
+ will be added. If GSS_C_NO_CREDENTIAL is
+ specified, the routine will create the new
+ credential based on default behavior (see
+ description above). Note that, while the
+ credential-handle is not modified by
+ gss_add_cred(), the underlying credential
+ will be modified if output_credential_handle
+ is NULL.
+
+ desired_name gss_name_t, read.
+ Name of principal whose credential
+ should be acquired.
+
+ desired_mech Object ID, read
+ Underlying security mechanism with which the
+ credential may be used.
+
+ cred_usage gss_cred_usage_t, read
+ GSS_C_BOTH - Credential may be used
+ either to initiate or accept
+ security contexts.
+ GSS_C_INITIATE - Credential will only be
+ used to initiate security
+ contexts.
+ GSS_C_ACCEPT - Credential will only be used to
+ accept security contexts.
+
+ initiator_time_req Integer, read, optional
+ number of seconds that the credential
+ should remain valid for initiating security
+ contexts. This argument is ignored if the
+ created credentials are of type GSS_C_ACCEPT.
+ Specify GSS_C_INDEFINITE to request that the
+ credentials have the maximum permitted initiator
+ lifetime.
+
+ acceptor_time_req Integer, read, optional
+ number of seconds that the credential
+ should remain valid for accepting security
+ contexts. This argument is ignored if the
+ created credentials are of type GSS_C_INITIATE.
+ Specify GSS_C_INDEFINITE to request that the
+ credentials have the maximum permitted initiator
+ lifetime.
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 35]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ output_cred_handle gss_cred_id_t, modify, optional
+ The returned credential handle, containing
+ the new credential-element and all the
+ credential-elements from input_cred_handle.
+ If a valid pointer to a gss_cred_id_t is
+ supplied for this parameter, gss_add_cred
+ creates a new credential handle containing all
+ credential-elements from the input_cred_handle
+ and the newly acquired credential-element; if
+ NULL is specified for this parameter, the newly
+ acquired credential-element will be added
+ to the credential identified by input_cred_handle.
+ The resources associated with any credential
+ handle returned via this parameter must be
+ released by the application after use with a
+ call to gss_release_cred().
+
+ actual_mechs Set of Object IDs, modify, optional
+ The complete set of mechanisms for which
+ the new credential is valid. Storage for
+ the returned OID-set must be freed by the
+ application after use with a call to
+ gss_release_oid_set(). Specify NULL if
+ not required.
+
+ initiator_time_rec Integer, modify, optional
+ Actual number of seconds for which the
+ returned credentials will remain valid for
+ initiating contexts using the specified
+ mechanism. If the implementation or mechanism
+ does not support expiration of credentials, the
+ value GSS_C_INDEFINITE will be returned. Specify
+ NULL if not required
+
+ acceptor_time_rec Integer, modify, optional
+ Actual number of seconds for which the
+ returned credentials will remain valid for
+ accepting security contexts using the specified
+ mechanism. If the implementation or mechanism
+ does not support expiration of credentials, the
+ value GSS_C_INDEFINITE will be returned. Specify
+ NULL if not required
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_MECH Unavailable mechanism requested
+
+ GSS_S_BAD_NAMETYPE Type contained within desired_name parameter is not
+ supported
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 36]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_S_BAD_NAME Value supplied for desired_name parameter is ill-
+ formed.
+
+ GSS_S_DUPLICATE_ELEMENT The credential already contains an element for
+ the requested mechanism with overlapping usage and
+ validity period.
+
+ GSS_S_CREDENTIALS_EXPIRED The required credentials could not be added
+ because they have expired.
+
+ GSS_S_NO_CRED No credentials were found for the specified name.
+
+
+
+
+
+
+
+ 7.4. gss_add_oid_set_member
+
+ OM_uint32 gss_add_oid_set_member (
+ OM_uint32 * minor_status,
+ const gss_OID member_oid,
+ gss_OID_set * oid_set)
+
+ Purpose:
+
+ Add an Object Identifier to an Object Identifier set. This routine is
+ intended for use in conjunction with gss_create_empty_oid_set when
+ constructing a set of mechanism OIDs for input to gss_acquire_cred.
+
+ The oid_set parameter must refer to an OID-set that was created by
+ GSSAPI (e.g. a set returned by gss_create_empty_oid_set()). GSSAPI
+ creates a copy of the member_oid and inserts this copy into the set,
+ expanding the storage allocated to the OID-set's elements array if
+ necessary. The routine may add the new member OID anywhere within the
+ elements array, and implementations should verify that the new
+ member_oid is not already contained within the elements array.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ member_oid Object ID, read
+ The object identifier to copied into
+ the set.
+
+ oid_set Set of Object ID, modify
+ The set in which the object identifier
+ should be inserted.
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 37]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+
+
+
+
+
+
+ 7.5. gss_canonicalize_name
+
+ OM_uint32 gss_canonicalize_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ const gss_OID mech_type,
+ gss_name_t * output_name)
+
+ Purpose:
+
+ Generate a canonical mechanism name (MN) from an arbitrary internal
+ name. The mechanism name is the name that would be returned to a
+ context acceptor on successful authentication of a context where the
+ initiator used the input_name in a successful call to gss_acquire_cred,
+ specifying an OID set containing <mech_type> as its only member,
+ followed by a call to gss_init_sec_context, specifying <mech_type> as
+ the authentication mechanism.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ input_name gss_name_t, read
+ The name for which a canonical form is
+ desired
+
+ mech_type Object ID, read
+ The authentication mechanism for which the
+ canonical form of the name is desired. The
+ desired mechanism must be specified explicitly;
+ no default is provided.
+
+ output_name gss_name_t, modify
+ The resultant canonical name. Storage
+ associated with this name must be freed by
+ the application after use with a call to
+ gss_release_name().
+
+ Function value: GSS status code
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 38]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_S_COMPLETE Successful completion.
+
+ GSS_S_BAD_MECH The identified mechanism is not supported.
+
+ GSS_S_BAD_NAMETYPE The provided internal name contains no elements that
+ could be processed by the sepcified mechanism.
+
+ GSS_S_BAD_NAME The provided internal name was ill-formed.
+
+
+
+
+
+
+
+ 7.6. gss_compare_name
+
+ OM_uint32 gss_compare_name (
+ OM_uint32 * minor_status,
+ const gss_name_t name1,
+ const gss_name_t name2,
+ int * name_equal)
+
+ Purpose:
+
+ Allows an application to compare two internal-form names to determine
+ whether they refer to the same entity.
+
+ If either name presented to gss_compare_name denotes an anonymous
+ principal, the routines should indicate that the two names do not refer
+ to the same identity.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ name1 gss_name_t, read
+ internal-form name
+
+ name2 gss_name_t, read
+ internal-form name
+
+ name_equal boolean, modify
+ non-zero - names refer to same entity
+ zero - names refer to different entities
+ (strictly, the names are not known
+ to refer to the same identity).
+
+ Function value: GSS status code
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 39]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_NAMETYPE The two names were of incomparable types.
+
+ GSS_S_BAD_NAME One or both of name1 or name2 was ill-formed
+
+
+
+
+
+
+
+ 7.7. gss_context_time
+
+ OM_uint32 gss_context_time (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ OM_uint32 * time_rec)
+
+ Purpose:
+
+ Determines the number of seconds for which the specified context will
+ remain valid.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Implementation specific status code.
+
+ context_handle gss_ctx_id_t, read
+ Identifies the context to be interrogated.
+
+ time_rec Integer, modify
+ Number of seconds that the context will remain
+ valid. If the context has already expired,
+ zero will be returned.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTEXT_EXPIRED The context has already expired
+
+ GSS_S_NO_CONTEXT The context_handle parameter did not identify a valid
+ context
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 40]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 7.8. gss_create_empty_oid_set
+
+ OM_uint32 gss_create_empty_oid_set (
+ OM_uint32 * minor_status,
+ gss_OID_set * oid_set)
+
+ Purpose:
+
+ Create an object-identifier set containing no object identifiers, to
+ which members may be subsequently added using the
+ gss_add_oid_set_member() routine. These routines are intended to be
+ used to construct sets of mechanism object identifiers, for input to
+ gss_acquire_cred.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ oid_set Set of Object IDs, modify
+ The empty object identifier set.
+ The routine will allocate the
+ gss_OID_set_desc object, which the
+ application must free after use with
+ a call to gss_release_oid_set().
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+
+
+
+
+
+
+ 7.9. gss_delete_sec_context
+
+ OM_uint32 gss_delete_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t output_token)
+
+ Purpose:
+
+ Delete a security context. gss_delete_sec_context will delete the local
+ data structures associated with the specified security context, and may
+ generate an output_token, which when passed to the peer
+ gss_process_context_token will instruct it to do likewise. If no token
+ is required by the mechanism, the GSS-API should set the length field of
+ the output_token (if provided) to zero. No further security services
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 41]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ may be obtained using the context specified by context_handle.
+
+ In addition to deleting established security contexts,
+ gss_delete_sec_context must also be able to delete "half-built" security
+ contexts resulting from an incomplete sequence of
+ gss_init_sec_context()/gss_accept_sec_context() calls.
+
+ The output_token parameter is retained for compatibility with version 1
+ of the GSS-API. It is recommended that both peer applications invoke
+ gss_delete_sec_context passing the value GSS_C_NO_BUFFER for the
+ output_token parameter, indicating that no token is required, and that
+ gss_delete_sec_context should simply delete local context data
+ structures. If the application does pass a valid buffer to
+ gss_delete_sec_context, mechanisms are encouraged to return a zero-
+ length token, indicating that no peer action is necessary, and that no
+ token should be transferred by the application.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ context_handle gss_ctx_id_t, modify
+ context handle identifying context to delete.
+ After deleting the context, the GSSAPI will set
+ this context handle to GSS_C_NO_CONTEXT.
+
+ output_token buffer, opaque, modify, optional
+ token to be sent to remote application to
+ instruct it to also delete the context. It
+ is recommended that applications specify
+ GSS_C_NO_BUFFER for this parameter, requesting
+ local deletion only. If a buffer parameter is
+ provided by the application, the mechanism may
+ return a token in it; mechanisms that implement
+ only local deletion should set the length field of
+ this token to zero to indicate to the application
+ that no token is to be sent to the peer.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_NO_CONTEXT No valid context was supplied
+
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 42]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 7.10. gss_display_name
+
+ OM_uint32 gss_display_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t output_name_buffer,
+ gss_OID * output_name_type)
+
+ Purpose:
+
+ Allows an application to obtain a textual representation of an opaque
+ internal-form name for display purposes. The syntax of a printable
+ name is defined by the GSS-API implementation.
+
+ If input_name denotes an anonymous principal, the implementation should
+ return the gss_OID value GSS_C_NT_ANONYMOUS as the output_name_type, and
+ a textual name that is syntactically distinct from all valid supported
+ printable names in output_name_buffer.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ input_name gss_name_t, read
+ name to be displayed
+
+ output_name_buffer buffer, character-string, modify
+ buffer to receive textual name string.
+ The application must free storage associated
+ with this name after use with a call to
+ gss_release_buffer().
+
+ output_name_type Object ID, modify, optional
+ The type of the returned name. The returned
+ gss_OID will be a pointer into static storage,
+ and should be treated as read-only by the caller
+ (in particular, it does not need to be freed).
+ Specify NULL if not required.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_NAME input_name was ill-formed
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 43]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 7.11. gss_display_status
+
+ OM_uint32 gss_display_status (
+ OM_uint32 * minor_status,
+ OM_uint32 status_value,
+ int status_type,
+ const gss_OID mech_type,
+ OM_uint32 * message_context,
+ gss_buffer_t status_string)
+
+ Purpose:
+
+ Allows an application to obtain a textual representation of a GSS-API
+ status code, for display to the user or for logging purposes. Since
+ some status values may indicate multiple conditions, applications may
+ need to call gss_display_status multiple times, each call generating a
+ single text string. The message_context parameter is used by
+ gss_acquire_cred to store state information about which error messages
+ have already been extracted from a given status_value; message_context
+ must be initialized to 0 by the application prior to the first call, and
+ gss_display_status will return a non-zero value in this parameter if
+ there are further messages to extract. The message_context parameter
+ contains all state information required by gss_display_status in order
+ to extract further messages from the status_value; even when a non-zero
+ value is returned in this parameter, the application is not required to
+ call gss_display_status again unless subsequent messages are desired.
+ The following code extracts all messages from a given status code and
+ prints them to stderr:
+
+
+ OM_uint32 message_context;
+ OM_uint32 status_code;
+ OM_uint32 maj_status;
+ OM_uint32 min_status;
+ gss_buffer_desc status_string;
+
+ ...
+
+ message_context = 0;
+
+ do {
+
+ maj_status = gss_display_status (&min_status,
+ status_code,
+ GSS_C_GSS_CODE,
+ GSS_C_NO_OID,
+ &message_context,
+ &status_string)
+
+ fprintf(stderr,
+ "%.*s\n",
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 44]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ status_string.length,
+ status_string.value);
+
+ gss_release_buffer(&min_status,
+ &status_string);
+
+ } while (message_context != 0);
+
+
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ status_value Integer, read
+ Status value to be converted
+
+ status_type Integer, read
+ GSS_C_GSS_CODE - status_value is a GSS status
+ code
+ GSS_C_MECH_CODE - status_value is a mechanism
+ status code
+
+ mech_type Object ID, read, optional
+ Underlying mechanism (used to interpret a
+ minor status value) Supply GSS_C_NO_OID to
+ obtain the system default.
+
+ message_context Integer, read/modify
+ Should be initialized to zero by the
+ application prior to the first call.
+ On return from gss_display_status(),
+ a non-zero status_value parameter indicates
+ that additional messages may be extracted
+ from the status code via subsequent calls
+ to gss_display_status(), passing the same
+ status_value, status_type, mech_type, and
+ message_context parameters.
+
+ status_string buffer, character string, modify
+ textual interpretation of the status_value.
+ Storage associated with this parameter must
+ be freed by the application after use with
+ a call to gss_release_buffer().
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 45]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_S_BAD_MECH Indicates that translation in accordance with an
+ unsupported mechanism type was requested
+
+ GSS_S_BAD_STATUS The status value was not recognized, or the status
+ type was neither GSS_C_GSS_CODE nor GSS_C_MECH_CODE.
+
+
+
+
+
+
+
+ 7.12. gss_duplicate_name
+
+ OM_uint32 gss_duplicate_name (
+ OM_uint32 * minor_status,
+ const gss_name_t src_name,
+ gss_name_t * dest_name)
+
+ Purpose:
+
+ Create an exact duplicate of the existing internal name src_name. The
+ new dest_name will be independent of src_name (i.e. src_name and
+ dest_name must both be released, and the release of one shall not affect
+ the validity of the other).
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ src_name gss_name_t, read
+ internal name to be duplicated.
+
+ dest_name gss_name_t, modify
+ The resultant copy of <src_name>.
+ Storage associated with this name must
+ be freed by the application after use
+ with a call to gss_release_name().
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_NAME The src_name parameter was ill-formed.
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 46]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 7.13. gss_export_name
+
+ OM_uint32 gss_export_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t exported_name)
+
+ Purpose:
+
+ To produce a canonical contiguous string representation of a mechanism
+ name (MN), suitable for direct comparison (e.g. with memcmp) for use in
+ authorization functions (e.g. matching entries in an access-control
+ list).
+
+ The <input_name> parameter must specify a valid MN (i.e. an internal
+ name generated by gss_accept_sec_context or by gss_canonicalize_name).
+
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ input_name gss_name_t, read
+ The MN to be exported
+
+ exported_name gss_buffer_t, octet-string, modify
+ The canonical contiguous string form of
+ <input_name>. Storage associated with
+ this string must freed by the application
+ after use with gss_release_buffer().
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_NAME_NOT_MN The provided internal name was not a mechanism name.
+
+ GSS_S_BAD_NAME The provide internal name was ill-formed.
+
+ GSS_S_BAD_NAMETYPE The internal name was of a type not supported by the
+ GSSAPI implementation.
+
+
+
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 47]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 7.14. gss_export_sec_context
+
+ OM_uint32 gss_export_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t interprocess_token)
+
+ Purpose:
+
+ Provided to support the sharing of work between multiple processes.
+ This routine will typically be used by the context-acceptor, in an
+ application where a single process receives incoming connection requests
+ and accepts security contexts over them, then passes the established
+ context to one or more other processes for message exchange.
+ gss_export_sec_context() deactivates the security context for the
+ calling process and creates an interprocess token which, when passed to
+ gss_import_sec_context in another process, will re-activate the context
+ in the second process. Only a single instantiation of a given context
+ may be active at any one time; a subsequent attempt by a context
+ exporter to access the exported security context will fail.
+
+ The implementation may constrain the set of processes by which the
+ interprocess token may be imported, either as a function of local
+ security policy, or as a result of implementation decisions. For
+ example, some implementations may constrain contexts to be passed only
+ between processes that run under the same account, or which are part of
+ the same process group.
+
+ The interprocess token may contain security-sensitive information (for
+ example cryptographic keys). While mechanisms are encouraged to either
+ avoid placing such sensitive information within interprocess tokens, or
+ to encrypt the token before returning it to the application, in a
+ typical object-library GSSAPI implementation this may not be possible.
+ Thus the application must take care to protect the interprocess token,
+ and ensure that any process to which the token is transferred is
+ trustworthy.
+
+ If creation of the interprocess token is succesful, the implementation
+ shall deallocate all process-wide resources associated with the security
+ context, and set the context_handle to GSS_C_NO_CONTEXT. In the event
+ of an error that makes it impossible to complete the export of the
+ security context, the implementation must not return an interprocess
+ token, and should strive to leave the security context referenced by the
+ context_handle parameter untouched. If this is impossible, it is
+ permissible for the implementation to delete the security context,
+ providing it also sets the context_handle parameter to GSS_C_NO_CONTEXT.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 48]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ context_handle gss_ctx_id_t, modify
+ context handle identifying the context to transfer.
+
+ interprocess_token buffer, opaque, modify
+ token to be transferred to target process.
+ Storage associated with this token must be
+ freed by the application after use with a
+ call to gss_release_buffer().
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTEXT_EXPIRED The context has expired
+
+ GSS_S_NO_CONTEXT The context was invalid
+
+ GSS_S_UNAVAILABLE The operation is not supported.
+
+
+
+
+
+
+
+ 7.15. gss_get_mic
+
+ OM_uint32 gss_get_mic (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t msg_token)
+
+ Purpose:
+
+ Generates a cryptographic MIC for the supplied message, and places the
+ MIC in a token for transfer to the peer application. The qop_req
+ parameter allows a choice between several cryptographic algorithms, if
+ supported by the chosen mechanism.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Implementation specific status code.
+
+ context_handle gss_ctx_id_t, read
+ identifies the context on which the message
+ will be sent
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 49]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+ qop_req gss_qop_t, read, optional
+ Specifies requested quality of protection.
+ Callers are encouraged, on portability grounds,
+ to accept the default quality of protection
+ offered by the chosen mechanism, which may be
+ requested by specifying GSS_C_QOP_DEFAULT for
+ this parameter. If an unsupported protection
+ strength is requested, gss_get_mic will return a
+ major_status of GSS_S_BAD_QOP.
+
+ message_buffer buffer, opaque, read
+ message to be protected
+
+ msg_token buffer, opaque, modify
+ buffer to receive token. The application must
+ free storage associated with this buffer after
+ use with a call to gss_release_buffer().
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTEXT_EXPIRED The context has already expired
+
+ GSS_S_NO_CONTEXT The context_handle parameter did not identify a valid
+ context
+
+ GSS_S_BAD_QOP The specified QOP is not supported by the mechanism.
+
+
+
+
+
+
+
+ 7.16. gss_import_name
+
+ OM_uint32 gss_import_name (
+ OM_uint32 * minor_status,
+ const gss_buffer_t input_name_buffer,
+ const gss_OID input_name_type,
+ gss_name_t * output_name)
+
+ Purpose:
+
+ Convert a contiguous string name to internal form. In general, the
+ internal name returned (via the <output_name> parameter) will not be an
+ MN; the exception to this is if the <input_name_type> indicates that the
+ contiguous string provided via the <input_name_buffer> parameter is of
+ type GSS_C_NT_EXPORT_NAME, in which case the returned internal name will
+ be an MN for the mechanism that exported the name.
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 50]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ input_name_buffer buffer, octet-string, read
+ buffer containing contiguous string name to convert
+
+ input_name_type Object ID, read, optional
+ Object ID specifying type of printable
+ name. Applications may specify either
+ GSS_C_NO_OID to use a mechanism-specific
+ default printable syntax, or an OID registered
+ by the GSS-API implementation to name a
+ specific namespace.
+
+ output_name gss_name_t, modify
+ returned name in internal form. Storage
+ associated with this name must be freed
+ by the application after use with a call
+ to gss_release_name().
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_NAMETYPE The input_name_type was unrecognized
+
+ GSS_S_BAD_NAME The input_name parameter could not be interpreted as a
+ name of the specified type
+
+
+
+
+
+
+
+
+ 7.17. gss_import_sec_context
+
+ OM_uint32 gss_import_sec_context (
+ OM_uint32 * minor_status,
+ const gss_buffer_t interprocess_token,
+ gss_ctx_id_t * context_handle)
+
+ Purpose:
+
+ Allows a process to import a security context established by another
+ process. A given interprocess token may be imported only once. See
+ gss_export_sec_context.
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 51]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ interprocess_token buffer, opaque, modify
+ token received from exporting process
+
+ context_handle gss_ctx_id_t, modify
+ context handle of newly reactivated context.
+ Resources associated with this context handle
+ must be released by the application after use
+ with a call to gss_delete_sec_context().
+
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion.
+
+ GSS_S_NO_CONTEXT The token did not contain a valid context reference.
+
+ GSS_S_DEFECTIVE_TOKEN The token was invalid.
+
+ GSS_S_UNAVAILABLE The operation is unavailable.
+
+ GSS_S_UNAUTHORIZED Local policy prevents the import of this context by
+ the current process..
+
+
+
+
+
+
+
+ 7.18. gss_indicate_mechs
+
+ OM_uint32 gss_indicate_mechs (
+ OM_uint32 * minor_status,
+ gss_OID_set * mech_set)
+
+ Purpose:
+
+ Allows an application to determine which underlying security mechanisms
+ are available.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 52]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+ mech_set set of Object IDs, modify
+ set of implementation-supported mechanisms.
+ The returned gss_OID_set value will be a
+ dynamically-allocated OID set, that should
+ be released by the caller after use with a
+ call to gss_release_oid_set().
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+
+
+
+
+
+
+ 7.19. gss_init_sec_context
+
+ OM_uint32 gss_init_sec_context (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t
+ input_chan_bindings,
+ const gss_buffer_t input_token
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec )
+
+ Purpose:
+
+ Initiates the establishment of a security context between the
+ application and a remote peer. Initially, the input_token parameter
+ should be specified either as GSS_C_NO_BUFFER, or as a pointer to a
+ gss_buffer_desc object whose length field contains the value zero. The
+ routine may return a output_token which should be transferred to the
+ peer application, where the peer application will present it to
+ gss_accept_sec_context. If no token need be sent, gss_init_sec_context
+ will indicate this by setting the length field of the output_token
+ argument to zero. To complete the context establishment, one or more
+ reply tokens may be required from the peer application; if so,
+ gss_init_sec_context will return a status containing the supplementary
+ information bit GSS_S_CONTINUE_NEEDED. In this case,
+ gss_init_sec_context should be called again when the reply token is
+ received from the peer application, passing the reply token to
+ gss_init_sec_context via the input_token parameters.
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 53]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Portable applications should be constructed to use the token length and
+ return status to determine whether a token needs to be sent or waited
+ for. Thus a typical portable caller should always invoke
+ gss_init_sec_context within a loop:
+
+ int context_established = 0;
+ gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
+ ...
+ input_token->length = 0;
+
+ while (!context_established) {
+ maj_stat = gss_init_sec_context(&min_stat,
+ cred_hdl,
+ &context_hdl,
+ target_name,
+ desired_mech,
+ desired_services,
+ desired_time,
+ input_bindings,
+ input_token,
+ &actual_mech,
+ output_token,
+ &actual_services,
+ &actual_time);
+ if (GSS_ERROR(maj_stat)) {
+ report_error(maj_stat, min_stat);
+ };
+ if (output_token->length != 0) {
+ send_token_to_peer(output_token);
+ gss_release_buffer(&min_stat,
+ output_token)
+ };
+ if (GSS_ERROR(maj_stat)) {
+ if (context_hdl != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&min_stat,
+ &context_hdl,
+ GSS_C_NO_BUFFER);
+ break;
+ };
+ if (maj_stat & GSS_S_CONTINUE_NEEDED) {
+ receive_token_from_peer(input_token);
+ } else {
+ context_established = 1;
+ };
+ };
+
+ Whenever the routine returns a major status that includes the value
+ GSS_S_CONTINUE_NEEDED, the context is not fully established and the
+ following restrictions apply to the output parameters:
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 54]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ (a) The value returned via the time_rec parameter is undefined
+
+ (b) Unless the accompanying ret_flags parameter contains the bit
+ GSS_C_PROT_READY_FLAG, indicating that per-message services may be
+ applied in advance of a successful completion status, the value
+ returned via the actual_mech_type parameter is undefined until the
+ routine returns a major status value of GSS_S_COMPLETE.
+
+ (c) The values of the GSS_C_DELEG_FLAG, GSS_C_MUTUAL_FLAG,
+ GSS_C_REPLAY_FLAG, GSS_C_SEQUENCE_FLAG, GSS_C_CONF_FLAG,
+ GSS_C_INTEG_FLAG and GSS_C_ANON_FLAG bits returned via the
+ ret_flags parameter should contain the values that the
+ implementation expects would be valid if context establishment
+ were to succeed. In particular, if the application has requested
+ a service such as delegation or anonymous authentication via the
+ req_flags argument, and such a service is unavailable from the
+ underlying mechanism, gss_init_sec_context should generate a token
+ that will not provide the service, and indicate via the ret_flags
+ argument that the service will not be supported. The application
+ may choose to abort the context establishment by calling
+ gss_delete_sec_context (if it cannot continue in the absence of
+ the service), or it may choose to transmit the token and continue
+ context establishment (if the service was merely desired but not
+ mandatory).
+
+ The values of the GSS_C_PROT_READY_FLAG and GSS_C_TRANS_FLAG bits
+ within ret_flags should indicate the actual state at the time
+ gss_init_sec_context returns, whether or not the context is fully
+ established.
+
+ Although this requires that GSSAPI implementations set the
+ GSS_C_PROT_READY_FLAG in the final ret_flags returned to a caller
+ (i.e. when accompanied by a GSS_S_COMPLETE status code),
+ applications should not rely on this behavior as the flag was not
+ defined in Version 1 of the GSSAPI. Instead, applications should
+ be prepared to use per-message services after a successful context
+ establishment, according to the GSS_C_INTEG_FLAG and
+ GSS_C_CONF_FLAG values.
+
+ All other bits within the ret_flags argument should be set to
+ zero.
+
+ If the initial call of gss_init_sec_context() fails, the implementation
+ should not create a context object, and should leave the value of the
+ context_handle parameter set to GSS_C_NO_CONTEXT to indicate this. In
+ the event of a failure on a subsequent call, the implementation is
+ permitted to delete the "half-built" security context (in which case it
+ should set the context_handle parameter to GSS_C_NO_CONTEXT), but the
+ preferred behavior is to leave the security context untouched for the
+ application to delete (using gss_delete_sec_context).
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 55]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ initiator_cred_handle gss_cred_id_t, read, optional
+ handle for credentials claimed. Supply
+ GSS_C_NO_CREDENTIAL to act as a default
+ initiator principal. If no default
+ initiator is defined, the function will
+ return GSS_S_NO_CRED.
+
+ context_handle gss_ctx_id_t, read/modify
+ context handle for new context. Supply
+ GSS_C_NO_CONTEXT for first call; use value
+ returned by first call in continuation calls.
+ Resources associated with this context-handle
+ must be released by the application after use
+ with a call to gee_delete_sec_context().
+
+ target_name gss_name_t, read
+ Name of target
+
+ mech_type OID, read, optional
+ Object ID of desired mechanism. Supply
+ GSS_C_NO_OID to obtain an implementation
+ specific default
+
+ req_flags bit-mask, read
+ Contains various independent flags, each of
+ which requests that the context support a
+ specific service option. Symbolic
+ names are provided for each flag, and the
+ symbolic names corresponding to the required
+ flags should be logically-ORed
+ together to form the bit-mask value. The
+ flags are:
+
+ GSS_C_DELEG_FLAG
+ True - Delegate credentials to remote peer
+ False - Don't delegate
+ GSS_C_MUTUAL_FLAG
+ True - Request that remote peer
+ authenticate itself
+ False - Authenticate self to remote peer
+ only
+ GSS_C_REPLAY_FLAG
+ True - Enable replay detection for
+ messages protected with gss_wrap
+ or gss_get_mic
+ False - Don't attempt to detect
+ replayed messages
+
+
+ Wray Document Expiration: 1 September 1997 [Page 56]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_C_SEQUENCE_FLAG
+ True - Enable detection of out-of-sequence
+ protected messages
+ False - Don't attempt to detect
+ out-of-sequence messages
+ GSS_C_ANON_FLAG
+ True - Do not reveal the initiator's
+ identity to the acceptor.
+ False - Authenticate normally.
+
+ time_req Integer, read, optional
+ Desired number of seconds for which context
+ should remain valid. Supply 0 to request a
+ default validity period.
+
+ input_chan_bindings channel bindings, read, optional
+ Application-specified bindings. Allows
+ application to securely bind channel
+ identification information to the security
+ context. Specify GSS_C_NO_CHANNEL_BINDINGS
+ if channel bindings are not used.
+
+ input_token buffer, opaque, read, optional (see text)
+ Token received from peer application.
+ Supply GSS_C_NO_BUFFER, or a pointer to
+ a buffer containing the value GSS_C_EMPTY_BUFFER
+ on initial call.
+
+ actual_mech_type OID, modify, optional
+ Actual mechanism used. The OID returned via
+ this parameter will be a pointer to static
+ storage that should be treated as read-only;
+ In particular the application should not attempt
+ to free it. Specify NULL if not required.
+
+ output_token buffer, opaque, modify
+ token to be sent to peer application. If
+ the length field of the returned buffer is
+ zero, no token need be sent to the peer
+ application. Storage associated with this
+ buffer must be freed by the application
+ after use with a call to gss_release_buffer().
+
+ ret_flags bit-mask, modify, optional
+ Contains various independent flags, each of which
+ indicates that the context supports a specific
+ service option. Specify NULL if not
+ required. Symbolic names are provided
+ for each flag, and the symbolic names
+ corresponding to the required flags should be
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 57]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ logically-ANDed with the ret_flags value to test
+ whether a given option is supported by the
+ context. The flags are:
+
+ GSS_C_DELEG_FLAG
+ True - Credentials were delegated to
+ the remote peer
+ False - No credentials were delegated
+ GSS_C_MUTUAL_FLAG
+ True - Remote peer has been asked to
+ authenticated itself
+ False - Remote peer has not been asked to
+ authenticate itself
+ GSS_C_REPLAY_FLAG
+ True - replay of protected messages
+ will be detected
+ False - replayed messages will not be
+ detected
+ GSS_C_SEQUENCE_FLAG
+ True - out-of-sequence protected
+ messages will be detected
+ False - out-of-sequence messages will
+ not be detected
+ GSS_C_CONF_FLAG
+ True - Confidentiality service may be
+ invoked by calling gss_wrap routine
+ False - No confidentiality service (via
+ gss_wrap) available. gss_wrap will
+ provide message encapsulation,
+ data-origin authentication and
+ integrity services only.
+ GSS_C_INTEG_FLAG
+ True - Integrity service may be invoked by
+ calling either gss_get_mic or gss_wrap
+ routines.
+ False - Per-message integrity service
+ unavailable.
+ GSS_C_ANON_FLAG
+ True - The initiator's identity has not been
+ revealed, and will not be revealed if
+ any emitted token is passed to the
+ acceptor.
+ False - The initiator's identity has been or
+ will be authenticated normally.
+ GSS_C_PROT_READY_FLAG
+ True - Protection services (as specified
+ by the states of the GSS_C_CONF_FLAG
+ and GSS_C_INTEG_FLAG) are available for
+ use if the accompanying major status
+ return value is either GSS_S_COMPLETE or
+ GSS_S_CONTINUE_NEEDED.
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 58]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ False - Protection services (as specified
+ by the states of the GSS_C_CONF_FLAG
+ and GSS_C_INTEG_FLAG) are available
+ only if the accompanying major status
+ return value is GSS_S_COMPLETE.
+ GSS_C_TRANS_FLAG
+ True - The resultant security context may
+ be transferred to other processes via
+ a call to gss_export_sec_context().
+ False - The security context is not
+ transferrable.
+ All other bits should be set to zero.
+
+ time_rec Integer, modify, optional
+ number of seconds for which the context
+ will remain valid. If the implementation does
+ not support context expiration, the value
+ GSS_C_INDEFINITE will be returned. Specify
+ NULL if not required.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTINUE_NEEDED Indicates that a token from the peer application
+ is required to complete the context, and that
+ gss_init_sec_context must be called again with that
+ token.
+
+ GSS_S_DEFECTIVE_TOKEN Indicates that consistency checks performed on the
+ input_token failed
+
+ GSS_S_DEFECTIVE_CREDENTIAL Indicates that consistency checks performed
+ on the credential failed.
+
+ GSS_S_NO_CRED The supplied credentials were not valid for context
+ initiation, or the credential handle did not reference
+ any credentials.
+
+ GSS_S_CREDENTIALS_EXPIRED The referenced credentials have expired
+
+ GSS_S_BAD_BINDINGS The input_token contains different channel bindings
+ to those specified via the input_chan_bindings
+ parameter
+
+ GSS_S_BAD_SIG The input_token contains an invalid MIC, or a MIC that
+ could not be verified
+
+ GSS_S_OLD_TOKEN The input_token was too old. This is a fatal error
+ during context establishment
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 59]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_S_DUPLICATE_TOKEN The input_token is valid, but is a duplicate of a
+ token already processed. This is a fatal error during
+ context establishment.
+
+ GSS_S_NO_CONTEXT Indicates that the supplied context handle did not
+ refer to a valid context
+
+ GSS_S_BAD_NAMETYPE The provided target_name parameter contained an
+ invalid or unsupported type of name
+
+ GSS_S_BAD_NAME The provided target_name parameter was ill-formed.
+
+ GSS_S_BAD_MECH The specified mechanism is not supported by the
+ provided credential, or is unrecognized by the
+ implementation.
+
+
+
+
+
+
+
+ 7.20. gss_inquire_context
+
+ OM_uint32 gss_inquire_context (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_name_t * src_name,
+ gss_name_t * targ_name,
+ OM_uint32 * lifetime_rec,
+ gss_OID * mech_type,
+ OM_uint32 * ctx_flags,
+ int * locally_initiated,
+ int * open )
+
+ Purpose:
+
+ Obtains information about a security context. The caller must already
+ have obtained a handle that refers to the context, although the context
+ need not be fully established.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ context_handle gss_ctx_id_t, read
+ A handle that refers to the security context.
+
+ src_name gss_name_t, modify, optional
+ The name of the context initiator.
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 60]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ If the context was established using anonymous
+ authentication, and if the application invoking
+ gss_inquire_context is the context acceptor,
+ an anonymous name will be returned. Storage
+ associated with this name must be freed by the
+ application after use with a call to
+ gss_release_name(). Specify NULL if not
+ required.
+
+ targ_name gss_name_t, modify, optional
+ The name of the context acceptor.
+ Storage associated with this name must be
+ freed by the application after use with a call
+ to gss_release_name(). Specify NULL if not
+ Specify NULL if not required.
+
+ lifetime_rec Integer, modify, optional
+ The number of seconds for which the context
+ will remain valid. If the context has
+ expired, this parameter will be set to zero.
+ If the implementation does not support
+ context expiration, the value
+ GSS_C_INDEFINITE will be returned. Specify
+ NULL if not required.
+
+ mech_type gss_OID, modify, optional
+ The security mechanism providing the
+ context. The returned OID will be a
+ pointer to static storage that should
+ be treated as read-only by the application;
+ in particular the application should not
+ attempt to free it. Specify NULL if not
+ required.
+
+ ctx_flags bit-mask, modify, optional
+ Contains various independent flags, each of
+ which indicates that the context supports
+ (or is expected to support, if ctx_open is
+ false) a specific service option. If not
+ needed, specify NULL. Symbolic names are
+ provided for each flag, and the symbolic names
+ corresponding to the required flags
+ should be logically-ANDed with the ret_flags
+ value to test whether a given option is
+ supported by the context. The flags are:
+
+ GSS_C_DELEG_FLAG
+ True - Credentials were delegated from
+ the initiator to the acceptor.
+ False - No credentials were delegated
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 61]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+ GSS_C_MUTUAL_FLAG
+ True - The acceptor was authenticated
+ to the initiator
+ False - The acceptor did not authenticate
+ itself.
+ GSS_C_REPLAY_FLAG
+ True - replay of protected messages
+ will be detected
+ False - replayed messages will not be
+ detected
+ GSS_C_SEQUENCE_FLAG
+ True - out-of-sequence protected
+ messages will be detected
+ False - out-of-sequence messages will not
+ be detected
+ GSS_C_CONF_FLAG
+ True - Confidentiality service may be invoked
+ by calling gss_wrap routine
+ False - No confidentiality service (via
+ gss_wrap) available. gss_wrap will
+ provide message encapsulation,
+ data-origin authentication and
+ integrity services only.
+ GSS_C_INTEG_FLAG
+ True - Integrity service may be invoked by
+ calling either gss_get_mic or gss_wrap
+ routines.
+ False - Per-message integrity service
+ unavailable.
+ GSS_C_ANON_FLAG
+ True - The initiator's identity will not
+ be revealed to the acceptor.
+ The src_name parameter (if
+ requested) contains an anonymous
+ internal name.
+ False - The initiator has been
+ authenticated normally.
+ GSS_C_PROT_READY_FLAG
+ True - Protection services (as specified
+ by the states of the GSS_C_CONF_FLAG
+ and GSS_C_INTEG_FLAG) are available
+ for use.
+ False - Protection services (as specified
+ by the states of the GSS_C_CONF_FLAG
+ and GSS_C_INTEG_FLAG) are available
+ only if the context is fully
+ established (i.e. if the open parameter
+ is non-zero).
+ GSS_C_TRANS_FLAG
+ True - The resultant security context may
+ be transferred to other processes via
+ a call to gss_export_sec_context().
+ False - The security context is not
+ transferrable.
+
+ Wray Document Expiration: 1 September 1997 [Page 62]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+
+
+ locally_initiated Boolean, modify
+ Non-zero if the invoking application is the
+ context initiator.
+ Specify NULL if not required.
+
+ open Boolean, modify
+ Non-zero if the context is fully established;
+ Zero if a context-establishment token
+ is expected from the peer application.
+ Specify NULL if not required.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_NO_CONTEXT The referenced context could not be accessed.
+
+ GSS_S_CONTEXT_EXPIRED The context has expired. If the lifetime_rec
+ parameter was requested, it will be set to 0.
+
+
+
+
+
+
+
+ 7.21. gss_inquire_cred
+
+ OM_uint32 gss_inquire_cred (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t * name,
+ OM_uint32 * lifetime,
+ gss_cred_usage_t * cred_usage,
+ gss_OID_set * mechanisms )
+
+ Purpose:
+
+ Obtains information about a credential. The caller must already have
+ obtained a handle that refers to the credential.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ cred_handle gss_cred_id_t, read
+ A handle that refers to the target credential.
+ Specify GSS_C_NO_CREDENTIAL to inquire about
+ the default initiator principal.
+
+
+ Wray Document Expiration: 1 September 1997 [Page 63]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+
+ name gss_name_t, modify, optional
+ The name whose identity the credential asserts.
+ Storage associated with this name should be freed
+ by the application after use with a call to
+ gss_release_name(). Specify NULL if not required.
+
+ lifetime Integer, modify, optional
+ The number of seconds for which the credential
+ will remain valid. If the credential has
+ expired, this parameter will be set to zero.
+ If the implementation does not support
+ credential expiration, the value
+ GSS_C_INDEFINITE will be returned. Specify
+ NULL if not required.
+
+ cred_usage gss_cred_usage_t, modify, optional
+ How the credential may be used. One of the
+ following:
+ GSS_C_INITIATE
+ GSS_C_ACCEPT
+ GSS_C_BOTH
+ Specify NULL if not required.
+
+ mechanisms gss_OID_set, modify, optional
+ Set of mechanisms supported by the credential.
+ Storage associated with this OID set must be
+ freed by the application after use with a call
+ to gss_release_oid_set(). Specify NULL if not
+ required.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_NO_CRED The referenced credentials could not be accessed.
+
+ GSS_S_DEFECTIVE_CREDENTIAL The referenced credentials were invalid.
+
+ GSS_S_CREDENTIALS_EXPIRED The referenced credentials have expired. If
+ the lifetime parameter was not passed as NULL, it will
+ be set to 0.
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 64]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 7.22. gss_inquire_cred_by_mech
+
+ OM_uint32 gss_inquire_cred_by_mech (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID mech_type,
+ gss_name_t * name,
+ OM_uint32 * initiator_lifetime,
+ OM_uint32 * acceptor_lifetime,
+ gss_cred_usage_t * cred_usage )
+
+ Purpose:
+
+ Obtains per-mechanism information about a credential. The caller must
+ already have obtained a handle that refers to the credential.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ cred_handle gss_cred_id_t, read
+ A handle that refers to the target credential.
+ Specify GSS_C_NO_CREDENTIAL to inquire about
+ the default initiator principal.
+
+ mech_type gss_OID, read
+ The mechanism for which information should be
+ returned.
+
+ name gss_name_t, modify, optional
+ The name whose identity the credential asserts.
+ Storage associated with this name must be
+ freed by the application after use with a call
+ to gss_release_name(). Specify NULL if not
+ required.
+
+ initiator_lifetime Integer, modify, optional
+ The number of seconds for which the credential
+ will remain capable of initiating security contexts
+ under the specified mechanism. If the credential
+ can no longer be used to initiate contexts, or if
+ the credential usage for this mechanism is
+ GSS_C_ACCEPT,
+ this parameter will be set to zero. If the
+ implementation does not support expiration of
+ initiator credentials, the value GSS_C_INDEFINITE
+ will be returned. Specify NULL if not required.
+
+ acceptor_lifetime Integer, modify, optional
+ The number of seconds for which the credential
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 65]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ will remain capable of accepting security contexts
+ under the specified mechanism. If the credential
+ can no longer be used to accept contexts, or if
+ the credential usage for this mechanism is
+ GSS_C_INITIATE, this parameter will be set to zero.
+ If the implementation does not support expiration
+ of acceptor credentials, the value GSS_C_INDEFINITE
+ will be returned. Specify NULL if not required.
+
+ cred_usage gss_cred_usage_t, modify, optional
+ How the credential may be used with the specified
+ mechanism. One of the following:
+ GSS_C_INITIATE
+ GSS_C_ACCEPT
+ GSS_C_BOTH
+ Specify NULL if not required.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_NO_CRED The referenced credentials could not be accessed.
+
+ GSS_S_DEFECTIVE_CREDENTIAL The referenced credentials were invalid.
+
+ GSS_S_CREDENTIALS_EXPIRED The referenced credentials have expired. If
+ the lifetime parameter was not passed as NULL, it will
+ be set to 0.
+
+
+
+
+
+
+
+ 7.23. gss_inquire_mechs_for_name
+
+ OM_uint32 gss_inquire_mechs_for_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_OID_set * mech_types )
+
+ Purpose:
+
+ Returns the set of mechanisms supported by the GSSAPI implementation
+ that may be able to process the specified name.
+
+ Each mechanism returned will recognize at least one element within the
+ name. It is permissible for this routine to be implemented within a
+ mechanism-independent GSSAPI layer, using the type information contained
+ within the presented name, and based on registration information
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 66]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ provided by individual mechanism implementations. This means that the
+ returned mech_types set may indicate that a particular mechanism will
+ understand the name when in fact it would refuse to accept the name as
+ input to gss_canonicalize_name, gss_init_sec_context, gss_acquire_cred
+ or gss_add_cred (due to some property of the specific name, as opposed
+ to the name type). Thus this routine should be used only as a pre-
+ filter for a call to a subsequent mechanism-specific routine.
+
+
+
+ Parameters:
+
+ minor_status Integer, modify
+ Implementation specific status code.
+
+ input_name gss_name_t, read
+ The name to which the inquiry relates.
+
+ mech_types gss_OID_set, modify
+ Set of mechanisms that may support the
+ specified name. The returned OID set
+ must be freed by the caller after use
+ with a call to gss_release_oid_set().
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_NAME The input_name parameter was ill-formed.
+
+ GSS_S_BAD_NAMETYPE The input_name parameter contained an invalid or
+ unsupported type of name
+
+
+
+
+
+
+ 7.24. gss_inquire_names_for_mech
+
+ OM_uint32 gss_inquire_names_for_mech (
+ OM_uint32 * minor_status,
+ const gss_OID mechanism,
+ gss_OID_set * name_types)
+
+ Purpose:
+
+ Returns the set of nametypes supported by the specified mechanism.
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 67]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Parameters:
+
+ minor_status Integer, modify
+ Implementation specific status code.
+
+ mechanism gss_OID, read
+ The mechanism to be interrogated.
+
+ name_types gss_OID_set, modify
+ Set of name-types supported by the specified
+ mechanism. The returned OID set must be
+ freed by the application after use with a
+ call to gss_release_oid_set().
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+
+
+
+
+
+
+ 7.25. gss_process_context_token
+
+ OM_uint32 gss_process_context_token (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t token_buffer)
+
+ Purpose:
+
+ Provides a way to pass a token to the security service. Used with
+ tokens emitted by gss_delete_sec_context. Note that mechanisms are
+ encouraged to perform local deletion, and not emit tokens from
+ gss_delete_sec_context. This routine, therefore, is primarily for
+ backwards compatibility with V1 applications.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Implementation specific status code.
+
+ context_handle gss_ctx_id_t, read
+ context handle of context on which token is to
+ be processed
+
+ token_buffer buffer, opaque, read
+ token to process
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 68]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_DEFECTIVE_TOKEN Indicates that consistency checks performed on the
+ token failed
+
+ GSS_S_NO_CONTEXT The context_handle did not refer to a valid context
+
+
+
+
+
+
+
+ 7.26. gss_release_buffer
+
+ OM_uint32 gss_release_buffer (
+ OM_uint32 * minor_status,
+ gss_buffer_t buffer)
+
+ Purpose:
+
+ Free storage associated with a buffer. The storage must have been
+ allocated by a GSS-API routine. In addition to freeing the associated
+ storage, the routine will zero the length field in the descriptor to
+ which the buffer parameter refers.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ buffer buffer, modify
+ The storage associated with the buffer will be
+ deleted. The gss_buffer_desc object will not
+ be freed, but its length field will be zeroed.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 69]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 7.27. gss_release_cred
+
+ OM_uint32 gss_release_cred (
+ OM_uint32 * minor_status,
+ gss_cred_id_t * cred_handle)
+
+ Purpose:
+
+ Informs GSS-API that the specified credential handle is no longer
+ required by the application, and frees associated resources.
+
+ Parameters:
+
+ cred_handle gss_cred_id_t, modify, optional
+ Opaque handle identifying credential
+ to be released. If GSS_C_NO_CREDENTIAL
+ is supplied, the routine will complete
+ successfully, but will do nothing.
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_NO_CRED Credentials could not be accessed.
+
+
+
+
+
+
+
+ 7.28. gss_release_name
+
+ OM_uint32 gss_release_name (
+ OM_uint32 * minor_status,
+ gss_name_t * name)
+
+ Purpose:
+
+ Free GSSAPI-allocated storage by associated with an internal-form name.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ name gss_name_t, modify
+ The name to be deleted
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 70]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_NAME The name parameter did not contain a valid name
+
+
+
+
+
+
+
+ 7.29. gss_release_oid_set
+
+ OM_uint32 gss_release_oid_set (
+ OM_uint32 * minor_status,
+ gss_OID_set * set)
+
+ Purpose:
+
+ Free storage associated with a GSSAPI-generated gss_OID_set object. The
+ set parameter must refer to an OID-set that was returned from a GSSAPI
+ routine. gss_release_oid_set() will free the storage associated with
+ each individual member OID, the OID set's elements array, and the
+ gss_OID_set_desc.
+
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ set Set of Object IDs, modify
+ The storage associated with the gss_OID_set
+ will be deleted.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 71]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ 7.30. gss_test_oid_set_member
+
+ OM_uint32 gss_test_oid_set_member (
+ OM_uint32 * minor_status,
+ const gss_OID member,
+ const gss_OID_set set,
+ int * present)
+
+ Purpose:
+
+ Interrogate an Object Identifier set to determine whether a specified
+ Object Identifier is a member. This routine is intended to be used with
+ OID sets returned by gss_indicate_mechs(), gss_acquire_cred(), and
+ gss_inquire_cred(), but will also work with user-generated sets.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ member Object ID, read
+ The object identifier whose presence
+ is to be tested.
+
+ set Set of Object ID, read
+ The Object Identifier set.
+
+ present Boolean, modify
+ non-zero if the specified OID is a member
+ of the set, zero if not.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+
+
+
+
+
+
+ 7.31. gss_unwrap
+
+ OM_uint32 gss_unwrap (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ gss_qop_t * qop_state)
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 72]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Purpose:
+
+ Converts a message previously protected by gss_wrap back to a usable
+ form, verifying the embedded MIC. The conf_state parameter indicates
+ whether the message was encrypted; the qop_state parameter indicates the
+ strength of protection that was used to provide the confidentiality and
+ integrity services.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ context_handle gss_ctx_id_t, read
+ Identifies the context on which the message
+ arrived
+
+ input_message_buffer buffer, opaque, read
+ protected message
+
+ output_message_buffer buffer, opaque, modify
+ Buffer to receive unwrapped message.
+ Storage associated with this buffer must
+ be freed by the application after use use
+ with a call to gss_release_buffer().
+
+ conf_state boolean, modify, optional
+ Non-zero - Confidentiality and integrity protection
+ were used
+ Zero - Integrity service only was used
+ Specify NULL if not required
+
+ qop_state gss_qop_t, modify, optional
+ Quality of protection gained from MIC.
+ Specify NULL if not required
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_DEFECTIVE_TOKEN The token failed consistency checks
+
+ GSS_S_BAD_SIG The MIC was incorrect
+
+ GSS_S_DUPLICATE_TOKEN The token was valid, and contained a correct MIC
+ for the message, but it had already been processed
+
+ GSS_S_OLD_TOKEN The token was valid, and contained a correct MIC for
+ the message, but it is too old to check for
+ duplication.
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 73]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_S_UNSEQ_TOKEN The token was valid, and contained a correct MIC for
+ the message, but has been verified out of sequence; a
+ later token has already been received.
+
+ GSS_S_GAP_TOKEN The token was valid, and contained a correct MIC for
+ the message, but has been verified out of sequence;
+ an earlier expected token has not yet been received.
+
+ GSS_S_CONTEXT_EXPIRED The context has already expired
+
+ GSS_S_NO_CONTEXT The context_handle parameter did not identify a valid
+ context
+
+
+
+
+
+
+
+ 7.32. gss_verify_mic
+
+ OM_uint32 gss_verify_mic (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state)
+
+ Purpose:
+
+ Verifies that a cryptographic MIC, contained in the token parameter,
+ fits the supplied message. The qop_state parameter allows a message
+ recipient to determine the strength of protection that was applied to
+ the message.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ context_handle gss_ctx_id_t, read
+ Identifies the context on which the message
+ arrived
+
+ message_buffer buffer, opaque, read
+ Message to be verified
+
+ token_buffer buffer, opaque, read
+ Token associated with message
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 74]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+ qop_state gss_qop_t, modify, optional
+ quality of protection gained from MIC
+ Specify NULL if not required
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_DEFECTIVE_TOKEN The token failed consistency checks
+
+ GSS_S_BAD_SIG The MIC was incorrect
+
+ GSS_S_DUPLICATE_TOKEN The token was valid, and contained a correct MIC
+ for the message, but it had already been processed
+
+ GSS_S_OLD_TOKEN The token was valid, and contained a correct MIC for
+ the message, but it is too old to check for
+ duplication.
+
+ GSS_S_UNSEQ_TOKEN The token was valid, and contained a correct MIC for
+ the message, but has been verified out of sequence; a
+ later token has already been received.
+
+ GSS_S_GAP_TOKEN The token was valid, and contained a correct MIC for
+ the message, but has been verified out of sequence;
+ an earlier expected token has not yet been received.
+
+ GSS_S_CONTEXT_EXPIRED The context has already expired
+
+ GSS_S_NO_CONTEXT The context_handle parameter did not identify a valid
+ context
+
+
+
+
+
+
+
+ 7.33. gss_wrap
+
+ OM_uint32 gss_wrap (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req
+ const gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer )
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 75]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ Purpose:
+
+ Attaches a cryptographic MIC and optionally encrypts the specified
+ input_message. The output_message contains both the MIC and the
+ message. The qop_req parameter allows a choice between several
+ cryptographic algorithms, if supported by the chosen mechanism.
+
+ Since some application-level protocols may wish to use tokens emitted by
+ gss_wrap() to provide "secure framing", implementations should support
+ the wrapping of zero-length messages.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+
+ context_handle gss_ctx_id_t, read
+ Identifies the context on which the message
+ will be sent
+
+ conf_req_flag boolean, read
+ Non-zero - Both confidentiality and integrity
+ services are requested
+ Zero - Only integrity service is requested
+
+ qop_req gss_qop_t, read, optional
+ Specifies required quality of protection. A
+ mechanism-specific default may be requested by
+ setting qop_req to GSS_C_QOP_DEFAULT. If an
+ unsupported protection strength is requested,
+ gss_wrap will return a major_status of
+ GSS_S_BAD_QOP.
+
+ input_message_buffer buffer, opaque, read
+ Message to be protected
+
+ conf_state boolean, modify, optional
+ Non-zero - Confidentiality, data origin
+ authentication and integrity
+ services have been applied
+ Zero - Integrity and data origin services only
+ has been applied.
+ Specify NULL if not required
+
+ output_message_buffer buffer, opaque, modify
+ Buffer to receive protected message.
+ Storage associated with this message must
+ be freed by the application after use with
+ a call to gss_release_buffer().
+
+ Function value: GSS status code
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 76]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTEXT_EXPIRED The context has already expired
+
+ GSS_S_NO_CONTEXT The context_handle parameter did not identify a valid
+ context
+
+ GSS_S_BAD_QOP The specified QOP is not supported by the mechanism.
+
+
+
+
+
+
+
+ 7.34. gss_wrap_size_limit
+
+ OM_uint32 gss_wrap_size_limit (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 * max_input_size)
+
+ Purpose:
+
+ Allows an application to determine the maximum message size that, if
+ presented to gss_wrap with the same conf_req_flag and qop_req
+ parameters, will result in an output token containing no more than
+ req_output_size bytes.
+
+ This call is intended for use by applications that communicate over
+ protocols that impose a maximum message size. It enables the
+ application to fragment messages prior to applying protection.
+
+ Successful completion of this call does not guarantee that gss_wrap will
+ be able to protect a message of length max_input_size bytes, since this
+ ability may depend on the availability of system resources at the time
+ that gss_wrap is called. However, if the implementation itself imposes
+ an upper limit on the length of messages that may be processed by
+ gss_wrap, the implementation should not return a value via
+ max_input_bytes that is greater than this length.
+
+ Parameters:
+
+ minor_status Integer, modify
+ Mechanism specific status code
+
+ context_handle gss_ctx_id_t, read
+ A handle that refers to the security over
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 77]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ which the messages will be sent.
+
+ conf_req_flag Boolean, read
+ Indicates whether gss_wrap will be asked
+ to apply confidentiality protection in
+ addition to integrity protection. See
+ the routine description for gss_wrap
+ for more details.
+
+ qop_req gss_qop_t, read
+ Indicates the level of protection that
+ gss_wrap will be asked to provide. See
+ the routine description for gss_wrap for
+ more details.
+
+ req_output_size Integer, read
+ The desired maximum size for tokens emitted
+ by gss_wrap.
+
+ max_input_size Integer, modify
+ The maximum input message size that may
+ be presented to gss_wrap in order to
+ guarantee that the emitted token shall
+ be no larger than req_output_size bytes.
+
+ Function value: GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_NO_CONTEXT The referenced context could not be accessed.
+
+ GSS_S_CONTEXT_EXPIRED The context has expired.
+
+ GSS_S_BAD_QOP The specified QOP is not supported by the mechanism.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 78]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ APPENDIX A. GSS-API C header file gssapi.h
+
+ C-language GSS-API implementations should include a copy of the
+ following header-file.
+
+ #ifndef GSSAPI_H_
+ #define GSSAPI_H_
+
+
+
+ /*
+ * First, include stddef.h to get size_t defined.
+ */
+ #include <stddef.h>
+
+ /*
+ * If the platform supports the xom.h header file, it should be
+ * included here.
+ */
+ #include <xom.h>
+
+
+
+ /*
+ * Now define the three implementation-dependent types.
+ */
+ typedef <platform-specific> gss_ctx_id_t;
+ typedef <platform-specific> gss_cred_id_t;
+ typedef <platform-specific> gss_name_t;
+
+ /*
+ * The following type must be defined as the smallest natural
+ * unsigned integer supported by the platform that has at least
+ * 32 bits of precision.
+ */
+ typedef <platform-specific> gss_uint32;
+
+
+ #ifdef OM_STRING
+ /*
+ * We have included the xom.h header file. Verify that OM_uint32
+ * is defined correctly.
+ */
+
+ #if sizeof(gss_uint32) != sizeof(OM_uint32)
+ #error Incompatible definition of OM_uint32 from xom.h
+ #endif
+
+ typedef OM_object_identifier gss_OID_desc, *gss_OID;
+
+ #else
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 79]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ /*
+ * We can't use X/Open definitions, so roll our own.
+ */
+
+ typedef gss_uint32 OM_uint32;
+
+ typedef struct gss_OID_desc_struct {
+ OM_uint32 length;
+ void *elements;
+ } gss_OID_desc, *gss_OID;
+
+ #endif
+
+ typedef struct gss_OID_set_desc_struct {
+ size_t count;
+ gss_OID elements;
+ } gss_OID_set_desc, *gss_OID_set;
+
+ typedef struct gss_buffer_desc_struct {
+ size_t length;
+ void *value;
+ } gss_buffer_desc, *gss_buffer_t;
+
+ typedef struct gss_channel_bindings_struct {
+ OM_uint32 initiator_addrtype;
+ gss_buffer_desc initiator_address;
+ OM_uint32 acceptor_addrtype;
+ gss_buffer_desc acceptor_address;
+ gss_buffer_desc application_data;
+ } *gss_channel_bindings_t;
+
+
+ /*
+ * For now, define a QOP-type as an OM_uint32
+ */
+ typedef OM_uint32 gss_qop_t;
+
+ typedef int gss_cred_usage_t;
+
+ /*
+ * Flag bits for context-level services.
+ */
+ #define GSS_C_DELEG_FLAG 1
+ #define GSS_C_MUTUAL_FLAG 2
+ #define GSS_C_REPLAY_FLAG 4
+ #define GSS_C_SEQUENCE_FLAG 8
+ #define GSS_C_CONF_FLAG 16
+ #define GSS_C_INTEG_FLAG 32
+ #define GSS_C_ANON_FLAG 64
+ #define GSS_C_PROT_READY_FLAG 128
+ #define GSS_C_TRANS_FLAG 256
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 80]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ /*
+ * Credential usage options
+ */
+ #define GSS_C_BOTH 0
+ #define GSS_C_INITIATE 1
+ #define GSS_C_ACCEPT 2
+
+ /*
+ * Status code types for gss_display_status
+ */
+ #define GSS_C_GSS_CODE 1
+ #define GSS_C_MECH_CODE 2
+
+ /*
+ * The constant definitions for channel-bindings address families
+ */
+ #define GSS_C_AF_UNSPEC 0
+ #define GSS_C_AF_LOCAL 1
+ #define GSS_C_AF_INET 2
+ #define GSS_C_AF_IMPLINK 3
+ #define GSS_C_AF_PUP 4
+ #define GSS_C_AF_CHAOS 5
+ #define GSS_C_AF_NS 6
+ #define GSS_C_AF_NBS 7
+ #define GSS_C_AF_ECMA 8
+ #define GSS_C_AF_DATAKIT 9
+ #define GSS_C_AF_CCITT 10
+ #define GSS_C_AF_SNA 11
+ #define GSS_C_AF_DECnet 12
+ #define GSS_C_AF_DLI 13
+ #define GSS_C_AF_LAT 14
+ #define GSS_C_AF_HYLINK 15
+ #define GSS_C_AF_APPLETALK 16
+ #define GSS_C_AF_BSC 17
+ #define GSS_C_AF_DSS 18
+ #define GSS_C_AF_OSI 19
+ #define GSS_C_AF_X25 21
+
+ #define GSS_C_AF_NULLADDR 255
+
+ /*
+ * Various Null values
+ */
+ #define GSS_C_NO_NAME ((gss_name_t) 0)
+ #define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
+ #define GSS_C_NO_OID ((gss_OID) 0)
+ #define GSS_C_NO_OID_SET ((gss_OID_set) 0)
+ #define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
+ #define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
+ #define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
+ #define GSS_C_EMPTY_BUFFER {0, NULL}
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 81]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ /*
+ * Some alternate names for a couple of the above
+ * values. These are defined for V1 compatibility.
+ */
+ #define GSS_C_NULL_OID GSS_C_NO_OID
+ #define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET
+
+ /*
+ * Define the default Quality of Protection for per-message
+ * services. Note that an implementation that offers multiple
+ * levels of QOP may define GSS_C_QOP_DEFAULT to be either zero
+ * (as done here) to mean "default protection", or to a specific
+ * explicit QOP value. However, a value of 0 should always be
+ * interpreted by a GSSAPI implementation as a request for the
+ * default protection level.
+ */
+ #define GSS_C_QOP_DEFAULT 0
+
+ /*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+ #define GSS_C_INDEFINITE 0xfffffffful
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+ extern gss_OID GSS_C_NT_USER_NAME;
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+ extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
+
+ /*
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 82]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+ extern gss_OID GSS_C_NT_STRING_UID_NAME;
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 2(gss-host-based-services)}. The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized to point
+ * to that gss_OID_desc.
+ */
+ extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+ extern gss_OID GSS_C_NT_ANONYMOUS;
+
+
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+ extern gss_OID GSS_C_NT_EXPORT_NAME;
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 83]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ /* Major status codes */
+
+ #define GSS_S_COMPLETE 0
+
+ /*
+ * Some "helper" definitions to make the status code macros obvious.
+ */
+ #define GSS_C_CALLING_ERROR_OFFSET 24
+ #define GSS_C_ROUTINE_ERROR_OFFSET 16
+ #define GSS_C_SUPPLEMENTARY_OFFSET 0
+ #define GSS_C_CALLING_ERROR_MASK 0377ul
+ #define GSS_C_ROUTINE_ERROR_MASK 0377ul
+ #define GSS_C_SUPPLEMENTARY_MASK 0177777ul
+
+ /*
+ * The macros that test status codes for error conditions.
+ * Note that the GSS_ERROR() macro has changed slightly from
+ * the V1 GSSAPI so that it now evaluates its argument
+ * only once.
+ */
+ #define GSS_CALLING_ERROR(x) \
+ (x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+ #define GSS_ROUTINE_ERROR(x) \
+ (x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+ #define GSS_SUPPLEMENTARY_INFO(x) \
+ (x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+ #define GSS_ERROR(x) \
+ (x & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
+ (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
+
+
+ /*
+ * Now the actual status code definitions
+ */
+
+ /*
+ * Calling errors:
+ */
+ #define GSS_S_CALL_INACCESSIBLE_READ \
+ (1ul << GSS_C_CALLING_ERROR_OFFSET)
+ #define GSS_S_CALL_INACCESSIBLE_WRITE \
+ (2ul << GSS_C_CALLING_ERROR_OFFSET)
+ #define GSS_S_CALL_BAD_STRUCTURE \
+ (3ul << GSS_C_CALLING_ERROR_OFFSET)
+
+ /*
+ * Routine errors:
+ */
+ #define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET)
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 84]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ #define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_MIC GSS_S_BAD_SIG
+ #define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_QOP (14ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_UNAUTHORIZED (15ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_UNAVAILABLE (16ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_DUPLICATE_ELEMENT (17ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_NAME_NOT_MN (18ul << GSS_C_ROUTINE_ERROR_OFFSET)
+
+ /*
+ * Supplementary info bits:
+ */
+ #define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
+ #define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
+ #define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
+ #define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
+ #define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
+
+
+ /*
+ * Finally, function prototypes for the GSS-API routines.
+ */
+
+ OM_uint32 gss_acquire_cred
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ const gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 * /* time_rec */
+ );
+
+ OM_uint32 gss_release_cred
+ (OM_uint32 *, /* minor_status */
+ gss_cred_id_t * /* cred_handle */
+ );
+
+ OM_uint32 gss_init_sec_context
+ (OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* initiator_cred_handle */
+ gss_ctx_id_t *, /* context_handle */
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 85]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ const gss_name_t, /* target_name */
+ const gss_OID, /* mech_type */
+ OM_uint32, /* req_flags */
+ OM_uint32, /* time_req */
+ const gss_channel_bindings_t,
+ /* input_chan_bindings */
+ const gss_buffer_t, /* input_token */
+ gss_OID *, /* actual_mech_type */
+ gss_buffer_t, /* output_token */
+ OM_uint32 *, /* ret_flags */
+ OM_uint32 * /* time_rec */
+ );
+
+ OM_uint32 gss_accept_sec_context
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ const gss_cred_id_t, /* acceptor_cred_handle */
+ const gss_buffer_t, /* input_token_buffer */
+ const gss_channel_bindings_t,
+ /* input_chan_bindings */
+ gss_name_t *, /* src_name */
+ gss_OID *, /* mech_type */
+ gss_buffer_t, /* output_token */
+ OM_uint32 *, /* ret_flags */
+ OM_uint32 *, /* time_rec */
+ gss_cred_id_t * /* delegated_cred_handle */
+ );
+
+ OM_uint32 gss_process_context_token
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t /* token_buffer */
+ );
+
+ OM_uint32 gss_delete_sec_context
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ gss_buffer_t /* output_token */
+ );
+
+ OM_uint32 gss_context_time
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ OM_uint32 * /* time_rec */
+ );
+
+ OM_uint32 gss_get_mic
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ gss_qop_t, /* qop_req */
+ const gss_buffer_t, /* message_buffer */
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 86]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ gss_buffer_t /* message_token */
+ );
+
+
+ OM_uint32 gss_verify_mic
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t, /* message_buffer */
+ const gss_buffer_t, /* token_buffer */
+ gss_qop_t * /* qop_state */
+ );
+
+ OM_uint32 gss_wrap
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ const gss_buffer_t, /* input_message_buffer */
+ int *, /* conf_state */
+ gss_buffer_t /* output_message_buffer */
+ );
+
+
+ OM_uint32 gss_unwrap
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t, /* input_message_buffer */
+ gss_buffer_t, /* output_message_buffer */
+ int *, /* conf_state */
+ gss_qop_t * /* qop_state */
+ );
+
+
+
+ OM_uint32 gss_display_status
+ (OM_uint32 *, /* minor_status */
+ OM_uint32, /* status_value */
+ int, /* status_type */
+ const gss_OID, /* mech_type */
+ OM_uint32 *, /* message_context */
+ gss_buffer_t /* status_string */
+ );
+
+ OM_uint32 gss_indicate_mechs
+ (OM_uint32 *, /* minor_status */
+ gss_OID_set * /* mech_set */
+ );
+
+ OM_uint32 gss_compare_name
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* name1 */
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 87]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ const gss_name_t, /* name2 */
+ int * /* name_equal */
+ );
+
+ OM_uint32 gss_display_name
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_buffer_t, /* output_name_buffer */
+ gss_OID * /* output_name_type */
+ );
+
+ OM_uint32 gss_import_name
+ (OM_uint32 *, /* minor_status */
+ const gss_buffer_t, /* input_name_buffer */
+ const gss_OID, /* input_name_type */
+ gss_name_t * /* output_name */
+ );
+
+ OM_uint32 gss_export_name
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_buffer_t /* exported_name */
+ );
+
+ OM_uint32 gss_release_name
+ (OM_uint32 *, /* minor_status */
+ gss_name_t * /* input_name */
+ );
+
+ OM_uint32 gss_release_buffer
+ (OM_uint32 *, /* minor_status */
+ gss_buffer_t /* buffer */
+ );
+
+ OM_uint32 gss_release_oid_set
+ (OM_uint32 *, /* minor_status */
+ gss_OID_set * /* set */
+ );
+
+ OM_uint32 gss_inquire_cred
+ (OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* cred_handle */
+ gss_name_t *, /* name */
+ OM_uint32 *, /* lifetime */
+ gss_cred_usage_t *, /* cred_usage */
+ gss_OID_set * /* mechanisms */
+ );
+
+ OM_uint32 gss_inquire_context (
+ OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 88]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ gss_name_t *, /* src_name */
+ gss_name_t *, /* targ_name */
+ OM_uint32 *, /* lifetime_rec */
+ gss_OID *, /* mech_type */
+ OM_uint32 *, /* ctx_flags */
+ int *, /* locally_initiated */
+ int * /* open */
+ );
+
+ OM_uint32 gss_wrap_size_limit (
+ OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ OM_uint32, /* req_output_size */
+ OM_uint32 * /* max_input_size */
+ );
+
+
+ OM_uint32 gss_add_cred (
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* input_cred_handle */
+ const gss_name_t, /* desired_name */
+ const gss_OID, /* desired_mech */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *, /* initiator_time_rec */
+ OM_uint32 * /* acceptor_time_rec */
+ );
+
+
+ OM_uint32 gss_inquire_cred_by_mech (
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* cred_handle */
+ const gss_OID, /* mech_type */
+ gss_name_t *, /* name */
+ OM_uint32 *, /* initiator_lifetime */
+ OM_uint32 *, /* acceptor_lifetime */
+ gss_cred_usage_t * /* cred_usage */
+ );
+
+ OM_uint32 gss_export_sec_context (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ gss_buffer_t /* interprocess_token */
+ );
+
+ OM_uint32 gss_import_sec_context (
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 89]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ OM_uint32 *, /* minor_status */
+ const gss_buffer_t, /* interprocess_token */
+ gss_ctx_id_t * /* context_handle */
+ );
+
+ OM_uint32 gss_create_empty_oid_set (
+ OM_uint32 *, /* minor_status */
+ gss_OID_set * /* oid_set */
+ );
+
+ OM_uint32 gss_add_oid_set_member (
+ OM_uint32 *, /* minor_status */
+ const gss_OID, /* member_oid */
+ gss_OID_set * /* oid_set */
+ );
+
+ OM_uint32 gss_test_oid_set_member (
+ OM_uint32 *, /* minor_status */
+ const gss_OID, /* member */
+ const gss_OID_set, /* set */
+ int * /* present */
+ );
+
+ OM_uint32 gss_inquire_names_for_mech (
+ OM_uint32 *, /* minor_status */
+ const gss_OID, /* mechanism */
+ gss_OID_set * /* name_types */
+ );
+
+ OM_uint32 gss_inquire_mechs_for_name (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_OID_set * /* mech_types */
+ );
+
+ OM_uint32 gss_canonicalize_name (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ const gss_OID, /* mech_type */
+ gss_name_t * /* output_name */
+ );
+
+ OM_uint32 gss_duplicate_name (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* src_name */
+ gss_name_t * /* dest_name */
+ );
+
+ /*
+ * The following routines are obsolete variants of gss_get_mic,
+ * gss_verify_mic, gss_wrap and gss_unwrap. They should be
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 90]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ * provided by GSSAPI V2 implementations for backwards
+ * compatibility with V1 applications. Distinct entrypoints
+ * (as opposed to #defines) should be provided, both to allow
+ * GSSAPI V1 applications to link against GSSAPI V2 implementations,
+ * and to retain the slight parameter type differences between the
+ * obsolete versions of these routines and their current forms.
+ */
+
+ OM_uint32 gss_sign
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* qop_req */
+ gss_buffer_t, /* message_buffer */
+ gss_buffer_t /* message_token */
+ );
+
+
+ OM_uint32 gss_verify
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t, /* message_buffer */
+ gss_buffer_t, /* token_buffer */
+ int * /* qop_state */
+ );
+
+ OM_uint32 gss_seal
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ int, /* qop_req */
+ gss_buffer_t, /* input_message_buffer */
+ int *, /* conf_state */
+ gss_buffer_t /* output_message_buffer */
+ );
+
+
+ OM_uint32 gss_unseal
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t, /* input_message_buffer */
+ gss_buffer_t, /* output_message_buffer */
+ int *, /* conf_state */
+ int * /* qop_state */
+ );
+
+
+
+
+ #endif /* GSSAPI_H_ */
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 91]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ APPENDIX B. Additional constraints for application binary portability
+
+ The purpose of this C-bindings document is to encourage source-level
+ portability of applications across GSS-API implementations on different
+ platforms and atop different mechanisms. Additional goals that have not
+ been explicitly addressed by this document are link-time and run-time
+ portability.
+
+ Link-time portability provides the ability to compile an application
+ against one implementation of GSS-API, and then link it against a
+ different implementation on the same platform. It is a stricter
+ requirement than source-level portability.
+
+ Run-time portability differs from link-time portability only on those
+ platforms that implement dynamically loadable GSS-API implementations,
+ but do not offer load-time symbol resolution. On such platforms, run-
+ time portability is a stricter requirement than link-time portability,
+ and will typically include the precise placement of the various GSS-API
+ routines within library entrypoint vectors.
+
+ Individual platforms will impose their own rules that must be followed
+ to achieve link-time (and run-time, if different) portability. In order
+ to ensure either form of binary portability, an ABI specification must
+ be written for GSS-API implementations on that platform. However, it is
+ recognized that there are some issues that are likely to be common to
+ all such ABI specifications. This appendix is intended to be a
+ repository for such common issues, and contains some suggestions that
+ individual ABI specifications may choose to reference. Since machine
+ architectures vary greatly, it may not be possible or desirable to
+ follow these suggestions on all platforms.
+
+ B.1. Pointers
+
+ While ANSI-C provides a single pointer type for each declared type, plus
+ a single (void *) type, some platforms (notably those using segmented
+ memory architectures) augment this with various modified pointer types
+ (e.g. far pointers, near pointers). These language bindings assume
+ ANSI-C, and thus do not address such non-standard implementations.
+ GSS-API implementations for such platforms must choose an appropriate
+ memory model, and should use it consistently throughout. For example,
+ if a memory model is chosen that requires the use of far pointers when
+ passing routine parameters, then far pointers should also be used within
+ the structures defined by GSS-API.
+
+ B.2. Internal structure alignment
+
+ GSS-API defines several data-structures containing differently-sized
+ fields. An ABI specification should include a detailed description of
+ how the fields of such structures are aligned, and if there is any
+ internal padding in these data structures. The use of compiler defaults
+ for the platform is recommended.
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 92]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ B.3. Handle types
+
+ The C bindings specify that the gss_cred_id_t and gss_ctx_id_t types
+ should be implemented as either pointer or arithmetic types, and that if
+ pointer types are used, care should be taken to ensure that two handles
+ may be compared with the == operator. Note that ANSI-C does not
+ guarantee that two pointer values may be compared with the == operator
+ unless either the two pointers point to members of a single array, or at
+ least one of the pointers contains a NULL value.
+
+ For binary portability, additional constraints are required. The
+ following is an attempt at defining platform-independent constraints.
+
+ (a) The size of the handle type must be the same as sizeof(void *),
+ using the appropriate memory model.
+
+ (b) The == operator for the chosen type must be a simple bit-wise
+ comparison. That is, for two in-memory handle objects h1 and h2,
+ the boolean value of the expression
+
+ (h1 == h2)
+
+ should always be the same as the boolean value of the expression
+
+ (memcmp(&h1, &h2, sizeof(h1)) == 0)
+
+ (c) The actual use of the type (void *) for handle types is
+ discouraged, not for binary portability reasons, but since it
+ effectively disables much of the compile-time type-checking that
+ the compiler can otherwise perform, and is therefore not
+ "programmer-friendly". If a pointer implementation is desired,
+ and if the platform's implementation of pointers permits, the
+ handles should be implemented as pointers to distinct
+ implementation-defined types.
+
+ B.4. The gss_name_t type
+
+ The gss_name_t type, representing the internal name object, should be
+ implemented as a pointer type. The use of the (void *) type is
+ discouraged as it does not allow the compiler to perform strong type-
+ checking. However, the pointer type chosen should be of the same size
+ as the (void *) type. Provided this rule is obeyed, ABI specifications
+ need not further constrain the implementation of gss_name_t objects.
+
+ B.5. The int and size_t types
+
+ Some platforms may support differently sized implementations of the
+ "int" and "size_t" types, perhaps chosen through compiler switches, and
+ perhaps dependent on memory model. An ABI specification for such a
+ platform should include required implementations for these types. It is
+ recommended that the default implementation (for the chosen memory
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 93]
+
+
+
+
+
+
+
+ INTERNET-DRAFT GSS-API V2 - C bindings March 1997
+
+
+
+ model, if appropriate) is chosen.
+
+ B.6. Procedure-calling conventions
+
+ Some platforms support a variety of different binary conventions for
+ calling procedures. Such conventions cover things like the format of
+ the stack frame, the order in which the routine parameters are pushed
+ onto the stack, whether or not a parameter count is pushed onto the
+ stack, whether some argument(s) or return values are to be passed in
+ registers, and whether the called routine or the caller is responsible
+ for removing the stack frame on return. For such platforms, an ABI
+ specification should specify which calling convention is to be used for
+ GSSAPI implementations.
+
+
+ REFERENCES
+
+ [GSSAPI] J. Linn, "Generic Security Service Application Program
+ Interface, Version 2", Internet-Draft draft-ietf-cat-gssv2-
+ 08, 26 August 1996. (This Internet-Draft, like all other
+ Internet-Drafts, is not an archival document and is subject
+ to change or deletion. It is available at the time of this
+ writing by anonymous ftp from ds.internic.net, directory
+ internet-drafts. Would-be readers should check for successor
+ Internet-Draft versions or Internet RFCs before relying on
+ this document.)
+
+ [XOM] OSI Object Management API Specification, Version 2.0 t",
+ X.400 API Association & X/Open Company Limited, August 24,
+ 1990. Specification of datatypes and routines for
+ manipulating information objects.
+
+
+ AUTHOR'S ADDRESS
+
+ John Wray Internet email: Wray@tuxedo.enet.dec.com
+ Digital Equipment Corporation Telephone: +1-508-486-5210
+ 550 King Street, LKG2-2/Z7
+ Littleton, MA 01460
+ USA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Wray Document Expiration: 1 September 1997 [Page 94]
+
+
+
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-chg-password-02.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-chg-password-02.txt
new file mode 100644
index 000000000000..e235bec58c02
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-chg-password-02.txt
@@ -0,0 +1,311 @@
+
+
+
+
+Network Working Group M. Horowitz
+<draft-ietf-cat-kerb-chg-password-02.txt> Stonecast, Inc.
+Internet-Draft August, 1998
+
+ Kerberos Change Password Protocol
+
+Status of this Memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its areas,
+ and its working groups. Note that other groups may also distribute
+ working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as ``work in progress.''
+
+ To learn the current status of any Internet-Draft, please check the
+ ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
+ Directories on ftp.ietf.org (US East Coast), nic.nordu.net
+ (Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific
+ Rim).
+
+ Distribution of this memo is unlimited. Please send comments to the
+ <cat-ietf@mit.edu> mailing list.
+
+Abstract
+
+ The Kerberos V5 protocol [RFC1510] does not describe any mechanism
+ for users to change their own passwords. In order to promote
+ interoperability between workstations, personal computers, terminal
+ servers, routers, and KDC's from multiple vendors, a common password
+ changing protocol is required.
+
+
+
+Overview
+
+ When a user wishes to change his own password, or is required to by
+ local policy, a simple request of a password changing service is
+ necessary. This service must be implemented on at least one host for
+ each Kerberos realm, probably on one of the kdc's for that realm.
+ The service must accept requests on UDP port 464 (kpasswd), and may
+ accept requests on TCP port 464 as well.
+
+ The protocol itself consists of a single request message followed by
+ a single reply message. For UDP transport, each message must be
+ fully contained in a single UDP packet.
+
+
+
+
+
+
+
+
+Horowitz [Page 1]
+
+Internet Draft Kerberos Change Password Protocol August, 1998
+
+
+Request Message
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | message length | protocol version number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | AP_REQ length | AP-REQ data /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / KRB-PRIV message /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ message length (16 bits)
+ Contains the length of the message, including this field, in bytes
+ (big-endian integer)
+ protocol version number (16 bits)
+ Contains the hex constant 0x0001 (big-endian integer)
+ AP-REQ length (16 bits)
+ length (big-endian integer) of AP-REQ data, in bytes.
+ AP-REQ data, as described in RFC1510 (variable length)
+ This AP-REQ must be for the service principal
+ kadmin/changepw@REALM, where REALM is the REALM of the user who
+ wishes to change his password. The Ticket in the AP-REQ must be
+ derived from an AS request (thus having the INITIAL flag set), and
+ must include a subkey in the Authenticator.
+ KRB-PRIV message, as described in RFC1510 (variable length)
+ This KRB-PRIV message must be generated using the subkey in the
+ Authenticator in the AP-REQ data. The user-data component of the
+ message must consist of the user's new password.
+
+ The server must verify the AP-REQ message, decrypt the new password,
+ perform any local policy checks (such as password quality, history,
+ authorization, etc.) required, then set the password to the new value
+ specified.
+
+ The principal whose password is to be changed is the principal which
+ authenticated to the password changing service. This protocol does
+ not address administrators who want to change passwords of principal
+ besides their own.
+
+
+Reply Message
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | message length | protocol version number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | AP_REP length | AP-REP data /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / KRB-PRIV or KRB-ERROR message /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ message length (16 bits)
+
+
+
+Horowitz [Page 2]
+
+Internet Draft Kerberos Change Password Protocol August, 1998
+
+
+ Contains the length of the message, including this field, in bytes
+ (big-endian integer),
+ protocol version number (16 bits)
+ Contains the hex constant 0x0001 (big-endian integer)
+ AP-REP length (16 bits)
+ length of AP-REP data, in bytes. If the the length is zero, then
+ the last field will contain a KRB-ERROR message instead of a KRB-
+ PRIV message.
+ AP-REP data, as described in RFC1510 (variable length)
+ The AP-REP corresponding to the AP-REQ in the request packet.
+ KRB-PRIV or KRB-ERROR message, as described in RFC1510 (variable
+ length)
+ If the AP-REP length is zero, then this field contains a KRB-ERROR
+ message. Otherwise, it contains a KRB-PRIV message. This KRB-
+ PRIV message must be generated using the subkey in the
+ Authenticator in the AP-REQ data.
+
+ The user-data component of the KRB-PRIV message, or e-data
+ component of the KRB-ERROR message, must consist of the following
+ data:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | result code | result string /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ result code (16 bits)
+ The result code must have one of the following values (big-
+ endian integer):
+ 0x0000 if the request succeeds. (This value is not permitted
+ in a KRB-ERROR message.)
+ 0x0001 if the request fails due to being malformed
+ 0x0002 if the request fails due to a "hard" error processing
+ the request (for example, there is a resource or other
+ problem causing the request to fail)
+ 0x0003 if the request fails due to an error in authentication
+ processing
+ 0x0004 if the request fails due to a "soft" error processing
+ the request (for example, some policy or other similar
+ consideration is causing the request to be rejected).
+ 0xFFFF if the request fails for some other reason.
+ Although only a few non-zero result codes are specified here,
+ the client should accept any non-zero result code as indicating
+ failure.
+ result string (variable length)
+ This field should contain information which the server thinks
+ might be useful to the user, such as feedback about policy
+ failures. The string must be encoded in UTF-8. It may be
+ omitted if the server does not wish to include it. If it is
+ present, the client should display the string to the user.
+ This field is analogous to the string which follows the numeric
+ code in SMTP, FTP, and similar protocols.
+
+
+
+
+Horowitz [Page 3]
+
+Internet Draft Kerberos Change Password Protocol August, 1998
+
+
+Dropped and Modified Messages
+
+ An attacker (or simply a lossy network) could cause either the
+ request or reply to be dropped, or modified by substituting a KRB-
+ ERROR message in the reply.
+
+ If a request is dropped, no modification of the password/key database
+ will take place. If a reply is dropped, the server will (assuming a
+ valid request) make the password change. However, the client cannot
+ distinguish between these two cases.
+
+ In this situation, the client should construct a new authenticator,
+ re-encrypt the request, and retransmit. If the original request was
+ lost, the server will treat this as a valid request, and the password
+ will be changed normally. If the reply was lost, then the server
+ should take care to notice that the request was a duplicate of the
+ prior request, because the "new" password is the current password,
+ and the password change time is within some implementation-defined
+ replay time window. The server should then return a success reply
+ (an AP-REP message with result code == 0x0000) without actually
+ changing the password or any other information (such as modification
+ timestamps).
+
+ If a success reply was replaced with an error reply, then the
+ application performing the request would return an error to the user.
+ In this state, the user's password has been changed, but the user
+ believes that it has not. If the user attempts to change the
+ password again, this will probably fail, because the user cannot
+ successfully provide the old password to get an INITIAL ticket to
+ make the request. This situation requires administrative
+ intervention as if a password was lost. This situation is,
+ unfortunately, impossible to prevent.
+
+
+Security Considerations
+
+ This document deals with changing passwords for Kerberos. Because
+ Kerberos is used for authentication and key distribution, it is
+ important that this protocol use the highest level of security
+ services available to a particular installation. Mutual
+ authentication is performed, so that the server knows the request is
+ valid, and the client knows that the request has been received and
+ processed by the server.
+
+ There are also security issues relating to dropped or modified
+ messages which are addressed explicitly.
+
+
+References
+
+ [RFC1510] Kohl, J. and Neuman, C., "The Kerberos Network
+ Authentication Service (V5)", RFC 1510, September 1993.
+
+
+
+
+
+Horowitz [Page 4]
+
+Internet Draft Kerberos Change Password Protocol August, 1998
+
+
+Author's Address
+
+ Marc Horowitz
+ Stonecast, Inc.
+ 108 Stow Road
+ Harvard, MA 01451
+
+ Phone: +1 978 456 9103
+ Email: marc@stonecast.net
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Horowitz [Page 5]
+
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-des3-hmac-sha1-00.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-des3-hmac-sha1-00.txt
new file mode 100644
index 000000000000..2583a84da0a4
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-des3-hmac-sha1-00.txt
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+Network Working Group M. Horowitz
+<draft-ietf-cat-kerb-des3-hmac-sha1-00.txt> Cygnus Solutions
+Internet-Draft November, 1996
+
+
+ Triple DES with HMAC-SHA1 Kerberos Encryption Type
+
+Status of this Memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its areas,
+ and its working groups. Note that other groups may also distribute
+ working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as ``work in progress.''
+
+ To learn the current status of any Internet-Draft, please check the
+ ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
+ Directories on ds.internic.net (US East Coast), nic.nordu.net
+ (Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific
+ Rim).
+
+ Distribution of this memo is unlimited. Please send comments to the
+ <cat-ietf@mit.edu> mailing list.
+
+Abstract
+
+ This document defines a new encryption type and a new checksum type
+ for use with Kerberos V5 [RFC1510]. This encryption type is based on
+ the Triple DES cryptosystem and the HMAC-SHA1 [Krawczyk96] message
+ authentication algorithm.
+
+ The des3-cbc-hmac-sha1 encryption type has been assigned the value 7.
+ The hmac-sha1-des3 checksum type has been assigned the value 12.
+
+
+Encryption Type des3-cbc-hmac-sha1
+
+ EncryptedData using this type must be generated as described in
+ [Horowitz96]. The encryption algorithm is Triple DES in Outer-CBC
+ mode. The keyed hash algorithm is HMAC-SHA1. Unless otherwise
+ specified, a zero IV must be used. If the length of the input data
+ is not a multiple of the block size, zero octets must be used to pad
+ the plaintext to the next eight-octet boundary. The counfounder must
+ be eight random octets (one block).
+
+
+Checksum Type hmac-sha1-des3
+
+ Checksums using this type must be generated as described in
+ [Horowitz96]. The keyed hash algorithm is HMAC-SHA1.
+
+
+
+Horowitz [Page 1]
+
+Internet Draft Kerberos Triple DES with HMAC-SHA1 November, 1996
+
+
+Common Requirements
+
+ Where the Triple DES key is represented as an EncryptionKey, it shall
+ be represented as three DES keys, with parity bits, concatenated
+ together. The key shall be represented with the most significant bit
+ first.
+
+ When keys are generated by the derivation function, a key length of
+ 168 bits shall be used. The output bit string will be converted to a
+ valid Triple DES key by inserting DES parity bits after every seventh
+ bit.
+
+ Any implementation which implements either of the encryption or
+ checksum types in this document must support both.
+
+
+Security Considerations
+
+ This entire document defines encryption and checksum types for use
+ with Kerberos V5.
+
+
+References
+
+ [Horowitz96] Horowitz, M., "Key Derivation for Kerberos V5", draft-
+ horowitz-kerb-key-derivation-00.txt, November 1996.
+ [Krawczyk96] Krawczyk, H., Bellare, and M., Canetti, R., "HMAC:
+ Keyed-Hashing for Message Authentication", draft-ietf-ipsec-hmac-
+ md5-01.txt, August, 1996.
+ [RFC1510] Kohl, J. and Neuman, C., "The Kerberos Network
+ Authentication Service (V5)", RFC 1510, September 1993.
+
+
+Author's Address
+
+ Marc Horowitz
+ Cygnus Solutions
+ 955 Massachusetts Avenue
+ Cambridge, MA 02139
+
+ Phone: +1 617 354 7688
+ Email: marc@cygnus.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Horowitz [Page 2]
+
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-key-derivation-00.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-key-derivation-00.txt
new file mode 100644
index 000000000000..46a415852706
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerb-key-derivation-00.txt
@@ -0,0 +1,250 @@
+
+
+
+
+
+Network Working Group M. Horowitz
+<draft-ietf-cat-kerb-key-derivation-00.txt> Cygnus Solutions
+Internet-Draft November, 1996
+
+
+ Key Derivation for Kerberos V5
+
+Status of this Memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its areas,
+ and its working groups. Note that other groups may also distribute
+ working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as ``work in progress.''
+
+ To learn the current status of any Internet-Draft, please check the
+ ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
+ Directories on ds.internic.net (US East Coast), nic.nordu.net
+ (Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific
+ Rim).
+
+ Distribution of this memo is unlimited. Please send comments to the
+ <cat-ietf@mit.edu> mailing list.
+
+Abstract
+
+ In the Kerberos protocol [RFC1510], cryptographic keys are used in a
+ number of places. In order to minimize the effect of compromising a
+ key, it is desirable to use a different key for each of these places.
+ Key derivation [Horowitz96] can be used to construct different keys
+ for each operation from the keys transported on the network. For
+ this to be possible, a small change to the specification is
+ necessary.
+
+
+Overview
+
+ Under RFC1510 as stated, key derivation could be specified as a set
+ of encryption types which share the same key type. The constant for
+ each derivation would be a function of the encryption type. However,
+ it is generally accepted that, for interoperability, key types and
+ encryption types must map one-to-one onto each other. (RFC 1510 is
+ being revised to address this issue.) Therefore, to use key
+ derivcation with Kerberos V5 requires a small change to the
+ specification.
+
+ For each place where a key is used in Kerberos, a ``key usage'' must
+ be specified for that purpose. The key, key usage, and
+ encryption/checksum type together describe the transformation from
+ plaintext to ciphertext, or plaintext to checksum. For backward
+
+
+
+Horowitz [Page 1]
+
+Internet Draft Key Derivation for Kerberos V5 November, 1996
+
+
+ compatibility, old encryption types would be defined independently of
+ the key usage.
+
+
+Key Usage Values
+
+ This is a complete list of places keys are used in the kerberos
+ protocol, with key usage values and RFC 1510 section numbers:
+
+ 1. AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
+ client key (section 5.4.1)
+ 2. AS-REP Ticket and TGS-REP Ticket (includes tgs session key or
+ application session key), encrypted with the service key
+ (section 5.4.2)
+ 3. AS-REP encrypted part (includes tgs session key or application
+ session key), encrypted with the client key (section 5.4.2)
+
+ 4. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ session key (section 5.4.1)
+ 5. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ authenticator subkey (section 5.4.1)
+ 6. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
+ with the tgs session key (sections 5.3.2, 5.4.1)
+ 7. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes tgs
+ authenticator subkey), encrypted with the tgs session key
+ (section 5.3.2)
+ 8. TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs session key (section 5.4.2)
+ 9. TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs authenticator subkey (section 5.4.2)
+
+ 10. AP-REQ Authenticator cksum, keyed with the application session
+ key (section 5.3.2)
+ 11. AP-REQ Authenticator (includes application authenticator
+ subkey), encrypted with the application session key (section
+ 5.3.2)
+ 12. AP-REP encrypted part (includes application session subkey),
+ encrypted with the application session key (section 5.5.2)
+
+ 13. KRB-PRIV encrypted part, encrypted with a key chosen by the
+ application (section 5.7.1)
+ 14. KRB-CRED encrypted part, encrypted with a key chosen by the
+ application (section 5.6.1)
+ 15. KRB-SAVE cksum, keyed with a key chosen by the application
+ (section 5.8.1)
+
+ 16. Data which is defined in some specification outside of
+ Kerberos to be encrypted using an RFC1510 encryption type.
+ 17. Data which is defined in some specification outside of
+ Kerberos to be checksummed using an RFC1510 checksum type.
+
+ A few of these key usages need a little clarification. A service
+ which receives an AP-REQ has no way to know if the enclosed Ticket
+ was part of an AS-REP or TGS-REP. Therefore, key usage 2 must always
+
+
+
+Horowitz [Page 2]
+
+Internet Draft Key Derivation for Kerberos V5 November, 1996
+
+
+ be used for generating a Ticket, whether it is in response to an AS-
+ REQ or TGS-REQ.
+
+ There might exist other documents which define protocols in terms of
+ the RFC1510 encryption types or checksum types. Such documents would
+ not know about key usages. In order that these documents continue to
+ be meaningful until they are updated, key usages 16 and 17 must be
+ used to derive keys for encryption and checksums, respectively. New
+ protocols defined in terms of the Kerberos encryption and checksum
+ types should use their own key usages. Key usages may be registered
+ with IANA to avoid conflicts. Key usages shall be unsigned 32 bit
+ integers. Zero is not permitted.
+
+
+Defining Cryptosystems Using Key Derivation
+
+ Kerberos requires that the ciphertext component of EncryptedData be
+ tamper-resistant as well as confidential. This implies encryption
+ and integrity functions, which must each use their own separate keys.
+ So, for each key usage, two keys must be generated, one for
+ encryption (Ke), and one for integrity (Ki):
+
+ Ke = DK(protocol key, key usage | 0xAA)
+ Ki = DK(protocol key, key usage | 0x55)
+
+ where the key usage is represented as a 32 bit integer in network
+ byte order. The ciphertest must be generated from the plaintext as
+ follows:
+
+ ciphertext = E(Ke, confounder | length | plaintext | padding) |
+ H(Ki, confounder | length | plaintext | padding)
+
+ The confounder and padding are specific to the encryption algorithm
+ E.
+
+ When generating a checksum only, there is no need for a confounder or
+ padding. Again, a new key (Kc) must be used. Checksums must be
+ generated from the plaintext as follows:
+
+ Kc = DK(protocol key, key usage | 0x99)
+
+ MAC = H(Kc, length | plaintext)
+
+ Note that each enctype is described by an encryption algorithm E and
+ a keyed hash algorithm H, and each checksum type is described by a
+ keyed hash algorithm H. HMAC, with an appropriate hash, is
+ recommended for use as H.
+
+
+Security Considerations
+
+ This entire document addresses shortcomings in the use of
+ cryptographic keys in Kerberos V5.
+
+
+
+
+Horowitz [Page 3]
+
+Internet Draft Key Derivation for Kerberos V5 November, 1996
+
+
+Acknowledgements
+
+ I would like to thank Uri Blumenthal, Sam Hartman, and Bill
+ Sommerfeld for their contributions to this document.
+
+
+References
+
+ [Horowitz96] Horowitz, M., "Key Derivation for Authentication,
+ Integrity, and Privacy", draft-horowitz-key-derivation-00.txt,
+ November 1996. [RFC1510] Kohl, J. and Neuman, C., "The Kerberos
+ Network Authentication Service (V5)", RFC 1510, September 1993.
+
+
+Author's Address
+
+ Marc Horowitz
+ Cygnus Solutions
+ 955 Massachusetts Avenue
+ Cambridge, MA 02139
+
+ Phone: +1 617 354 7688
+ Email: marc@cygnus.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Horowitz [Page 4]
+
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-err-msg-00.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-err-msg-00.txt
new file mode 100644
index 000000000000..c5e4d05e7e3e
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-err-msg-00.txt
@@ -0,0 +1,252 @@
+
+INTERNET-DRAFT Ari Medvinsky
+draft-ietf-cat-kerberos-err-msg-00.txt Matt Hur
+Updates: RFC 1510 Dominique Brezinski
+expires September 30, 1997 CyberSafe Corporation
+ Gene Tsudik
+ Brian Tung
+ ISI
+
+Integrity Protection for the Kerberos Error Message
+
+0. Status Of this Memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six
+ months and may be updated, replaced, or obsoleted by other
+ documents at any time. It is inappropriate to use Internet-Drafts
+ as reference material or to cite them other than as "work in
+ progress."
+
+ To learn the current status of any Internet-Draft, please check
+ the "1id-abstracts.txt" listing contained in the Internet-Drafts
+ Shadow Directories on ds.internic.net (US East Coast),
+ nic.nordu.net (Europe), ftp.isi.edu (US West Coast), or
+ munnari.oz.au (Pacific Rim).
+
+ The distribution of this memo is unlimited. It is filed as
+ draft-ietf-cat-kerberos-pk-init-03.txt, and expires June xx, 1997.
+ Please send comments to the authors.
+
+1. Abstract
+
+ The Kerberos error message, as defined in RFC 1510, is transmitted
+ to the client without any integrity assurance. Therefore, the
+ client has no means to distinguish between a valid error message
+ sent from the KDC and one sent by an attacker. This draft describes
+ a method for assuring the integrity of Kerberos error messages, and
+ proposes a consistent format for the e-data field in the KRB_ERROR
+ message. This e-data format enables the storage of cryptographic
+ checksums by providing an extensible mechanism for specifying e-data
+ types.
+
+
+2. Motivation
+
+ In the Kerberos protocol [1], if an error occurs for AS_REQ,
+ TGS_REQ, or AP_REQ, a clear text error message is returned to the
+ client. An attacker may exploit this vulnerability by sending a
+ false error message as a reply to any of the above requests. For
+ example, an attacker may send the KDC_ERR_KEY_EXPIRED error message
+ in order to force a user to change their password in hope that the
+ new key will not be as strong as the current key, and thus, easier
+ to break.
+
+ Since false error messages may be utilized by an attacker, a
+ Kerberos client should have a means for determining how much trust
+ to place in a given error message. The rest of this draft
+ describes a method for assuring the integrity of Kerberos error
+ messages.
+
+
+3. Approach
+
+ We propose taking a cryptographic checksum over the entire KRB-ERROR
+ message. This checksum would be returned as part of the error
+ message and would enable the client to verify the integrity of the
+ error message. For interoperability reasons, no new fields are
+ added to the KRB-ERROR message. Instead, the e-data field (see
+ figure 1) is utilized to carry the cryptographic checksum.
+
+
+3.1 Cryptographic checksums in error messages for AS_REQ,
+ TGS_REQ & AP_REQ
+
+ If an error occurs for the AS request, the only key that is
+ available to the KDC is the shared secret (the key derived from the
+ clients password) registered in the KDCs database. The KDC will
+ use this key to sign the error message, if and only if, the client
+ already proved knowledge of the shared secret in the AS request
+ (e.g. via PA-ENC-TIMESTAMP in preauth data). This policy is needed
+ to prevent an attacker from getting the KDC to send a signed error
+ message and then launching an off-line attack in order to obtain a
+ key of a given principal.
+
+ If an error occurs for a TGS or an AP request, the server will use
+ the session key sealed in the clients ticket granting ticket to
+ compute the checksum over the error message. If the checksum could
+ not be computed (e.g. error while decrypting the ticket) the error
+ message is returned to the client without the checksum. The client
+ then has the option to treat unprotected error messages differently.
+
+
+ KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
+ pvno [0] integer,
+ msg-type [1] integer,
+ ctime [2] KerberosTime OPTIONAL,
+ cusec [3] INTEGER OPTIONAL,
+ stime [4] KerberosTime,
+ susec [5] INTEGER,
+ error-code [6] INTEGER,
+ crealm [7] Realm OPTIONAL,
+ cname [8] PrincipalName OPTIONAL,
+ realm [9] Realm, --Correct realm
+ sname [10] PrincipalName, --Correct name
+ e-text [11] GeneralString OPTIONAL,
+ e-data [12] OCTET STRING OPTIONAL
+ }
+ Figure 1
+
+
+3.2 Format of the e-data field
+
+ We propose to place the cryptographic checksum in the e-data field.
+ First, we review the format of the e-data field, as specified in
+ RFC 1510. The format of e-data is specified only in two cases [2].
+ "If the error code is KDC_ERR_PREAUTH_REQUIRED, then the e-data
+ field will contain an encoding of a sequence of padata fields":
+
+ METHOD-DATA ::= SEQUENCE of PA-DATA
+ PA-DATA ::= SEQUENCE {
+ padata-type [1] INTEGER,
+ padata-value [2] OCTET STRING
+ }
+
+ The second case deals with the KRB_AP_ERR_METHOD error code. The
+ e-data field will contain an encoding of the following sequence:
+
+ METHOD-DATA ::= SEQUENCE {
+ method-type [0] INTEGER,
+ method-data [1] OCTET STRING OPTIONAL
+ }
+
+ method-type indicates the required alternate authentication method.
+
+ It should be noted that, in the case of KRB_AP_ERR_METHOD, a signed
+ checksum is not returned as part of the error message, since the
+ error code indicates that the Kerberos credentials provided in the
+ AP_REQ message are unacceptable.
+
+ We propose that the e-data field have the following format for all
+ error-codes (except KRB_AP_ERR_METHOD):
+
+ E-DATA ::= SEQUENCE {
+ data-type [1] INTEGER,
+ data-value [2] OCTET STRING,
+ }
+
+ The data-type field specifies the type of information that is
+ carried in the data-value field. Thus, to send a cryptographic
+ checksum back to the client, the data-type is set to CHECKSUM, the
+ data-value is set to the ASN.1 encoding of the following sequence:
+
+ Checksum ::= SEQUENCE {
+ cksumtype [0] INTEGER,
+ checksum [1] OCTET STRING
+ }
+
+
+3.3 Computing the checksum
+
+ After the error message is filled out, the error structure is
+ converted into ASN.1 representation. A cryptographic checksum is
+ then taken over the encoded error message; the result is placed in
+ the error message structure, as the last item in the e-data field.
+ To send the error message, ASN.1 encoding is again performed over
+ the error message, which now includes the cryptographic checksum.
+
+
+3.4 Verifying the integrity of the error message
+
+ In addition to verifying the cryptographic checksum for the error
+ message, the client must verify that the error message is bound to
+ its request. This is done by comparing the ctime field in the
+ error message to its counterpart in the request message.
+
+
+4. E-DATA types
+
+ Since the e-data types must not conflict with preauthentication data
+ types, we propose that the preauthentication data types in the range
+ of 2048 and above be reserved for use as e-data types.
+
+ We define the following e-data type in support of integrity checking
+ for the Kerberos error message:
+
+ CHECKSUM = 2048 -- the keyed checksum described above
+
+
+5. Discussion
+
+
+5.1 e-data types
+
+ The extension for Kerberos error messages, as outlined above, is
+ extensible to allow for definition of other error data types.
+ We propose that the following e-data types be reserved:
+
+ KDCTIME = 2049
+ The error data would consist of the KDCs time in KerberosTime.
+ This data would be used by the client to adjust for clock skew.
+
+ REDIRECT = 2050
+ The error data would consist of a hostname. The hostname would
+ indicate the authoritative KDC from which to obtain a TGT.
+
+
+5.2 e-data types vs. error code specific data formats
+
+ Since RFC 1510 does not define an error data type, the data format
+ must be explicitly specified for each error code. This draft has
+ proposed an extension to RFC 1510 that would introduce the concept
+ of error data types. This would allow for a manageable set of data
+ types to be used for any error message. The authors assume that
+ the introduction of this e-data structure will not break any
+ existing Kerberos implementations.
+
+
+6. Bibliography
+
+ [1] J. Kohl, C. Neuman. The Kerberos Network Authentication
+ Service (V5). Request for Comments: 1510
+ [2] J. Kohl, C. Neuman. The Kerberos Network Authentication
+ Service (V5). Request for Comments: 1510 p.67
+
+
+7. Authors
+
+ Ari Medvinsky <ari.medvinsky@cybersafe.com>
+ Matthew Hur <matt.hur@cybersafe.com>
+ Dominique Brezinski <dominique.brezinski@cybersafe.com>
+
+ CyberSafe Corporation
+ 1605 NW Sammamish Road
+ Suite 310
+ Issaquah, WA 98027-5378
+ Phone: (206) 391-6000
+ Fax: (206) 391-0508
+ http:/www.cybersafe.com
+
+
+ Brian Tung <brian@isi.edu>
+ Gene Tsudik <gts@isi.edu>
+
+ USC Information Sciences Institute
+ 4676 Admiralty Way Suite 1001
+ Marina del Rey CA 90292-6695
+ Phone: (310) 822-1511
+
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-pk-cross-01.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-pk-cross-01.txt
new file mode 100644
index 000000000000..4b193c57390c
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-pk-cross-01.txt
@@ -0,0 +1,282 @@
+INTERNET-DRAFT Brian Tung
+draft-ietf-cat-kerberos-pk-cross-01.txt Tatyana Ryutov
+Updates: RFC 1510 Clifford Neuman
+expires September 30, 1997 Gene Tsudik
+ ISI
+ Bill Sommerfeld
+ Hewlett-Packard
+ Ari Medvinsky
+ Matthew Hur
+ CyberSafe Corporation
+
+
+ Public Key Cryptography for Cross-Realm Authentication in Kerberos
+
+
+0. Status Of this Memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six
+ months and may be updated, replaced, or obsoleted by other
+ documents at any time. It is inappropriate to use Internet-Drafts
+ as reference material or to cite them other than as ``work in
+ progress.''
+
+ To learn the current status of any Internet-Draft, please check
+ the ``1id-abstracts.txt'' listing contained in the Internet-Drafts
+ Shadow Directories on ds.internic.net (US East Coast),
+ nic.nordu.net (Europe), ftp.isi.edu (US West Coast), or
+ munnari.oz.au (Pacific Rim).
+
+ The distribution of this memo is unlimited. It is filed as
+ draft-ietf-cat-kerberos-pk-cross-01.txt, and expires September 30,
+ 1997. Please send comments to the authors.
+
+
+1. Abstract
+
+ This document defines extensions to the Kerberos protocol
+ specification (RFC 1510, "The Kerberos Network Authentication
+ Service (V5)", September 1993) to provide a method for using
+ public key cryptography during cross-realm authentication. The
+ methods defined here specify the way in which message exchanges
+ are to be used to transport cross-realm secret keys protected by
+ encryption under public keys certified as belonging to KDCs.
+
+
+2. Motivation
+
+ The advantages provided by public key cryptography--ease of
+ recoverability in the event of a compromise, the possibility of
+ an autonomous authentication infrastructure, to name a few--have
+ produced a demand for use by Kerberos authentication protocol. A
+ draft describing the use of public key cryptography in the initial
+ authentication exchange in Kerberos has already been submitted.
+ This draft describes its use in cross-realm authentication.
+
+ The principal advantage provided by public key cryptography in
+ cross-realm authentication lies in the ability to leverage the
+ existing public key infrastructure. It frees the Kerberos realm
+ administrator from having to maintain separate keys for each other
+ realm with which it wishes to exchange authentication information,
+ or to utilize a hierarchical arrangement, which may pose problems
+ of trust.
+
+ Even with the multi-hop cross-realm authentication, there must be
+ some way to locate the path by which separate realms are to be
+ transited. The current method, which makes use of the DNS-like
+ realm names typical to Kerberos, requires trust of the intermediate
+ KDCs.
+
+ The methods described in this draft allow a realm to specify, at
+ the time of authentication, which certification paths it will
+ trust. A shared key for cross-realm authentication can be
+ established, for a period of time. Furthermore, these methods are
+ transparent to the client, so that only the KDC's need to be
+ modified to use them.
+
+ It is not necessary to implement the changes described in the
+ "Public Key Cryptography for Initial Authentication" draft to make
+ use of the changes in this draft. We solicit comments about the
+ interaction between the two protocol changes, but as of this
+ writing, the authors do not perceive any obstacles to using both.
+
+
+3. Protocol Amendments
+
+ We assume that the user has already obtained a TGT. To perform
+ cross-realm authentication, the user sends a request to the local
+ KDC as per RFC 1510. If the two realms share a secret key, then
+ cross-realm authentication proceeds as usual. Otherwise, the
+ local KDC may attempt to establish a shared key with the remote
+ KDC using public key cryptography, and exchange this key through
+ the cross-realm ticket granting ticket.
+
+ We will consider the specific channel on which the message
+ exchanges take place in Section 5 below.
+
+
+3.1. Changes to the Cross-Realm Ticket Granting Ticket
+
+ In order to avoid the need for changes to the "installed base" of
+ Kerberos application clients and servers, the only protocol change
+ is to the way in which cross-realm ticket granting tickets (TGTs)
+ are encrypted; as these tickets are opaque to clients and servers,
+ the only change visible to them will be the increased size of the
+ tickets.
+
+ Cross-realm TGTs are granted by a local KDC to authenticate a user
+ to a remote KDC's ticket granting service. In standard Kerberos,
+ they are encrypted using a shared secret key manually configured
+ into each KDC.
+
+ In order to incorporate public key cryptography, we define a new
+ encryption type, "ENCTYPE_PK_CROSS". Operationally, this encryption
+ type transforms an OCTET STRING of plaintext (normally an EncTktPart)
+ into the following SEQUENCE:
+
+ PKCrossOutput ::= SEQUENCE {
+ certificate [0] OCTET STRING OPTIONAL,
+ -- public key certificate
+ -- of local KDC
+ encSharedKey [1] EncryptedData,
+ -- of type EncryptionKey
+ -- containing random symmetric key
+ -- encrypted using public key
+ -- of remote KDC
+ sigSharedKey [2] Signature,
+ -- of encSharedKey
+ -- using signature key
+ -- of local KDC
+ pkEncData [3] EncryptedData,
+ -- (normally) of type EncTktPart
+ -- encrypted using encryption key
+ -- found in encSharedKey
+ }
+
+ PKCROSS operates as follows: when a client submits a request for
+ cross-realm authentication, the local KDC checks to see if it has
+ a long-term shared key established for that realm. If so, it uses
+ this key as per RFC 1510.
+
+ If not, it sends a request for information to the remote KDC. The
+ content of this message is immaterial, as it does not need to be
+ processed by the remote KDC; for the sake of consistency, we define
+ it as follows:
+
+ RemoteRequest ::= [APPLICATION 41] SEQUENCE {
+ nonce [0] INTEGER
+ }
+
+ The remote KDC replies with a list of all trusted certifiers and
+ all its (the remote KDC's) certificates. We note that this response
+ is universal and does not depend on which KDC makes the request:
+
+ RemoteReply ::= [APPLICATION 42] SEQUENCE {
+ trustedCertifiers [0] SEQUENCE OF PrincipalName,
+ certificates[1] SEQUENCE OF Certificate,
+ encTypeToUse [1] SEQUENCE OF INTEGER
+ -- encryption types usable
+ -- for encrypting pkEncData
+ }
+
+ Certificate ::= SEQUENCE {
+ CertType [0] INTEGER,
+ -- type of certificate
+ -- 1 = X.509v3 (DER encoding)
+ -- 2 = PGP (per PGP draft)
+ CertData [1] OCTET STRING
+ -- actual certificate
+ -- type determined by CertType
+ } -- from pk-init draft
+
+ Upon receiving this reply, the local KDC determines whether it has
+ a certificate the remote KDC trusts, and whether the remote KDC has
+ a certificate the local KDC trusts. If so, it issues a ticket
+ encrypted using the ENCTYPE_PK_CROSS encryption type defined above.
+
+
+3.2. Profile Caches
+
+ We observe that using PKCROSS as specified above requires two
+ private key operations: a signature generation by the local KDC and
+ a decryption by the remote KDC. This cost can be reduced in the
+ long term by judicious caching of the encSharedKey and the
+ sigSharedKey.
+
+ Let us define a "profile" as the encSharedKey and sigSharedKey, in
+ conjunction with the associated remote realm name and decrypted
+ shared key (the key encrypted in the encSharedKey).
+
+ To optimize these interactions, each KDC maintains two caches, one
+ for outbound profiles and one for inbound profiles. When generating
+ an outbound TGT for another realm, the local KDC first checks to see
+ if the corresponding entry exists in the outbound profile cache; if
+ so, it uses its contents to form the first three fields of the
+ PKCrossOutput; the shared key is used to encrypt the data for the
+ fourth field. If not, the components are generated fresh and stored
+ in the outbound profile cache.
+
+ Upon receipt of the TGT, the remote realm checks its inbound profile
+ cache for the corresponding entry. If it exists, then it uses the
+ contents of the entry to decrypt the data encrypted in the pkEncData.
+ If not, then it goes through the full process of verifying and
+ extracting the shared key; if this is successful, then a new entry
+ is created in the inbound profile cache.
+
+ The inbound profile cache should support multiple entries per realm,
+ in the event that the initiating realm is replicated.
+
+
+4. Finding Realms Supporting PKCROSS
+
+ If either the local realm or the destination realm does not support
+ PKCROSS, or both do not, the mechanism specified in Section 3 can
+ still be used in obtaining the desired remote TGT.
+
+ In the reference Kerberos implementations, the default behavior is
+ to traverse a path up and down the realm name hierarchy, if the
+ two realms do not share a key. There is, however, the possibility
+ of using cross links--i.e., keys shared between two realms that
+ are non-contiguous in the realm name hierarchy--to shorten the
+ path, both to minimize delay and the number of intermediate realms
+ that need to be trusted.
+
+ PKCROSS can be used as a way to provide cross-links even in the
+ absence of shared keys. If the client is aware that one or two
+ intermediate realms support PKCROSS, then a combination of
+ PKCROSS and conventional cross-realm authentication can be used
+ to reach the final destination realm.
+
+ We solicit discussion on the best methods for clients and KDCs to
+ determine or advertise support for PKCROSS.
+
+
+5. Message Ports
+
+ We have not specified the port on which KDCs supporting PKCROSS
+ should listen to receive the request for information messages noted
+ above. We solicit discussion on which port should be used. We
+ propose to use the standard Kerberos ports (well-known 88 or 750),
+ but another possibility is to use a completely different port.
+
+ We also solicit discussion on what other approaches can be taken to
+ obtain the information in the RemoteReply (e.g., secure DNS or some
+ other repository).
+
+
+6. Expiration Date
+
+ This Internet-Draft will expire on September 30, 1997.
+
+
+7. Authors' Addresses
+
+ Brian Tung
+ Tatyana Ryutov
+ Clifford Neuman
+ Gene Tsudik
+ USC/Information Sciences Institute
+ 4676 Admiralty Way Suite 1001
+ Marina del Rey, CA 90292-6695
+ Phone: +1 310 822 1511
+ E-Mail: {brian, tryutov, bcn, gts}@isi.edu
+
+ Bill Sommerfeld
+ Hewlett Packard
+ 300 Apollo Drive
+ Chelmsford MA 01824
+ Phone: +1 508 436 4352
+ E-Mail: sommerfeld@apollo.hp.com
+
+ Ari Medvinsky
+ Matthew Hur
+ CyberSafe Corporation
+ 1605 NW Sammamish Road Suite 310
+ Issaquah WA 98027-5378
+ Phone: +1 206 391 6000
+ E-mail: {ari.medvinsky, matt.hur}@cybersafe.com
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-pk-init-03.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-pk-init-03.txt
new file mode 100644
index 000000000000..d91c087dddf9
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-pk-init-03.txt
@@ -0,0 +1,589 @@
+
+INTERNET-DRAFT Clifford Neuman
+draft-ietf-cat-kerberos-pk-init-03.txt Brian Tung
+Updates: RFC 1510 ISI
+expires September 30, 1997 John Wray
+ Digital Equipment Corporation
+ Ari Medvinsky
+ Matthew Hur
+ CyberSafe Corporation
+ Jonathan Trostle
+ Novell
+
+
+ Public Key Cryptography for Initial Authentication in Kerberos
+
+
+0. Status Of this Memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six
+ months and may be updated, replaced, or obsoleted by other
+ documents at any time. It is inappropriate to use Internet-Drafts
+ as reference material or to cite them other than as "work in
+ progress."
+
+ To learn the current status of any Internet-Draft, please check
+ the "1id-abstracts.txt" listing contained in the Internet-Drafts
+ Shadow Directories on ds.internic.net (US East Coast),
+ nic.nordu.net (Europe), ftp.isi.edu (US West Coast), or
+ munnari.oz.au (Pacific Rim).
+
+ The distribution of this memo is unlimited. It is filed as
+ draft-ietf-cat-kerberos-pk-init-03.txt, and expires September 30,
+ 1997. Please send comments to the authors.
+
+
+1. Abstract
+
+ This document defines extensions (PKINIT) to the Kerberos protocol
+ specification (RFC 1510 [1]) to provide a method for using public
+ key cryptography during initial authentication. The methods
+ defined specify the ways in which preauthentication data fields and
+ error data fields in Kerberos messages are to be used to transport
+ public key data.
+
+
+2. Introduction
+
+ The popularity of public key cryptography has produced a desire for
+ its support in Kerberos [2]. The advantages provided by public key
+ cryptography include simplified key management (from the Kerberos
+ perspective) and the ability to leverage existing and developing
+ public key certification infrastructures.
+
+ Public key cryptography can be integrated into Kerberos in a number
+ of ways. One is to to associate a key pair with each realm, which
+ can then be used to facilitate cross-realm authentication; this is
+ the topic of another draft proposal. Another way is to allow users
+ with public key certificates to use them in initial authentication.
+ This is the concern of the current document.
+
+ One of the guiding principles in the design of PKINIT is that
+ changes should be as minimal as possible. As a result, the basic
+ mechanism of PKINIT is as follows: The user sends a request to the
+ KDC as before, except that if that user is to use public key
+ cryptography in the initial authentication step, his certificate
+ accompanies the initial request, in the preauthentication fields.
+
+ Upon receipt of this request, the KDC verifies the certificate and
+ issues a ticket granting ticket (TGT) as before, except that instead
+ of being encrypted in the user's long-term key (which is derived
+ from a password), it is encrypted in a randomly-generated key. This
+ random key is in turn encrypted using the public key certificate
+ that came with the request and signed using the KDC's signature key,
+ and accompanies the reply, in the preauthentication fields.
+
+ PKINIT also allows for users with only digital signature keys to
+ authenticate using those keys, and for users to store and retrieve
+ private keys on the KDC.
+
+ The PKINIT specification may also be used for direct peer to peer
+ authentication without contacting a central KDC. This application
+ of PKINIT is described in PKTAPP [4] and is based on concepts
+ introduced in [5, 6]. For direct client-to-server authentication,
+ the client uses PKINIT to authenticate to the end server (instead
+ of a central KDC), which then issues a ticket for itself. This
+ approach has an advantage over SSL [7] in that the server does not
+ need to save state (cache session keys). Furthermore, an
+ additional benefit is that Kerberos tickets can facilitate
+ delegation (see [8]).
+
+
+3. Proposed Extensions
+
+ This section describes extensions to RFC 1510 for supporting the
+ use of public key cryptography in the initial request for a ticket
+ granting ticket (TGT).
+
+ In summary, the following changes to RFC 1510 are proposed:
+
+ --> Users may authenticate using either a public key pair or a
+ conventional (symmetric) key. If public key cryptography is
+ used, public key data is transported in preauthentication
+ data fields to help establish identity.
+ --> Users may store private keys on the KDC for retrieval during
+ Kerberos initial authentication.
+
+ This proposal addresses two ways that users may use public key
+ cryptography for initial authentication. Users may present public
+ key certificates, or they may generate their own session key,
+ signed by their digital signature key. In either case, the end
+ result is that the user obtains an ordinary TGT that may be used for
+ subsequent authentication, with such authentication using only
+ conventional cryptography.
+
+ Section 3.1 provides definitions to help specify message formats.
+ Section 3.2 and 3.3 describe the extensions for the two initial
+ authentication methods. Section 3.3 describes a way for the user to
+ store and retrieve his private key on the KDC.
+
+
+3.1. Definitions
+
+ Hash and encryption types will be specified using ENCTYPE tags; we
+ propose the addition of the following types:
+
+ #define ENCTYPE_SIGN_DSA_GENERATE 0x0011
+ #define ENCTYPE_SIGN_DSA_VERIFY 0x0012
+ #define ENCTYPE_ENCRYPT_RSA_PRIV 0x0021
+ #define ENCTYPE_ENCRYPT_RSA_PUB 0x0022
+
+ allowing further signature types to be defined in the range 0x0011
+ through 0x001f, and further encryption types to be defined in the
+ range 0x0021 through 0x002f.
+
+ The extensions involve new preauthentication fields. The
+ preauthentication data types are in the range 17 through 21.
+ These values are also specified along with their corresponding
+ ASN.1 definition.
+
+ #define PA-PK-AS-REQ 17
+ #define PA-PK-AS-REP 18
+ #define PA-PK-AS-SIGN 19
+ #define PA-PK-KEY-REQ 20
+ #define PA-PK-KEY-REP 21
+
+ The extensions also involve new error types. The new error types
+ are in the range 227 through 229. They are:
+
+ #define KDC_ERROR_CLIENT_NOT_TRUSTED 227
+ #define KDC_ERROR_KDC_NOT_TRUSTED 228
+ #define KDC_ERROR_INVALID_SIG 229
+
+ In the exposition below, we use the following terms: encryption key,
+ decryption key, signature key, verification key. It should be
+ understood that encryption and verification keys are essentially
+ public keys, and decryption and signature keys are essentially
+ private keys. The fact that they are logically distinct does
+ not preclude the assignment of bitwise identical keys.
+
+
+3.2. Standard Public Key Authentication
+
+ Implementation of the changes in this section is REQUIRED for
+ compliance with pk-init.
+
+ It is assumed that all public keys are signed by some certification
+ authority (CA). The initial authentication request is sent as per
+ RFC 1510, except that a preauthentication field containing data
+ signed by the user's signature key accompanies the request:
+
+ PA-PK-AS-REQ ::- SEQUENCE {
+ -- PA TYPE 17
+ signedPKAuth [0] SignedPKAuthenticator,
+ userCert [1] SEQUENCE OF Certificate OPTIONAL,
+ -- the user's certificate
+ -- optionally followed by that
+ -- certificate's certifier chain
+ trustedCertifiers [2] SEQUENCE OF PrincipalName OPTIONAL
+ -- CAs that the client trusts
+ }
+
+ SignedPKAuthenticator ::= SEQUENCE {
+ pkAuth [0] PKAuthenticator,
+ pkAuthSig [1] Signature,
+ -- of pkAuth
+ -- using user's signature key
+ }
+
+ PKAuthenticator ::= SEQUENCE {
+ cusec [0] INTEGER,
+ -- for replay prevention
+ ctime [1] KerberosTime,
+ -- for replay prevention
+ nonce [2] INTEGER,
+ -- binds response to this request
+ kdcName [3] PrincipalName,
+ clientPubValue [4] SubjectPublicKeyInfo OPTIONAL,
+ -- for Diffie-Hellman algorithm
+ }
+
+ Signature ::= SEQUENCE {
+ signedHash [0] EncryptedData
+ -- of type Checksum
+ -- encrypted under signature key
+ }
+
+ Checksum ::= SEQUENCE {
+ cksumtype [0] INTEGER,
+ checksum [1] OCTET STRING
+ } -- as specified by RFC 1510
+
+ SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm [0] algorithmIdentifier,
+ subjectPublicKey [1] BIT STRING
+ } -- as specified by the X.509 recommendation [9]
+
+ Certificate ::= SEQUENCE {
+ CertType [0] INTEGER,
+ -- type of certificate
+ -- 1 = X.509v3 (DER encoding)
+ -- 2 = PGP (per PGP draft)
+ CertData [1] OCTET STRING
+ -- actual certificate
+ -- type determined by CertType
+ }
+
+ Note: If the signature uses RSA keys, then it is to be performed
+ as per PKCS #1.
+
+ The PKAuthenticator carries information to foil replay attacks,
+ to bind the request and response, and to optionally pass the
+ client's Diffie-Hellman public value (i.e. for using DSA in
+ combination with Diffie-Hellman). The PKAuthenticator is signed
+ with the private key corresponding to the public key in the
+ certificate found in userCert (or cached by the KDC).
+
+ In the PKAuthenticator, the client may specify the KDC name in one
+ of two ways: 1) a Kerberos principal name, or 2) the name in the
+ KDC's certificate (e.g., an X.500 name, or a PGP name). Note that
+ case #1 requires that the certificate name and the Kerberos principal
+ name be bound together (e.g., via an X.509v3 extension).
+
+ The userCert field is a sequence of certificates, the first of which
+ must be the user's public key certificate. Any subsequent
+ certificates will be certificates of the certifiers of the user's
+ certificate. These cerificates may be used by the KDC to verify the
+ user's public key. This field is empty if the KDC already has the
+ user's certifcate.
+
+ The trustedCertifiers field contains a list of certification
+ authorities trusted by the client, in the case that the client does
+ not possess the KDC's public key certificate.
+
+ Upon receipt of the AS_REQ with PA-PK-AS-REQ pre-authentication
+ type, the KDC attempts to verify the user's certificate chain
+ (userCert), if one is provided in the request. This is done by
+ verifying the certification path against the KDC's policy of
+ legitimate certifiers. This may be based on a certification
+ hierarchy, or it may be simply a list of recognized certifiers in a
+ system like PGP. If the certification path does not match one of
+ the KDC's trusted certifiers, the KDC sends back an error message of
+ type KDC_ERROR_CLIENT_NOT_TRUSTED, and it includes in the error data
+ field a list of its own trusted certifiers, upon which the client
+ resends the request.
+
+ If trustedCertifiers is provided in the PA-PK-AS-REQ, the KDC
+ verifies that it has a certificate issued by one of the certifiers
+ trusted by the client. If it does not have a suitable certificate,
+ the KDC returns an error message of type KDC_ERROR_KDC_NOT_TRUSTED
+ to the client.
+
+ If a trust relationship exists, the KDC then verifies the client's
+ signature on PKAuthenticator. If that fails, the KDC returns an
+ error message of type KDC_ERROR_INVALID_SIG. Otherwise, the KDC
+ uses the timestamp in the PKAuthenticator to assure that the request
+ is not a replay. The KDC also verifies that its name is specified
+ in PKAuthenticator.
+
+ Assuming no errors, the KDC replies as per RFC 1510, except that it
+ encrypts the reply not with the user's key, but with a random key
+ generated only for this particular response. This random key
+ is sealed in the preauthentication field:
+
+ PA-PK-AS-REP ::= SEQUENCE {
+ -- PA TYPE 18
+ kdcCert [0] SEQUENCE OF Certificate OPTIONAL,
+ -- the KDC's certificate
+ -- optionally followed by that
+ -- certificate's certifier chain
+ encPaReply [1] EncryptedData,
+ -- of type PaReply
+ -- using either the client public
+ -- key or the Diffie-Hellman key
+ -- specified by SignedDHPublicValue
+ signedDHPublicValue [2] SignedDHPublicValue OPTIONAL
+ }
+
+
+ PaReply ::= SEQUENCE {
+ replyEncKeyPack [0] ReplyEncKeyPack,
+ replyEncKeyPackSig [1] Signature,
+ -- of replyEncKeyPack
+ -- using KDC's signature key
+ }
+
+ ReplyEncKeyPack ::= SEQUENCE {
+ replyEncKey [0] EncryptionKey,
+ -- used to encrypt main reply
+ nonce [1] INTEGER
+ -- binds response to the request
+ -- passed in the PKAuthenticator
+ }
+
+ SignedDHPublicValue ::= SEQUENCE {
+ dhPublicValue [0] SubjectPublicKeyInfo,
+ dhPublicValueSig [1] Signature
+ -- of dhPublicValue
+ -- using KDC's signature key
+ }
+
+ The kdcCert field is a sequence of certificates, the first of which
+ must have as its root certifier one of the certifiers sent to the
+ KDC in the PA-PK-AS-REQ. Any subsequent certificates will be
+ certificates of the certifiers of the KDC's certificate. These
+ cerificates may be used by the client to verify the KDC's public
+ key. This field is empty if the client did not send to the KDC a
+ list of trusted certifiers (the trustedCertifiers field was empty).
+
+ Since each certifier in the certification path of a user's
+ certificate is essentially a separate realm, the name of each
+ certifier shall be added to the transited field of the ticket. The
+ format of these realm names shall follow the naming constraints set
+ forth in RFC 1510 (sections 7.1 and 3.3.3.1). Note that this will
+ require new nametypes to be defined for PGP certifiers and other
+ types of realms as they arise.
+
+ The KDC's certificate must bind the public key to a name derivable
+ from the name of the realm for that KDC. The client then extracts
+ the random key used to encrypt the main reply. This random key (in
+ encPaReply) is encrypted with either the client's public key or
+ with a key derived from the DH values exchanged between the client
+ and the KDC.
+
+
+3.3. Digital Signature
+
+ Implementation of the changes in this section are OPTIONAL for
+ compliance with pk-init.
+
+ We offer this option with the warning that it requires the client to
+ generate a random key; the client may not be able to guarantee the
+ same level of randomness as the KDC.
+
+ If the user registered a digital signature key with the KDC instead
+ of an encryption key, then a separate exchange must be used. The
+ client sends a request for a TGT as usual, except that it (rather
+ than the KDC) generates the random key that will be used to encrypt
+ the KDC response. This key is sent to the KDC along with the
+ request in a preauthentication field:
+
+ PA-PK-AS-SIGN ::= SEQUENCE {
+ -- PA TYPE 19
+ encSignedKeyPack [0] EncryptedData
+ -- of SignedKeyPack
+ -- using the KDC's public key
+ }
+
+ SignedKeyPack ::= SEQUENCE {
+ signedKey [0] KeyPack,
+ signedKeyAuth [1] PKAuthenticator,
+ signedKeySig [2] Signature
+ -- of signedKey.signedKeyAuth
+ -- using user's signature key
+ }
+
+ KeyPack ::= SEQUENCE {
+ randomKey [0] EncryptionKey,
+ -- will be used to encrypt reply
+ nonce [1] INTEGER
+ }
+
+ where the nonce is copied from the request.
+
+ Upon receipt of the PA-PK-AS-SIGN, the KDC decrypts then verifies
+ the randomKey. It then replies as per RFC 1510, except that the
+ reply is encrypted not with a password-derived user key, but with
+ the randomKey sent in the request. Since the client already knows
+ this key, there is no need to accompany the reply with an extra
+ preauthentication field. The transited field of the ticket should
+ specify the certification path as described in Section 3.2.
+
+
+3.4. Retrieving the Private Key From the KDC
+
+ Implementation of the changes in this section is RECOMMENDED for
+ compliance with pk-init.
+
+ When the user's private key is not stored local to the user, he may
+ choose to store the private key (normally encrypted using a
+ password-derived key) on the KDC. We provide this option to present
+ the user with an alternative to storing the private key on local
+ disk at each machine where he expects to authenticate himself using
+ pk-init. It should be noted that it replaces the added risk of
+ long-term storage of the private key on possibly many workstations
+ with the added risk of storing the private key on the KDC in a
+ form vulnerable to brute-force attack.
+
+ In order to obtain a private key, the client includes a
+ preauthentication field with the AS-REQ message:
+
+ PA-PK-KEY-REQ ::= SEQUENCE {
+ -- PA TYPE 20
+ patimestamp [0] KerberosTime OPTIONAL,
+ -- used to address replay attacks.
+ pausec [1] INTEGER OPTIONAL,
+ -- used to address replay attacks.
+ nonce [2] INTEGER,
+ -- binds the reply to this request
+ privkeyID [3] SEQUENCE OF KeyID OPTIONAL
+ -- constructed as a hash of
+ -- public key corresponding to
+ -- desired private key
+ }
+
+ KeyID ::= SEQUENCE {
+ KeyIdentifier [0] OCTET STRING
+ }
+
+ The client may request a specific private key by sending the
+ corresponding ID. If this field is left empty, then all
+ private keys are returned.
+
+ If all checks out, the KDC responds as described in the above
+ sections, except that an additional preauthentication field,
+ containing the user's private key, accompanies the reply:
+
+ PA-PK-KEY-REP ::= SEQUENCE {
+ -- PA TYPE 21
+ nonce [0] INTEGER,
+ -- binds the reply to the request
+ KeyData [1] SEQUENCE OF KeyPair
+ }
+
+ KeyPair ::= SEQUENCE {
+ privKeyID [0] OCTET STRING,
+ -- corresponding to encPrivKey
+ encPrivKey [1] OCTET STRING
+ }
+
+
+3.4.1. Additional Protection of Retrieved Private Keys
+
+ We solicit discussion on the following proposal: that the client may
+ optionally include in its request additional data to encrypt the
+ private key, which is currently only protected by the user's
+ password. One possibility is that the client might generate a
+ random string of bits, encrypt it with the public key of the KDC (as
+ in the SignedKeyPack, but with an ordinary OCTET STRING in place of
+ an EncryptionKey), and include this with the request. The KDC then
+ XORs each returned key with this random bit string. (If the bit
+ string is too short, the KDC could either return an error, or XOR
+ the returned key with a repetition of the bit string.)
+
+ In order to make this work, additional means of preauthentication
+ need to be devised in order to prevent attackers from simply
+ inserting their own bit string. One way to do this is to store
+ a hash of the password-derived key (the one used to encrypt the
+ private key). This hash is then used in turn to derive a second
+ key (called the hash-key); the hash-key is used to encrypt an ASN.1
+ structure containing the generated bit string and a nonce value
+ that binds it to the request.
+
+ Since the KDC possesses the hash, it can generate the hash-key and
+ verify this (weaker) preauthentication, and yet cannot reproduce
+ the private key itself, since the hash is a one-way function.
+
+
+4. Logistics and Policy Issues
+
+ We solicit discussion on how clients and KDCs should be configured
+ in order to determine which of the options described above (if any)
+ should be used. One possibility is to set the user's database
+ record to indicate that authentication is to use public key
+ cryptography; this will not work, however, in the event that the
+ client needs to know before making the initial request.
+
+5. Compatibility with One-Time Passcodes
+
+ We solicit discussion on how the protocol changes proposed in this
+ draft will interact with the proposed use of one-time passcodes
+ discussed in draft-ietf-cat-kerberos-passwords-00.txt.
+
+
+6. Strength of Cryptographic Schemes
+
+ In light of recent findings on the strength of MD5 and DES,
+ we solicit discussion on which encryption types to incorporate
+ into the protocol changes.
+
+
+7. Bibliography
+
+ [1] J. Kohl, C. Neuman. The Kerberos Network Authentication
+ Service (V5). Request for Comments: 1510
+
+ [2] B.C. Neuman, Theodore Ts'o. Kerberos: An Authentication Service
+ for Computer Networks, IEEE Communications, 32(9):33-38.
+ September 1994.
+
+ [3] A. Medvinsky, M. Hur. Addition of Kerberos Cipher Suites to
+ Transport Layer Security (TLS).
+ draft-ietf-tls-kerb-cipher-suites-00.txt
+
+ [4] A. Medvinsky, M. Hur, B. Clifford Neuman. Public Key Utilizing
+ Tickets for Application Servers (PKTAPP).
+ draft-ietf-cat-pktapp-00.txt
+
+ [5] M. Sirbu, J. Chuang. Distributed Authentication in Kerberos Using
+ Public Key Cryptography. Symposium On Network and Distributed System
+ Security, 1997.
+
+ [6] B. Cox, J.D. Tygar, M. Sirbu. NetBill Security and Transaction
+ Protocol. In Proceedings of the USENIX Workshop on Electronic Commerce,
+ July 1995.
+
+ [7] Alan O. Freier, Philip Karlton and Paul C. Kocher.
+ The SSL Protocol, Version 3.0 - IETF Draft.
+
+ [8] B.C. Neuman, Proxy-Based Authorization and Accounting for
+ Distributed Systems. In Proceedings of the 13th International
+ Conference on Distributed Computing Systems, May 1993
+
+ [9] ITU-T (formerly CCITT)
+ Information technology - Open Systems Interconnection -
+ The Directory: Authentication Framework Recommendation X.509
+ ISO/IEC 9594-8
+
+
+8. Acknowledgements
+
+ Some of the ideas on which this proposal is based arose during
+ discussions over several years between members of the SAAG, the IETF
+ CAT working group, and the PSRG, regarding integration of Kerberos
+ and SPX. Some ideas have also been drawn from the DASS system.
+ These changes are by no means endorsed by these groups. This is an
+ attempt to revive some of the goals of those groups, and this
+ proposal approaches those goals primarily from the Kerberos
+ perspective. Lastly, comments from groups working on similar ideas
+ in DCE have been invaluable.
+
+
+9. Expiration Date
+
+ This draft expires September 30, 1997.
+
+
+10. Authors
+
+ Clifford Neuman
+ Brian Tung
+ USC Information Sciences Institute
+ 4676 Admiralty Way Suite 1001
+ Marina del Rey CA 90292-6695
+ Phone: +1 310 822 1511
+ E-mail: {bcn, brian}@isi.edu
+
+ John Wray
+ Digital Equipment Corporation
+ 550 King Street, LKG2-2/Z7
+ Littleton, MA 01460
+ Phone: +1 508 486 5210
+ E-mail: wray@tuxedo.enet.dec.com
+
+ Ari Medvinsky
+ Matthew Hur
+ CyberSafe Corporation
+ 1605 NW Sammamish Road Suite 310
+ Issaquah WA 98027-5378
+ Phone: +1 206 391 6000
+ E-mail: {ari.medvinsky, matt.hur}@cybersafe.com
+
+ Jonathan Trostle
+ Novell
+ E-mail: jonathan.trostle@novell.com
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-00.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-00.txt
new file mode 100644
index 000000000000..2284c3c6b57b
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-00.txt
@@ -0,0 +1,8277 @@
+
+INTERNET-DRAFT Clifford Neuman
+ John Kohl
+ Theodore Ts'o
+ 11 July 1997
+
+
+
+ The Kerberos Network Authentication Service (V5)
+
+
+STATUS OF THIS MEMO
+
+ This document is an Internet-Draft. Internet-Drafts
+are working documents of the Internet Engineering Task Force
+(IETF), its areas, and its working groups. Note that other
+groups may also distribute working documents as Internet-
+Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum
+of six months and may be updated, replaced, or obsoleted by
+other documents at any time. It is inappropriate to use
+Internet-Drafts as reference material or to cite them other
+than as "work in progress."
+
+ To learn the current status of any Internet-Draft,
+please check the "1id-abstracts.txt" listing contained in
+the Internet-Drafts Shadow Directories on ds.internic.net
+(US East Coast), nic.nordu.net (Europe), ftp.isi.edu (US
+West Coast), or munnari.oz.au (Pacific Rim).
+
+ The distribution of this memo is unlimited. It is
+filed as draft-ietf-cat-kerberos-revisions-00.txt, and expires
+11 January 1998. Please send comments to:
+
+ krb-protocol@MIT.EDU
+
+ABSTRACT
+
+
+ This document provides an overview and specification of
+Version 5 of the Kerberos protocol, and updates RFC1510 to
+clarify aspects of the protocol and its intended use that
+require more detailed or clearer explanation than was pro-
+vided in RFC1510. This document is intended to provide a
+detailed description of the protocol, suitable for implemen-
+tation, together with descriptions of the appropriate use of
+protocol messages and fields within those messages.
+
+ This document is not intended to describe Kerberos to
+__________________________
+Project Athena, Athena, and Kerberos are trademarks of
+the Massachusetts Institute of Technology (MIT). No
+commercial use of these trademarks may be made without
+prior written permission of MIT.
+
+
+
+Overview - 1 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+the end user, system administrator, or application
+developer. Higher level papers describing Version 5 of the
+Kerberos system [1] and documenting version 4 [23], are
+available elsewhere.
+
+OVERVIEW
+
+ This INTERNET-DRAFT describes the concepts and model
+upon which the Kerberos network authentication system is
+based. It also specifies Version 5 of the Kerberos proto-
+col.
+
+ The motivations, goals, assumptions, and rationale
+behind most design decisions are treated cursorily; they are
+more fully described in a paper available in IEEE communica-
+tions [1] and earlier in the Kerberos portion of the Athena
+Technical Plan [2]. The protocols have been a proposed
+standard and are being considered for advancement for draft
+standard through the IETF standard process. Comments are
+encouraged on the presentation, but only minor refinements
+to the protocol as implemented or extensions that fit within
+current protocol framework will be considered at this time.
+
+ Requests for addition to an electronic mailing list for
+discussion of Kerberos, kerberos@MIT.EDU, may be addressed
+to kerberos-request@MIT.EDU. This mailing list is gatewayed
+onto the Usenet as the group comp.protocols.kerberos.
+Requests for further information, including documents and
+code availability, may be sent to info-kerberos@MIT.EDU.
+
+BACKGROUND
+
+ The Kerberos model is based in part on Needham and
+Schroeder's trusted third-party authentication protocol [4]
+and on modifications suggested by Denning and Sacco [5].
+The original design and implementation of Kerberos Versions
+1 through 4 was the work of two former Project Athena staff
+members, Steve Miller of Digital Equipment Corporation and
+Clifford Neuman (now at the Information Sciences Institute
+of the University of Southern California), along with Jerome
+Saltzer, Technical Director of Project Athena, and Jeffrey
+Schiller, MIT Campus Network Manager. Many other members of
+Project Athena have also contributed to the work on Ker-
+beros.
+
+ Version 5 of the Kerberos protocol (described in this
+document) has evolved from Version 4 based on new require-
+ments and desires for features not available in Version 4.
+The design of Version 5 of the Kerberos protocol was led by
+Clifford Neuman and John Kohl with much input from the com-
+munity. The development of the MIT reference implementation
+was led at MIT by John Kohl and Theodore T'so, with help and
+contributed code from many others. Reference implementa-
+tions of both version 4 and version 5 of Kerberos are pub-
+licly available and commercial implementations have been
+
+Overview - 2 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+developed and are widely used.
+
+ Details on the differences between Kerberos Versions 4
+and 5 can be found in [6].
+
+1. Introduction
+
+ Kerberos provides a means of verifying the identities
+of principals, (e.g. a workstation user or a network server)
+on an open (unprotected) network. This is accomplished
+without relying on assertions by the host operating system,
+without basing trust on host addresses, without requiring
+physical security of all the hosts on the network, and under
+the assumption that packets traveling along the network can
+be read, modified, and inserted at will[1]. Kerberos per-
+forms authentication under these conditions as a trusted
+third-party authentication service by using conventional
+(shared secret key[2]) cryptography. Kerberos extensions
+have been proposed and implemented that provide for the use
+of public key cryptography during certain phases of the
+authentication protocol. These extensions provide for
+authentication of users registered with public key certifi-
+cation authorities, and allow the system to provide certain
+benefits of public key cryptography in situations where they
+are needed.
+
+ The basic Kerberos authentication process proceeds as
+follows: A client sends a request to the authentication
+server (AS) requesting "credentials" for a given server.
+The AS responds with these credentials, encrypted in the
+client's key. The credentials consist of 1) a "ticket" for
+the server and 2) a temporary encryption key (often called a
+"session key"). The client transmits the ticket (which con-
+tains the client's identity and a copy of the session key,
+all encrypted in the server's key) to the server. The ses-
+sion key (now shared by the client and server) is used to
+authenticate the client, and may optionally be used to
+__________________________
+[1] Note, however, that many applications use Kerberos'
+functions only upon the initiation of a stream-based
+network connection. Unless an application subsequently
+provides integrity protection for the data stream, the
+identity verification applies only to the initiation of
+the connection, and does not guarantee that subsequent
+messages on the connection originate from the same
+principal.
+[2] Secret and private are often used interchangeably
+in the literature. In our usage, it takes two (or
+more) to share a secret, thus a shared DES key is a
+secret key. Something is only private when no one but
+its owner knows it. Thus, in public key cryptosystems,
+one has a public and a private key.
+
+
+
+Section 1. - 3 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+authenticate the server. It may also be used to encrypt
+further communication between the two parties or to exchange
+a separate sub-session key to be used to encrypt further
+communication.
+
+ Implementation of the basic protocol consists of one or
+more authentication servers running on physically secure
+hosts. The authentication servers maintain a database of
+principals (i.e., users and servers) and their secret keys.
+Code libraries provide encryption and implement the Kerberos
+protocol. In order to add authentication to its transac-
+tions, a typical network application adds one or two calls
+to the Kerberos library directly or through the Generic
+Security Services Application Programming Interface, GSSAPI,
+described in separate document. These calls result in the
+transmission of the necessary messages to achieve authenti-
+cation.
+
+ The Kerberos protocol consists of several sub-protocols
+(or exchanges). There are two basic methods by which a
+client can ask a Kerberos server for credentials. In the
+first approach, the client sends a cleartext request for a
+ticket for the desired server to the AS. The reply is sent
+encrypted in the client's secret key. Usually this request
+is for a ticket-granting ticket (TGT) which can later be
+used with the ticket-granting server (TGS). In the second
+method, the client sends a request to the TGS. The client
+uses the TGT to authenticate itself to the TGS in the same
+manner as if it were contacting any other application server
+that requires Kerberos authentication. The reply is
+encrypted in the session key from the TGT. Though the pro-
+tocol specification describes the AS and the TGS as separate
+servers, they are implemented in practice as different pro-
+tocol entry points within a single Kerberos server.
+
+ Once obtained, credentials may be used to verify the
+identity of the principals in a transaction, to ensure the
+integrity of messages exchanged between them, or to preserve
+privacy of the messages. The application is free to choose
+whatever protection may be necessary.
+
+ To verify the identities of the principals in a tran-
+saction, the client transmits the ticket to the application
+server. Since the ticket is sent "in the clear" (parts of
+it are encrypted, but this encryption doesn't thwart replay)
+and might be intercepted and reused by an attacker, addi-
+tional information is sent to prove that the message ori-
+ginated with the principal to whom the ticket was issued.
+This information (called the authenticator) is encrypted in
+the session key, and includes a timestamp. The timestamp
+proves that the message was recently generated and is not a
+replay. Encrypting the authenticator in the session key
+proves that it was generated by a party possessing the ses-
+sion key. Since no one except the requesting principal and
+
+
+Section 1. - 4 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+the server know the session key (it is never sent over the
+network in the clear) this guarantees the identity of the
+client.
+
+ The integrity of the messages exchanged between princi-
+pals can also be guaranteed using the session key (passed in
+the ticket and contained in the credentials). This approach
+provides detection of both replay attacks and message stream
+modification attacks. It is accomplished by generating and
+transmitting a collision-proof checksum (elsewhere called a
+hash or digest function) of the client's message, keyed with
+the session key. Privacy and integrity of the messages
+exchanged between principals can be secured by encrypting
+the data to be passed using the session key contained in the
+ticket or the subsession key found in the authenticator.
+
+ The authentication exchanges mentioned above require
+read-only access to the Kerberos database. Sometimes, how-
+ever, the entries in the database must be modified, such as
+when adding new principals or changing a principal's key.
+This is done using a protocol between a client and a third
+Kerberos server, the Kerberos Administration Server (KADM).
+There is also a protocol for maintaining multiple copies of
+the Kerberos database. Neither of these protocols are
+described in this document.
+
+1.1. Cross-Realm Operation
+
+ The Kerberos protocol is designed to operate across
+organizational boundaries. A client in one organization can
+be authenticated to a server in another. Each organization
+wishing to run a Kerberos server establishes its own
+"realm". The name of the realm in which a client is
+registered is part of the client's name, and can be used by
+the end-service to decide whether to honor a request.
+
+ By establishing "inter-realm" keys, the administrators
+of two realms can allow a client authenticated in the local
+realm to prove its identity to servers in other realms[3].
+The exchange of inter-realm keys (a separate key may be used
+for each direction) registers the ticket-granting service of
+each realm as a principal in the other realm. A client is
+then able to obtain a ticket-granting ticket for the remote
+realm's ticket-granting service from its local realm. When
+that ticket-granting ticket is used, the remote ticket-
+granting service uses the inter-realm key (which usually
+__________________________
+[3] Of course, with appropriate permission the client
+could arrange registration of a separately-named prin-
+cipal in a remote realm, and engage in normal exchanges
+with that realm's services. However, for even small
+numbers of clients this becomes cumbersome, and more
+automatic methods as described here are necessary.
+
+
+Section 1.1. - 5 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+differs from its own normal TGS key) to decrypt the ticket-
+granting ticket, and is thus certain that it was issued by
+the client's own TGS. Tickets issued by the remote ticket-
+granting service will indicate to the end-service that the
+client was authenticated from another realm.
+
+ A realm is said to communicate with another realm if
+the two realms share an inter-realm key, or if the local
+realm shares an inter-realm key with an intermediate realm
+that communicates with the remote realm. An authentication
+path is the sequence of intermediate realms that are tran-
+sited in communicating from one realm to another.
+
+ Realms are typically organized hierarchically. Each
+realm shares a key with its parent and a different key with
+each child. If an inter-realm key is not directly shared by
+two realms, the hierarchical organization allows an authen-
+tication path to be easily constructed. If a hierarchical
+organization is not used, it may be necessary to consult a
+database in order to construct an authentication path
+between realms.
+
+ Although realms are typically hierarchical, intermedi-
+ate realms may be bypassed to achieve cross-realm authenti-
+cation through alternate authentication paths (these might
+be established to make communication between two realms more
+efficient). It is important for the end-service to know
+which realms were transited when deciding how much faith to
+place in the authentication process. To facilitate this
+decision, a field in each ticket contains the names of the
+realms that were involved in authenticating the client.
+
+1.2. Authorization
+
+As an authentication service, Kerberos provides a means of
+verifying the identity of principals on a network. Authen-
+tication is usually useful primarily as a first step in the
+process of authorization, determining whether a client may
+use a service, which objects the client is allowed to
+access, and the type of access allowed for each. Kerberos
+does not, by itself, provide authorization. Possession of a
+client ticket for a service provides only for authentication
+of the client to that service, and in the absence of a
+separate authorization procedure, it should not be con-
+sidered by an application as authorizing the use of that
+service.
+
+ Such separate authorization methods may be implemented
+as application specific access control functions and may be
+based on files such as the application server, or on
+separately issued authorization credentials such as those
+based on proxies [7] , or on other authorization services.
+
+ Applications should not be modified to accept the
+issuance of a service ticket by the Kerberos server (even by
+
+Section 1.2. - 6 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+an modified Kerberos server) as granting authority to use
+the service, since such applications may become vulnerable
+to the bypass of this authorization check in an environment
+where they interoperate with other KDCs or where other
+options for application authentication (e.g. the PKTAPP pro-
+posal) are provided.
+
+1.3. Environmental assumptions
+
+Kerberos imposes a few assumptions on the environment in
+which it can properly function:
+
++ "Denial of service" attacks are not solved with Ker-
+ beros. There are places in these protocols where an
+ intruder can prevent an application from participating
+ in the proper authentication steps. Detection and
+ solution of such attacks (some of which can appear to
+ be not-uncommon "normal" failure modes for the system)
+ is usually best left to the human administrators and
+ users.
+
++ Principals must keep their secret keys secret. If an
+ intruder somehow steals a principal's key, it will be
+ able to masquerade as that principal or impersonate any
+ server to the legitimate principal.
+
++ "Password guessing" attacks are not solved by Kerberos.
+ If a user chooses a poor password, it is possible for
+ an attacker to successfully mount an offline dictionary
+ attack by repeatedly attempting to decrypt, with suc-
+ cessive entries from a dictionary, messages obtained
+ which are encrypted under a key derived from the user's
+ password.
+
++ Each host on the network must have a clock which is
+ "loosely synchronized" to the time of the other hosts;
+ this synchronization is used to reduce the bookkeeping
+ needs of application servers when they do replay detec-
+ tion. The degree of "looseness" can be configured on a
+ per-server basis, but is typically on the order of 5
+ minutes. If the clocks are synchronized over the net-
+ work, the clock synchronization protocol must itself be
+ secured from network attackers.
+
++ Principal identifiers are not recycled on a short-term
+ basis. A typical mode of access control will use
+ access control lists (ACLs) to grant permissions to
+ particular principals. If a stale ACL entry remains
+ for a deleted principal and the principal identifier is
+ reused, the new principal will inherit rights specified
+ in the stale ACL entry. By not re-using principal
+ identifiers, the danger of inadvertent access is
+ removed.
+
+
+
+Section 1.3. - 7 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+1.4. Glossary of terms
+
+Below is a list of terms used throughout this document.
+
+
+Authentication Verifying the claimed identity of a
+ principal.
+
+
+Authentication headerA record containing a Ticket and an
+ Authenticator to be presented to a
+ server as part of the authentication
+ process.
+
+
+Authentication path A sequence of intermediate realms tran-
+ sited in the authentication process when
+ communicating from one realm to another.
+
+
+Authenticator A record containing information that can
+ be shown to have been recently generated
+ using the session key known only by the
+ client and server.
+
+
+Authorization The process of determining whether a
+ client may use a service, which objects
+ the client is allowed to access, and the
+ type of access allowed for each.
+
+
+Capability A token that grants the bearer permis-
+ sion to access an object or service. In
+ Kerberos, this might be a ticket whose
+ use is restricted by the contents of the
+ authorization data field, but which
+ lists no network addresses, together
+ with the session key necessary to use
+ the ticket.
+
+
+Ciphertext The output of an encryption function.
+ Encryption transforms plaintext into
+ ciphertext.
+
+
+Client A process that makes use of a network
+ service on behalf of a user. Note that
+ in some cases a Server may itself be a
+ client of some other server (e.g. a
+ print server may be a client of a file
+ server).
+
+
+
+Section 1.4. - 8 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+Credentials A ticket plus the secret session key
+ necessary to successfully use that
+ ticket in an authentication exchange.
+
+
+KDC Key Distribution Center, a network ser-
+ vice that supplies tickets and temporary
+ session keys; or an instance of that
+ service or the host on which it runs.
+ The KDC services both initial ticket and
+ ticket-granting ticket requests. The
+ initial ticket portion is sometimes
+ referred to as the Authentication Server
+ (or service). The ticket-granting
+ ticket portion is sometimes referred to
+ as the ticket-granting server (or ser-
+ vice).
+
+
+Kerberos Aside from the 3-headed dog guarding
+ Hades, the name given to Project
+ Athena's authentication service, the
+ protocol used by that service, or the
+ code used to implement the authentica-
+ tion service.
+
+
+Plaintext The input to an encryption function or
+ the output of a decryption function.
+ Decryption transforms ciphertext into
+ plaintext.
+
+
+Principal A uniquely named client or server
+ instance that participates in a network
+ communication.
+
+
+Principal identifierThe name used to uniquely identify each
+ different principal.
+
+
+Seal To encipher a record containing several
+ fields in such a way that the fields
+ cannot be individually replaced without
+ either knowledge of the encryption key
+ or leaving evidence of tampering.
+
+
+Secret key An encryption key shared by a principal
+ and the KDC, distributed outside the
+ bounds of the system, with a long life-
+ time. In the case of a human user's
+ principal, the secret key is derived
+
+
+Section 1.4. - 9 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ from a password.
+
+
+Server A particular Principal which provides a
+ resource to network clients. The server
+ is sometimes refered to as the Applica-
+ tion Server.
+
+
+Service A resource provided to network clients;
+ often provided by more than one server
+ (for example, remote file service).
+
+
+Session key A temporary encryption key used between
+ two principals, with a lifetime limited
+ to the duration of a single login "ses-
+ sion".
+
+
+Sub-session key A temporary encryption key used between
+ two principals, selected and exchanged
+ by the principals using the session key,
+ and with a lifetime limited to the dura-
+ tion of a single association.
+
+
+Ticket A record that helps a client authenti-
+ cate itself to a server; it contains the
+ client's identity, a session key, a
+ timestamp, and other information, all
+ sealed using the server's secret key.
+ It only serves to authenticate a client
+ when presented along with a fresh
+ Authenticator.
+
+2. Ticket flag uses and requests
+
+Each Kerberos ticket contains a set of flags which are used
+to indicate various attributes of that ticket. Most flags
+may be requested by a client when the ticket is obtained;
+some are automatically turned on and off by a Kerberos
+server as required. The following sections explain what the
+various flags mean, and gives examples of reasons to use
+such a flag.
+
+2.1. Initial and pre-authenticated tickets
+
+ The INITIAL flag indicates that a ticket was issued
+using the AS protocol and not issued based on a ticket-
+granting ticket. Application servers that want to require
+the demonstrated knowledge of a client's secret key (e.g. a
+password-changing program) can insist that this flag be set
+in any tickets they accept, and thus be assured that the
+
+
+Section 2.1. - 10 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+client's key was recently presented to the application
+client.
+
+ The PRE-AUTHENT and HW-AUTHENT flags provide addition
+information about the initial authentication, regardless of
+whether the current ticket was issued directly (in which
+case INITIAL will also be set) or issued on the basis of a
+ticket-granting ticket (in which case the INITIAL flag is
+clear, but the PRE-AUTHENT and HW-AUTHENT flags are carried
+forward from the ticket-granting ticket).
+
+2.2. Invalid tickets
+
+ The INVALID flag indicates that a ticket is invalid.
+Application servers must reject tickets which have this flag
+set. A postdated ticket will usually be issued in this
+form. Invalid tickets must be validated by the KDC before
+use, by presenting them to the KDC in a TGS request with the
+VALIDATE option specified. The KDC will only validate tick-
+ets after their starttime has passed. The validation is
+required so that postdated tickets which have been stolen
+before their starttime can be rendered permanently invalid
+(through a hot-list mechanism) (see section 3.3.3.1).
+
+2.3. Renewable tickets
+
+ Applications may desire to hold tickets which can be
+valid for long periods of time. However, this can expose
+their credentials to potential theft for equally long
+periods, and those stolen credentials would be valid until
+the expiration time of the ticket(s). Simply using short-
+lived tickets and obtaining new ones periodically would
+require the client to have long-term access to its secret
+key, an even greater risk. Renewable tickets can be used to
+mitigate the consequences of theft. Renewable tickets have
+two "expiration times": the first is when the current
+instance of the ticket expires, and the second is the latest
+permissible value for an individual expiration time. An
+application client must periodically (i.e. before it
+expires) present a renewable ticket to the KDC, with the
+RENEW option set in the KDC request. The KDC will issue a
+new ticket with a new session key and a later expiration
+time. All other fields of the ticket are left unmodified by
+the renewal process. When the latest permissible expiration
+time arrives, the ticket expires permanently. At each
+renewal, the KDC may consult a hot-list to determine if the
+ticket had been reported stolen since its last renewal; it
+will refuse to renew such stolen tickets, and thus the
+usable lifetime of stolen tickets is reduced.
+
+ The RENEWABLE flag in a ticket is normally only inter-
+preted by the ticket-granting service (discussed below in
+section 3.3). It can usually be ignored by application
+servers. However, some particularly careful application
+
+
+Section 2.3. - 11 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+servers may wish to disallow renewable tickets.
+
+ If a renewable ticket is not renewed by its expiration
+time, the KDC will not renew the ticket. The RENEWABLE flag
+is reset by default, but a client may request it be set by
+setting the RENEWABLE option in the KRB_AS_REQ message. If
+it is set, then the renew-till field in the ticket contains
+the time after which the ticket may not be renewed.
+
+2.4. Postdated tickets
+
+ Applications may occasionally need to obtain tickets
+for use much later, e.g. a batch submission system would
+need tickets to be valid at the time the batch job is ser-
+viced. However, it is dangerous to hold valid tickets in a
+batch queue, since they will be on-line longer and more
+prone to theft. Postdated tickets provide a way to obtain
+these tickets from the KDC at job submission time, but to
+leave them "dormant" until they are activated and validated
+by a further request of the KDC. If a ticket theft were
+reported in the interim, the KDC would refuse to validate
+the ticket, and the thief would be foiled.
+
+ The MAY-POSTDATE flag in a ticket is normally only
+interpreted by the ticket-granting service. It can be
+ignored by application servers. This flag must be set in a
+ticket-granting ticket in order to issue a postdated ticket
+based on the presented ticket. It is reset by default; it
+may be requested by a client by setting the ALLOW-POSTDATE
+option in the KRB_AS_REQ message. This flag does not allow
+a client to obtain a postdated ticket-granting ticket; post-
+dated ticket-granting tickets can only by obtained by
+requesting the postdating in the KRB_AS_REQ message. The
+life (endtime-starttime) of a postdated ticket will be the
+remaining life of the ticket-granting ticket at the time of
+the request, unless the RENEWABLE option is also set, in
+which case it can be the full life (endtime-starttime) of
+the ticket-granting ticket. The KDC may limit how far in
+the future a ticket may be postdated.
+
+ The POSTDATED flag indicates that a ticket has been
+postdated. The application server can check the authtime
+field in the ticket to see when the original authentication
+occurred. Some services may choose to reject postdated
+tickets, or they may only accept them within a certain
+period after the original authentication. When the KDC
+issues a POSTDATED ticket, it will also be marked as
+INVALID, so that the application client must present the
+ticket to the KDC to be validated before use.
+
+2.5. Proxiable and proxy tickets
+
+ At times it may be necessary for a principal to allow a
+service to perform an operation on its behalf. The service
+
+
+Section 2.5. - 12 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+must be able to take on the identity of the client, but only
+for a particular purpose. A principal can allow a service
+to take on the principal's identity for a particular purpose
+by granting it a proxy.
+
+ The process of granting a proxy using the proxy and
+proxiable flags is used to provide credentials for use with
+specific services. Though conceptually also a proxy, user's
+wishing to delegate their identity for ANY purpose must use
+the ticket forwarding mechanism described in the next sec-
+tion to forward a ticket granting ticket.
+
+ The PROXIABLE flag in a ticket is normally only inter-
+preted by the ticket-granting service. It can be ignored by
+application servers. When set, this flag tells the ticket-
+granting server that it is OK to issue a new ticket (but not
+a ticket-granting ticket) with a different network address
+based on this ticket. This flag is set if requested by the
+client on initial authentication. By default, the client
+will request that it be set when requesting a ticket grant-
+ing ticket, and reset when requesting any other ticket.
+
+ This flag allows a client to pass a proxy to a server
+to perform a remote request on its behalf, e.g. a print ser-
+vice client can give the print server a proxy to access the
+client's files on a particular file server in order to
+satisfy a print request.
+
+ In order to complicate the use of stolen credentials,
+Kerberos tickets are usually valid from only those network
+addresses specifically included in the ticket[4]. When
+granting a proxy, the client must specify the new network
+address from which the proxy is to be used, or indicate that
+the proxy is to be issued for use from any address.
+
+ The PROXY flag is set in a ticket by the TGS when it
+issues a proxy ticket. Application servers may check this
+flag and at their option they may require additional authen-
+tication from the agent presenting the proxy in order to
+provide an audit trail.
+
+2.6. Forwardable tickets
+
+ Authentication forwarding is an instance of a proxy
+where the service is granted complete use of the client's
+identity. An example where it might be used is when a user
+logs in to a remote system and wants authentication to work
+from that system as if the login were local.
+
+ The FORWARDABLE flag in a ticket is normally only
+__________________________
+[4] Though it is permissible to request or issue tick-
+ets with no network addresses specified.
+
+
+Section 2.6. - 13 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+interpreted by the ticket-granting service. It can be
+ignored by application servers. The FORWARDABLE flag has an
+interpretation similar to that of the PROXIABLE flag, except
+ticket-granting tickets may also be issued with different
+network addresses. This flag is reset by default, but users
+may request that it be set by setting the FORWARDABLE option
+in the AS request when they request their initial ticket-
+granting ticket.
+
+ This flag allows for authentication forwarding without
+requiring the user to enter a password again. If the flag
+is not set, then authentication forwarding is not permitted,
+but the same result can still be achieved if the user
+engages in the AS exchange specifying the requested network
+addresses and supplies a password.
+
+ The FORWARDED flag is set by the TGS when a client
+presents a ticket with the FORWARDABLE flag set and requests
+a forwarded ticket by specifying the FORWARDED KDC option
+and supplying a set of addresses for the new ticket. It is
+also set in all tickets issued based on tickets with the
+FORWARDED flag set. Application servers may choose to pro-
+cess FORWARDED tickets differently than non-FORWARDED tick-
+ets.
+
+2.7. Other KDC options
+
+ There are two additional options which may be set in a
+client's request of the KDC. The RENEWABLE-OK option indi-
+cates that the client will accept a renewable ticket if a
+ticket with the requested life cannot otherwise be provided.
+If a ticket with the requested life cannot be provided, then
+the KDC may issue a renewable ticket with a renew-till equal
+to the the requested endtime. The value of the renew-till
+field may still be adjusted by site-determined limits or
+limits imposed by the individual principal or server.
+
+ The ENC-TKT-IN-SKEY option is honored only by the
+ticket-granting service. It indicates that the ticket to be
+issued for the end server is to be encrypted in the session
+key from the a additional second ticket-granting ticket pro-
+vided with the request. See section 3.3.3 for specific
+details.
+
+__________________________
+[5] The password-changing request must not be honored
+unless the requester can provide the old password (the
+user's current secret key). Otherwise, it would be
+possible for someone to walk up to an unattended ses-
+sion and change another user's password.
+[6] To authenticate a user logging on to a local sys-
+tem, the credentials obtained in the AS exchange may
+first be used in a TGS exchange to obtain credentials
+
+
+Section 3.1. - 14 - Expires 11 January 1998
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+
+3. Message Exchanges
+
+The following sections describe the interactions between
+network clients and servers and the messages involved in
+those exchanges.
+
+3.1. The Authentication Service Exchange
+
+ Summary
+ Message direction Message type Section
+ 1. Client to Kerberos KRB_AS_REQ 5.4.1
+ 2. Kerberos to client KRB_AS_REP or 5.4.2
+ KRB_ERROR 5.9.1
+
+
+ The Authentication Service (AS) Exchange between the
+client and the Kerberos Authentication Server is initiated
+by a client when it wishes to obtain authentication creden-
+tials for a given server but currently holds no credentials.
+In its basic form, the client's secret key is used for en-
+cryption and decryption. This exchange is typically used at
+the initiation of a login session to obtain credentials for
+a Ticket-Granting Server which will subsequently be used to
+obtain credentials for other servers (see section 3.3)
+without requiring further use of the client's secret key.
+This exchange is also used to request credentials for ser-
+vices which must not be mediated through the Ticket-Granting
+Service, but rather require a principal's secret key, such
+as the password-changing service[5]. This exchange does not
+by itself provide any assurance of the the identity of the
+user[6].
+
+ The exchange consists of two messages: KRB_AS_REQ from
+the client to Kerberos, and KRB_AS_REP or KRB_ERROR in
+reply. The formats for these messages are described in sec-
+tions 5.4.1, 5.4.2, and 5.9.1.
+
+ In the request, the client sends (in cleartext) its own
+identity and the identity of the server for which it is
+requesting credentials. The response, KRB_AS_REP, contains
+a ticket for the client to present to the server, and a ses-
+sion key that will be shared by the client and the server.
+The session key and additional information are encrypted in
+the client's secret key. The KRB_AS_REP message contains
+information which can be used to detect replays, and to
+associate it with the message to which it replies. Various
+errors can occur; these are indicated by an error response
+(KRB_ERROR) instead of the KRB_AS_REP response. The error
+__________________________
+for a local server. Those credentials must then be
+verified by a local server through successful comple-
+tion of the Client/Server exchange.
+
+
+
+Section 3.1. - 15 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+message is not encrypted. The KRB_ERROR message contains
+information which can be used to associate it with the mes-
+sage to which it replies. The lack of encryption in the
+KRB_ERROR message precludes the ability to detect replays,
+fabrications, or modifications of such messages.
+
+ Without preautentication, the authentication server
+does not know whether the client is actually the principal
+named in the request. It simply sends a reply without know-
+ing or caring whether they are the same. This is acceptable
+because nobody but the principal whose identity was given in
+the request will be able to use the reply. Its critical
+information is encrypted in that principal's key. The ini-
+tial request supports an optional field that can be used to
+pass additional information that might be needed for the
+initial exchange. This field may be used for pre-
+authentication as described in section <<sec preauth>>.
+
+3.1.1. Generation of KRB_AS_REQ message
+
+ The client may specify a number of options in the ini-
+tial request. Among these options are whether pre-
+authentication is to be performed; whether the requested
+ticket is to be renewable, proxiable, or forwardable;
+whether it should be postdated or allow postdating of
+derivative tickets; and whether a renewable ticket will be
+accepted in lieu of a non-renewable ticket if the requested
+ticket expiration date cannot be satisfied by a non-
+renewable ticket (due to configuration constraints; see sec-
+tion 4). See section A.1 for pseudocode.
+
+ The client prepares the KRB_AS_REQ message and sends it
+to the KDC.
+
+3.1.2. Receipt of KRB_AS_REQ message
+
+ If all goes well, processing the KRB_AS_REQ message
+will result in the creation of a ticket for the client to
+present to the server. The format for the ticket is
+described in section 5.3.1. The contents of the ticket are
+determined as follows.
+
+3.1.3. Generation of KRB_AS_REP message
+
+ The authentication server looks up the client and
+server principals named in the KRB_AS_REQ in its database,
+extracting their respective keys. If required, the server
+pre-authenticates the request, and if the pre-authentication
+check fails, an error message with the code
+KDC_ERR_PREAUTH_FAILED is returned. If the server cannot
+accommodate the requested encryption type, an error message
+with code KDC_ERR_ETYPE_NOSUPP is returned. Otherwise it
+generates a "random" session key[7].
+__________________________
+
+
+Section 3.1.3. - 16 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ If there are multiple encryption keys registered for a
+client in the Kerberos database (or if the key registered
+supports multiple encryption types; e.g. DES-CBC-CRC and
+DES-CBC-MD5), then the etype field from the AS request is
+used by the KDC to select the encryption method to be used
+for encrypting the response to the client. If there is more
+than one supported, strong encryption type in the etype
+list, the first valid etype for which an encryption key is
+available is used. The encryption method used to respond to
+a TGS request is taken from the keytype of the session key
+found in the ticket granting ticket.
+
+ When the etype field is present in a KDC request,
+whether an AS or TGS request, the KDC will attempt to assign
+the type of the random session key from the list of methods
+in the etype field. The KDC will select the appropriate
+type using the list of methods provided together with infor-
+mation from the Kerberos database indicating acceptable
+encryption methods for the application server. The KDC will
+not issue tickets with a weak session key encryption type.
+
+ If the requested start time is absent, indicates a time
+in the past, or is within the window of acceptable clock
+skew for the KDC and the POSTDATE option has not been speci-
+fied, then the start time of the ticket is set to the
+authentication server's current time. If it indicates a
+time in the future beyond the acceptable clock skew, but the
+POSTDATED option has not been specified then the error
+KDC_ERR_CANNOT_POSTDATE is returned. Otherwise the
+requested start time is checked against the policy of the
+local realm (the administrator might decide to prohibit cer-
+tain types or ranges of postdated tickets), and if accept-
+able, the ticket's start time is set as requested and the
+INVALID flag is set in the new ticket. The postdated ticket
+must be validated before use by presenting it to the KDC
+after the start time has been reached.
+
+
+
+
+
+
+
+
+
+__________________________
+[7] "Random" means that, among other things, it should
+be impossible to guess the next session key based on
+knowledge of past session keys. This can only be
+achieved in a pseudo-random number generator if it is
+based on cryptographic principles. It is more desir-
+able to use a truly random number generator, such as
+one based on measurements of random physical phenomena.
+
+
+
+Section 3.1.3. - 17 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+The expiration time of the ticket will be set to the minimum
+of the following:
+
++The expiration time (endtime) requested in the KRB_AS_REQ
+ message.
+
++The ticket's start time plus the maximum allowable lifetime
+ associated with the client principal (the authentication
+ server's database includes a maximum ticket lifetime field
+ in each principal's record; see section 4).
+
++The ticket's start time plus the maximum allowable lifetime
+ associated with the server principal.
+
++The ticket's start time plus the maximum lifetime set by
+ the policy of the local realm.
+
+ If the requested expiration time minus the start time
+(as determined above) is less than a site-determined minimum
+lifetime, an error message with code KDC_ERR_NEVER_VALID is
+returned. If the requested expiration time for the ticket
+exceeds what was determined as above, and if the
+"RENEWABLE-OK" option was requested, then the "RENEWABLE"
+flag is set in the new ticket, and the renew-till value is
+set as if the "RENEWABLE" option were requested (the field
+and option names are described fully in section 5.4.1).
+
+If the RENEWABLE option has been requested or if the
+RENEWABLE-OK option has been set and a renewable ticket is
+to be issued, then the renew-till field is set to the
+minimum of:
+
++Its requested value.
+
++The start time of the ticket plus the minimum of the two
+ maximum renewable lifetimes associated with the principals'
+ database entries.
+
++The start time of the ticket plus the maximum renewable
+ lifetime set by the policy of the local realm.
+
+ The flags field of the new ticket will have the follow-
+ing options set if they have been requested and if the pol-
+icy of the local realm allows: FORWARDABLE, MAY-POSTDATE,
+POSTDATED, PROXIABLE, RENEWABLE. If the new ticket is post-
+dated (the start time is in the future), its INVALID flag
+will also be set.
+
+ If all of the above succeed, the server formats a
+KRB_AS_REP message (see section 5.4.2), copying the
+addresses in the request into the caddr of the response,
+placing any required pre-authentication data into the padata
+of the response, and encrypts the ciphertext part in the
+client's key using the requested encryption method, and
+
+
+Section 3.1.3. - 18 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+sends it to the client. See section A.2 for pseudocode.
+
+3.1.4. Generation of KRB_ERROR message
+
+ Several errors can occur, and the Authentication Server
+responds by returning an error message, KRB_ERROR, to the
+client, with the error-code and e-text fields set to
+appropriate values. The error message contents and details
+are described in Section 5.9.1.
+
+3.1.5. Receipt of KRB_AS_REP message
+
+ If the reply message type is KRB_AS_REP, then the
+client verifies that the cname and crealm fields in the
+cleartext portion of the reply match what it requested. If
+any padata fields are present, they may be used to derive
+the proper secret key to decrypt the message. The client
+decrypts the encrypted part of the response using its secret
+key, verifies that the nonce in the encrypted part matches
+the nonce it supplied in its request (to detect replays).
+It also verifies that the sname and srealm in the response
+match those in the request (or are otherwise expected
+values), and that the host address field is also correct.
+It then stores the ticket, session key, start and expiration
+times, and other information for later use. The key-
+expiration field from the encrypted part of the response may
+be checked to notify the user of impending key expiration
+(the client program could then suggest remedial action, such
+as a password change). See section A.3 for pseudocode.
+
+ Proper decryption of the KRB_AS_REP message is not suf-
+ficient to verify the identity of the user; the user and an
+attacker could cooperate to generate a KRB_AS_REP format
+message which decrypts properly but is not from the proper
+KDC. If the host wishes to verify the identity of the user,
+it must require the user to present application credentials
+which can be verified using a securely-stored secret key for
+the host. If those credentials can be verified, then the
+identity of the user can be assured.
+
+3.1.6. Receipt of KRB_ERROR message
+
+ If the reply message type is KRB_ERROR, then the client
+interprets it as an error and performs whatever
+application-specific tasks are necessary to recover.
+
+3.2. The Client/Server Authentication Exchange
+
+ Summary
+Message direction Message type Section
+Client to Application server KRB_AP_REQ 5.5.1
+[optional] Application server to client KRB_AP_REP or 5.5.2
+ KRB_ERROR 5.9.1
+
+
+
+Section 3.2. - 19 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ The client/server authentication (CS) exchange is used
+by network applications to authenticate the client to the
+server and vice versa. The client must have already
+acquired credentials for the server using the AS or TGS
+exchange.
+
+3.2.1. The KRB_AP_REQ message
+
+ The KRB_AP_REQ contains authentication information
+which should be part of the first message in an authenti-
+cated transaction. It contains a ticket, an authenticator,
+and some additional bookkeeping information (see section
+5.5.1 for the exact format). The ticket by itself is insuf-
+ficient to authenticate a client, since tickets are passed
+across the network in cleartext[8], so the authenticator is
+used to prevent invalid replay of tickets by proving to the
+server that the client knows the session key of the ticket
+and thus is entitled to use the ticket. The KRB_AP_REQ mes-
+sage is referred to elsewhere as the "authentication
+header."
+
+3.2.2. Generation of a KRB_AP_REQ message
+
+ When a client wishes to initiate authentication to a
+server, it obtains (either through a credentials cache, the
+AS exchange, or the TGS exchange) a ticket and session key
+for the desired service. The client may re-use any tickets
+it holds until they expire. To use a ticket the client con-
+structs a new Authenticator from the the system time, its
+name, and optionally an application specific checksum, an
+initial sequence number to be used in KRB_SAFE or KRB_PRIV
+messages, and/or a session subkey to be used in negotiations
+for a session key unique to this particular session.
+Authenticators may not be re-used and will be rejected if
+replayed to a server[9]. If a sequence number is to be
+included, it should be randomly chosen so that even after
+many messages have been exchanged it is not likely to col-
+lide with other sequence numbers in use.
+
+ The client may indicate a requirement of mutual
+__________________________
+[8] Tickets contain both an encrypted and unencrypted
+portion, so cleartext here refers to the entire unit,
+which can be copied from one message and replayed in
+another without any cryptographic skill.
+[9] Note that this can make applications based on un-
+reliable transports difficult to code correctly. If the
+transport might deliver duplicated messages, either a
+new authenticator must be generated for each retry, or
+the application server must match requests and replies
+and replay the first reply in response to a detected
+duplicate.
+
+
+
+Section 3.2.2. - 20 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+authentication or the use of a session-key based ticket by
+setting the appropriate flag(s) in the ap-options field of
+the message.
+
+ The Authenticator is encrypted in the session key and
+combined with the ticket to form the KRB_AP_REQ message
+which is then sent to the end server along with any addi-
+tional application-specific information. See section A.9
+for pseudocode.
+
+3.2.3. Receipt of KRB_AP_REQ message
+
+ Authentication is based on the server's current time of
+day (clocks must be loosely synchronized), the authentica-
+tor, and the ticket. Several errors are possible. If an
+error occurs, the server is expected to reply to the client
+with a KRB_ERROR message. This message may be encapsulated
+in the application protocol if its "raw" form is not accept-
+able to the protocol. The format of error messages is
+described in section 5.9.1.
+
+ The algorithm for verifying authentication information
+is as follows. If the message type is not KRB_AP_REQ, the
+server returns the KRB_AP_ERR_MSG_TYPE error. If the key
+version indicated by the Ticket in the KRB_AP_REQ is not one
+the server can use (e.g., it indicates an old key, and the
+server no longer possesses a copy of the old key), the
+KRB_AP_ERR_BADKEYVER error is returned. If the USE-
+SESSION-KEY flag is set in the ap-options field, it indi-
+cates to the server that the ticket is encrypted in the ses-
+sion key from the server's ticket-granting ticket rather
+than its secret key[10]. Since it is possible for the
+server to be registered in multiple realms, with different
+keys in each, the srealm field in the unencrypted portion of
+the ticket in the KRB_AP_REQ is used to specify which secret
+key the server should use to decrypt that ticket. The
+KRB_AP_ERR_NOKEY error code is returned if the server
+doesn't have the proper key to decipher the ticket.
+
+ The ticket is decrypted using the version of the
+server's key specified by the ticket. If the decryption
+routines detect a modification of the ticket (each encryp-
+tion system must provide safeguards to detect modified
+ciphertext; see section 6), the KRB_AP_ERR_BAD_INTEGRITY
+error is returned (chances are good that different keys were
+used to encrypt and decrypt).
+
+ The authenticator is decrypted using the session key
+extracted from the decrypted ticket. If decryption shows it
+to have been modified, the KRB_AP_ERR_BAD_INTEGRITY error is
+__________________________
+[10] This is used for user-to-user authentication as
+described in [8].
+
+
+Section 3.2.3. - 21 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+returned. The name and realm of the client from the ticket
+are compared against the same fields in the authenticator.
+If they don't match, the KRB_AP_ERR_BADMATCH error is
+returned (they might not match, for example, if the wrong
+session key was used to encrypt the authenticator). The
+addresses in the ticket (if any) are then searched for an
+address matching the operating-system reported address of
+the client. If no match is found or the server insists on
+ticket addresses but none are present in the ticket, the
+KRB_AP_ERR_BADADDR error is returned.
+
+ If the local (server) time and the client time in the
+authenticator differ by more than the allowable clock skew
+(e.g., 5 minutes), the KRB_AP_ERR_SKEW error is returned.
+If the server name, along with the client name, time and
+microsecond fields from the Authenticator match any
+recently-seen such tuples, the KRB_AP_ERR_REPEAT error is
+returned[11]. The server must remember any authenticator
+presented within the allowable clock skew, so that a replay
+attempt is guaranteed to fail. If a server loses track of
+any authenticator presented within the allowable clock skew,
+it must reject all requests until the clock skew interval
+has passed. This assures that any lost or re-played authen-
+ticators will fall outside the allowable clock skew and can
+no longer be successfully replayed (If this is not done, an
+attacker could conceivably record the ticket and authentica-
+tor sent over the network to a server, then disable the
+client's host, pose as the disabled host, and replay the
+ticket and authenticator to subvert the authentication.).
+If a sequence number is provided in the authenticator, the
+server saves it for later use in processing KRB_SAFE and/or
+KRB_PRIV messages. If a subkey is present, the server
+either saves it for later use or uses it to help generate
+its own choice for a subkey to be returned in a KRB_AP_REP
+message.
+
+ The server computes the age of the ticket: local
+(server) time minus the start time inside the Ticket. If
+the start time is later than the current time by more than
+the allowable clock skew or if the INVALID flag is set in
+the ticket, the KRB_AP_ERR_TKT_NYV error is returned. Oth-
+erwise, if the current time is later than end time by more
+than the allowable clock skew, the KRB_AP_ERR_TKT_EXPIRED
+error is returned.
+
+ If all these checks succeed without an error, the
+__________________________
+[11] Note that the rejection here is restricted to au-
+thenticators from the same principal to the same
+server. Other client principals communicating with the
+same server principal should not be have their authen-
+ticators rejected if the time and microsecond fields
+happen to match some other client's authenticator.
+
+
+Section 3.2.3. - 22 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+server is assured that the client possesses the credentials
+of the principal named in the ticket and thus, the client
+has been authenticated to the server. See section A.10 for
+pseudocode.
+
+ Passing these checks provides only authentication of
+the named principal; it does not imply authorization to use
+the named service. Applications must make a separate
+authorization decisions based upon the authenticated name of
+the user, the requested operation, local acces control
+information such as that contained in a .k5login or .k5users
+file, and possibly a separate distributed authorization ser-
+vice.
+
+3.2.4. Generation of a KRB_AP_REP message
+
+ Typically, a client's request will include both the
+authentication information and its initial request in the
+same message, and the server need not explicitly reply to
+the KRB_AP_REQ. However, if mutual authentication (not only
+authenticating the client to the server, but also the server
+to the client) is being performed, the KRB_AP_REQ message
+will have MUTUAL-REQUIRED set in its ap-options field, and a
+KRB_AP_REP message is required in response. As with the
+error message, this message may be encapsulated in the
+application protocol if its "raw" form is not acceptable to
+the application's protocol. The timestamp and microsecond
+field used in the reply must be the client's timestamp and
+microsecond field (as provided in the authenticator)[12].
+If a sequence number is to be included, it should be ran-
+domly chosen as described above for the authenticator. A
+subkey may be included if the server desires to negotiate a
+different subkey. The KRB_AP_REP message is encrypted in
+the session key extracted from the ticket. See section A.11
+for pseudocode.
+
+3.2.5. Receipt of KRB_AP_REP message
+
+
+ If a KRB_AP_REP message is returned, the client uses
+the session key from the credentials obtained for the
+server[13] to decrypt the message, and verifies that the
+__________________________
+[12] In the Kerberos version 4 protocol, the timestamp
+in the reply was the client's timestamp plus one. This
+is not necessary in version 5 because version 5 mes-
+sages are formatted in such a way that it is not possi-
+ble to create the reply by judicious message surgery
+(even in encrypted form) without knowledge of the ap-
+propriate encryption keys.
+[13] Note that for encrypting the KRB_AP_REP message,
+the sub-session key is not used, even if present in the
+Authenticator.
+
+
+Section 3.2.5. - 23 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+timestamp and microsecond fields match those in the Authen-
+ticator it sent to the server. If they match, then the
+client is assured that the server is genuine. The sequence
+number and subkey (if present) are retained for later use.
+See section A.12 for pseudocode.
+
+
+3.2.6. Using the encryption key
+
+ After the KRB_AP_REQ/KRB_AP_REP exchange has occurred,
+the client and server share an encryption key which can be
+used by the application. The "true session key" to be used
+for KRB_PRIV, KRB_SAFE, or other application-specific uses
+may be chosen by the application based on the subkeys in the
+KRB_AP_REP message and the authenticator[14]. In some
+cases, the use of this session key will be implicit in the
+protocol; in others the method of use must be chosen from
+several alternatives. We leave the protocol negotiations of
+how to use the key (e.g. selecting an encryption or check-
+sum type) to the application programmer; the Kerberos proto-
+col does not constrain the implementation options, but an
+example of how this might be done follows.
+
+ One way that an application may choose to negotiate a
+key to be used for subequent integrity and privacy protec-
+tion is for the client to propose a key in the subkey field
+of the authenticator. The server can then choose a key
+using the proposed key from the client as input, returning
+the new subkey in the subkey field of the application reply.
+This key could then be used for subsequent communication.
+To make this example more concrete, if the encryption method
+in use required a 56 bit key, and for whatever reason, one
+of the parties was prevented from using a key with more than
+40 unknown bits, this method would allow the the party which
+is prevented from using more than 40 bits to either propose
+(if the client) an initial key with a known quantity for 16
+of those bits, or to mask 16 of the bits (if the server)
+with the known quantity. The application implementor is
+warned, however, that this is only an example, and that an
+analysis of the particular crytosystem to be used, and the
+reasons for limiting the key length, must be made before
+deciding whether it is acceptable to mask bits of the key.
+
+ With both the one-way and mutual authentication
+exchanges, the peers should take care not to send sensitive
+information to each other without proper assurances. In
+particular, applications that require privacy or integrity
+should use the KRB_AP_REP response from the server to client
+__________________________
+[14] Implementations of the protocol may wish to pro-
+vide routines to choose subkeys based on session keys
+and random numbers and to generate a negotiated key to
+be returned in the KRB_AP_REP message.
+
+
+Section 3.2.6. - 24 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+to assure both client and server of their peer's identity.
+If an application protocol requires privacy of its messages,
+it can use the KRB_PRIV message (section 3.5). The KRB_SAFE
+message (section 3.4) can be used to assure integrity.
+
+
+3.3. The Ticket-Granting Service (TGS) Exchange
+
+ Summary
+ Message direction Message type Section
+ 1. Client to Kerberos KRB_TGS_REQ 5.4.1
+ 2. Kerberos to client KRB_TGS_REP or 5.4.2
+ KRB_ERROR 5.9.1
+
+
+ The TGS exchange between a client and the Kerberos
+Ticket-Granting Server is initiated by a client when it
+wishes to obtain authentication credentials for a given
+server (which might be registered in a remote realm), when
+it wishes to renew or validate an existing ticket, or when
+it wishes to obtain a proxy ticket. In the first case, the
+client must already have acquired a ticket for the Ticket-
+Granting Service using the AS exchange (the ticket-granting
+ticket is usually obtained when a client initially authenti-
+cates to the system, such as when a user logs in). The mes-
+sage format for the TGS exchange is almost identical to that
+for the AS exchange. The primary difference is that encryp-
+tion and decryption in the TGS exchange does not take place
+under the client's key. Instead, the session key from the
+ticket-granting ticket or renewable ticket, or sub-session
+key from an Authenticator is used. As is the case for all
+application servers, expired tickets are not accepted by the
+TGS, so once a renewable or ticket-granting ticket expires,
+the client must use a separate exchange to obtain valid
+tickets.
+
+ The TGS exchange consists of two messages: A request
+(KRB_TGS_REQ) from the client to the Kerberos Ticket-
+Granting Server, and a reply (KRB_TGS_REP or KRB_ERROR).
+The KRB_TGS_REQ message includes information authenticating
+the client plus a request for credentials. The authentica-
+tion information consists of the authentication header
+(KRB_AP_REQ) which includes the client's previously obtained
+ticket-granting, renewable, or invalid ticket. In the
+ticket-granting ticket and proxy cases, the request may
+include one or more of: a list of network addresses, a col-
+lection of typed authorization data to be sealed in the
+ticket for authorization use by the application server, or
+additional tickets (the use of which are described later).
+The TGS reply (KRB_TGS_REP) contains the requested creden-
+tials, encrypted in the session key from the ticket-granting
+ticket or renewable ticket, or if present, in the sub-
+session key from the Authenticator (part of the authentica-
+tion header). The KRB_ERROR message contains an error code
+
+
+Section 3.3. - 25 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+and text explaining what went wrong. The KRB_ERROR message
+is not encrypted. The KRB_TGS_REP message contains informa-
+tion which can be used to detect replays, and to associate
+it with the message to which it replies. The KRB_ERROR mes-
+sage also contains information which can be used to associ-
+ate it with the message to which it replies, but the lack of
+encryption in the KRB_ERROR message precludes the ability to
+detect replays or fabrications of such messages.
+
+3.3.1. Generation of KRB_TGS_REQ message
+
+ Before sending a request to the ticket-granting ser-
+vice, the client must determine in which realm the applica-
+tion server is registered[15]. If the client does not
+already possess a ticket-granting ticket for the appropriate
+realm, then one must be obtained. This is first attempted
+by requesting a ticket-granting ticket for the destination
+realm from a Kerberos server for which the client does
+posess a ticket-granting ticket (using the KRB_TGS_REQ mes-
+sage recursively). The Kerberos server may return a TGT for
+the desired realm in which case one can proceed. Alterna-
+tively, the Kerberos server may return a TGT for a realm
+which is "closer" to the desired realm (further along the
+standard hierarchical path), in which case this step must be
+repeated with a Kerberos server in the realm specified in
+the returned TGT. If neither are returned, then the request
+must be retried with a Kerberos server for a realm higher in
+the hierarchy. This request will itself require a ticket-
+granting ticket for the higher realm which must be obtained
+by recursively applying these directions.
+
+
+ Once the client obtains a ticket-granting ticket for
+the appropriate realm, it determines which Kerberos servers
+serve that realm, and contacts one. The list might be
+obtained through a configuration file or network service or
+it may be generated from the name of the realm; as long as
+the secret keys exchanged by realms are kept secret, only
+denial of service results from using a false Kerberos
+server.
+__________________________
+[15] This can be accomplished in several ways. It
+might be known beforehand (since the realm is part of
+the principal identifier), it might be stored in a
+nameserver, or it might be obtained from a configura-
+tion file. If the realm to be used is obtained from a
+nameserver, there is a danger of being spoofed if the
+nameservice providing the realm name is not authenti-
+cated. This might result in the use of a realm which
+has been compromised, and would result in an attacker's
+ability to compromise the authentication of the appli-
+cation server to the client.
+
+
+
+Section 3.3.1. - 26 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ As in the AS exchange, the client may specify a number
+of options in the KRB_TGS_REQ message. The client prepares
+the KRB_TGS_REQ message, providing an authentication header
+as an element of the padata field, and including the same
+fields as used in the KRB_AS_REQ message along with several
+optional fields: the enc-authorization-data field for appli-
+cation server use and additional tickets required by some
+options.
+
+ In preparing the authentication header, the client can
+select a sub-session key under which the response from the
+Kerberos server will be encrypted[16]. If the sub-session
+key is not specified, the session key from the ticket-
+granting ticket will be used. If the enc-authorization-data
+is present, it must be encrypted in the sub-session key, if
+present, from the authenticator portion of the authentica-
+tion header, or if not present, using the session key from
+the ticket-granting ticket.
+
+ Once prepared, the message is sent to a Kerberos server
+for the destination realm. See section A.5 for pseudocode.
+
+3.3.2. Receipt of KRB_TGS_REQ message
+
+ The KRB_TGS_REQ message is processed in a manner simi-
+lar to the KRB_AS_REQ message, but there are many additional
+checks to be performed. First, the Kerberos server must
+determine which server the accompanying ticket is for and it
+must select the appropriate key to decrypt it. For a normal
+KRB_TGS_REQ message, it will be for the ticket granting ser-
+vice, and the TGS's key will be used. If the TGT was issued
+by another realm, then the appropriate inter-realm key must
+be used. If the accompanying ticket is not a ticket grant-
+ing ticket for the current realm, but is for an application
+server in the current realm, the RENEW, VALIDATE, or PROXY
+options are specified in the request, and the server for
+which a ticket is requested is the server named in the
+accompanying ticket, then the KDC will decrypt the ticket in
+the authentication header using the key of the server for
+which it was issued. If no ticket can be found in the
+padata field, the KDC_ERR_PADATA_TYPE_NOSUPP error is
+returned.
+
+ Once the accompanying ticket has been decrypted, the
+user-supplied checksum in the Authenticator must be verified
+against the contents of the request, and the message
+rejected if the checksums do not match (with an error code
+__________________________
+[16] If the client selects a sub-session key, care must
+be taken to ensure the randomness of the selected sub-
+session key. One approach would be to generate a ran-
+dom number and XOR it with the session key from the
+ticket-granting ticket.
+
+
+Section 3.3.2. - 27 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+of KRB_AP_ERR_MODIFIED) or if the checksum is not keyed or
+not collision-proof (with an error code of
+KRB_AP_ERR_INAPP_CKSUM). If the checksum type is not sup-
+ported, the KDC_ERR_SUMTYPE_NOSUPP error is returned. If
+the authorization-data are present, they are decrypted using
+the sub-session key from the Authenticator.
+
+ If any of the decryptions indicate failed integrity
+checks, the KRB_AP_ERR_BAD_INTEGRITY error is returned.
+
+3.3.3. Generation of KRB_TGS_REP message
+
+ The KRB_TGS_REP message shares its format with the
+KRB_AS_REP (KRB_KDC_REP), but with its type field set to
+KRB_TGS_REP. The detailed specification is in section
+5.4.2.
+
+ The response will include a ticket for the requested
+server. The Kerberos database is queried to retrieve the
+record for the requested server (including the key with
+which the ticket will be encrypted). If the request is for
+a ticket granting ticket for a remote realm, and if no key
+is shared with the requested realm, then the Kerberos server
+will select the realm "closest" to the requested realm with
+which it does share a key, and use that realm instead. This
+is the only case where the response from the KDC will be for
+a different server than that requested by the client.
+
+ By default, the address field, the client's name and
+realm, the list of transited realms, the time of initial
+authentication, the expiration time, and the authorization
+data of the newly-issued ticket will be copied from the
+ticket-granting ticket (TGT) or renewable ticket. If the
+transited field needs to be updated, but the transited type
+is not supported, the KDC_ERR_TRTYPE_NOSUPP error is
+returned.
+
+ If the request specifies an endtime, then the endtime
+of the new ticket is set to the minimum of (a) that request,
+(b) the endtime from the TGT, and (c) the starttime of the
+TGT plus the minimum of the maximum life for the application
+server and the maximum life for the local realm (the maximum
+life for the requesting principal was already applied when
+the TGT was issued). If the new ticket is to be a renewal,
+then the endtime above is replaced by the minimum of (a) the
+value of the renew_till field of the ticket and (b) the
+starttime for the new ticket plus the life (endtime-
+starttime) of the old ticket.
+
+ If the FORWARDED option has been requested, then the
+resulting ticket will contain the addresses specified by the
+client. This option will only be honored if the FORWARDABLE
+flag is set in the TGT. The PROXY option is similar; the
+resulting ticket will contain the addresses specified by the
+
+
+Section 3.3.3. - 28 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+client. It will be honored only if the PROXIABLE flag in
+the TGT is set. The PROXY option will not be honored on
+requests for additional ticket-granting tickets.
+
+ If the requested start time is absent, indicates a time
+in the past, or is within the window of acceptable clock
+skew for the KDC and the POSTDATE option has not been speci-
+fied, then the start time of the ticket is set to the
+authentication server's current time. If it indicates a
+time in the future beyond the acceptable clock skew, but the
+POSTDATED option has not been specified or the MAY-POSTDATE
+flag is not set in the TGT, then the error
+KDC_ERR_CANNOT_POSTDATE is returned. Otherwise, if the
+ticket-granting ticket has the MAY-POSTDATE flag set, then
+the resulting ticket will be postdated and the requested
+starttime is checked against the policy of the local realm.
+If acceptable, the ticket's start time is set as requested,
+and the INVALID flag is set. The postdated ticket must be
+validated before use by presenting it to the KDC after the
+starttime has been reached. However, in no case may the
+starttime, endtime, or renew-till time of a newly-issued
+postdated ticket extend beyond the renew-till time of the
+ticket-granting ticket.
+
+ If the ENC-TKT-IN-SKEY option has been specified and an
+additional ticket has been included in the request, the KDC
+will decrypt the additional ticket using the key for the
+server to which the additional ticket was issued and verify
+that it is a ticket-granting ticket. If the name of the
+requested server is missing from the request, the name of
+the client in the additional ticket will be used. Otherwise
+the name of the requested server will be compared to the
+name of the client in the additional ticket and if dif-
+ferent, the request will be rejected. If the request
+succeeds, the session key from the additional ticket will be
+used to encrypt the new ticket that is issued instead of
+using the key of the server for which the new ticket will be
+used[17].
+
+ If the name of the server in the ticket that is
+presented to the KDC as part of the authentication header is
+not that of the ticket-granting server itself, the server is
+registered in the realm of the KDC, and the RENEW option is
+requested, then the KDC will verify that the RENEWABLE flag
+is set in the ticket, that the INVALID flag is not set in
+the ticket, and that the renew_till time is still in the
+future. If the VALIDATE option is rqeuested, the KDC will
+__________________________
+[17] This allows easy implementation of user-to-user
+authentication [8], which uses ticket-granting ticket
+session keys in lieu of secret server keys in situa-
+tions where such secret keys could be easily comprom-
+ised.
+
+
+Section 3.3.3. - 29 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+check that the starttime has passed and the INVALID flag is
+set. If the PROXY option is requested, then the KDC will
+check that the PROXIABLE flag is set in the ticket. If the
+tests succeed, and the ticket passes the hotlist check
+described in the next paragraph, the KDC will issue the
+appropriate new ticket.
+
+
+3.3.3.1. Checking for revoked tickets
+
+ Whenever a request is made to the ticket-granting
+server, the presented ticket(s) is(are) checked against a
+hot-list of tickets which have been canceled. This hot-list
+might be implemented by storing a range of issue timestamps
+for "suspect tickets"; if a presented ticket had an authtime
+in that range, it would be rejected. In this way, a stolen
+ticket-granting ticket or renewable ticket cannot be used to
+gain additional tickets (renewals or otherwise) once the
+theft has been reported. Any normal ticket obtained before
+it was reported stolen will still be valid (because they
+require no interaction with the KDC), but only until their
+normal expiration time.
+
+ The ciphertext part of the response in the KRB_TGS_REP
+message is encrypted in the sub-session key from the Authen-
+ticator, if present, or the session key key from the
+ticket-granting ticket. It is not encrypted using the
+client's secret key. Furthermore, the client's key's
+expiration date and the key version number fields are left
+out since these values are stored along with the client's
+database record, and that record is not needed to satisfy a
+request based on a ticket-granting ticket. See section A.6
+for pseudocode.
+
+3.3.3.2. Encoding the transited field
+
+ If the identity of the server in the TGT that is
+presented to the KDC as part of the authentication header is
+that of the ticket-granting service, but the TGT was issued
+from another realm, the KDC will look up the inter-realm key
+shared with that realm and use that key to decrypt the
+ticket. If the ticket is valid, then the KDC will honor the
+request, subject to the constraints outlined above in the
+section describing the AS exchange. The realm part of the
+client's identity will be taken from the ticket-granting
+ticket. The name of the realm that issued the ticket-
+granting ticket will be added to the transited field of the
+ticket to be issued. This is accomplished by reading the
+transited field from the ticket-granting ticket (which is
+treated as an unordered set of realm names), adding the new
+realm to the set, then constructing and writing out its
+encoded (shorthand) form (this may involve a rearrangement
+of the existing encoding).
+
+
+
+Section 3.3.3.2. - 30 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ Note that the ticket-granting service does not add the
+name of its own realm. Instead, its responsibility is to
+add the name of the previous realm. This prevents a mali-
+cious Kerberos server from intentionally leaving out its own
+name (it could, however, omit other realms' names).
+
+ The names of neither the local realm nor the
+principal's realm are to be included in the transited field.
+They appear elsewhere in the ticket and both are known to
+have taken part in authenticating the principal. Since the
+endpoints are not included, both local and single-hop
+inter-realm authentication result in a transited field that
+is empty.
+
+ Because the name of each realm transited is added to
+this field, it might potentially be very long. To decrease
+the length of this field, its contents are encoded. The
+initially supported encoding is optimized for the normal
+case of inter-realm communication: a hierarchical arrange-
+ment of realms using either domain or X.500 style realm
+names. This encoding (called DOMAIN-X500-COMPRESS) is now
+described.
+
+ Realm names in the transited field are separated by a
+",". The ",", "\", trailing "."s, and leading spaces (" ")
+are special characters, and if they are part of a realm
+name, they must be quoted in the transited field by preced-
+ing them with a "\".
+
+ A realm name ending with a "." is interpreted as being
+prepended to the previous realm. For example, we can encode
+traversal of EDU, MIT.EDU, ATHENA.MIT.EDU, WASHINGTON.EDU,
+and CS.WASHINGTON.EDU as:
+
+ "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS.".
+
+Note that if ATHENA.MIT.EDU, or CS.WASHINGTON.EDU were end-
+points, that they would not be included in this field, and
+we would have:
+
+ "EDU,MIT.,WASHINGTON.EDU"
+
+A realm name beginning with a "/" is interpreted as being
+appended to the previous realm[18]. If it is to stand by
+itself, then it should be preceded by a space (" "). For
+example, we can encode traversal of /COM/HP/APOLLO, /COM/HP,
+/COM, and /COM/DEC as:
+
+ "/COM,/HP,/APOLLO, /COM/DEC".
+__________________________
+[18] For the purpose of appending, the realm preceding
+the first listed realm is considered to be the null
+realm ("").
+
+
+Section 3.3.3.2. - 31 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+Like the example above, if /COM/HP/APOLLO and /COM/DEC are
+endpoints, they they would not be included in this field,
+and we would have:
+
+ "/COM,/HP"
+
+
+ A null subfield preceding or following a "," indicates
+that all realms between the previous realm and the next
+realm have been traversed[19]. Thus, "," means that all
+realms along the path between the client and the server have
+been traversed. ",EDU, /COM," means that that all realms
+from the client's realm up to EDU (in a domain style hierar-
+chy) have been traversed, and that everything from /COM down
+to the server's realm in an X.500 style has also been
+traversed. This could occur if the EDU realm in one hierar-
+chy shares an inter-realm key directly with the /COM realm
+in another hierarchy.
+
+3.3.4. Receipt of KRB_TGS_REP message
+
+When the KRB_TGS_REP is received by the client, it is pro-
+cessed in the same manner as the KRB_AS_REP processing
+described above. The primary difference is that the cipher-
+text part of the response must be decrypted using the ses-
+sion key from the ticket-granting ticket rather than the
+client's secret key. See section A.7 for pseudocode.
+
+
+3.4. The KRB_SAFE Exchange
+
+ The KRB_SAFE message may be used by clients requiring
+the ability to detect modifications of messages they
+exchange. It achieves this by including a keyed collision-
+proof checksum of the user data and some control informa-
+tion. The checksum is keyed with an encryption key (usually
+the last key negotiated via subkeys, or the session key if
+no negotiation has occured).
+
+3.4.1. Generation of a KRB_SAFE message
+
+When an application wishes to send a KRB_SAFE message, it
+collects its data and the appropriate control information
+and computes a checksum over them. The checksum algorithm
+should be a keyed one-way hash function (such as the RSA-
+MD5-DES checksum algorithm specified in section 6.4.5, or
+the DES MAC), generated using the sub-session key if
+present, or the session key. Different algorithms may be
+__________________________
+[19] For the purpose of interpreting null subfields,
+the client's realm is considered to precede those in
+the transited field, and the server's realm is con-
+sidered to follow them.
+
+
+Section 3.4.1. - 32 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+selected by changing the checksum type in the message.
+Unkeyed or non-collision-proof checksums are not suitable
+for this use.
+
+ The control information for the KRB_SAFE message
+includes both a timestamp and a sequence number. The
+designer of an application using the KRB_SAFE message must
+choose at least one of the two mechanisms. This choice
+should be based on the needs of the application protocol.
+
+ Sequence numbers are useful when all messages sent will
+be received by one's peer. Connection state is presently
+required to maintain the session key, so maintaining the
+next sequence number should not present an additional prob-
+lem.
+
+ If the application protocol is expected to tolerate
+lost messages without them being resent, the use of the
+timestamp is the appropriate replay detection mechanism.
+Using timestamps is also the appropriate mechanism for
+multi-cast protocols where all of one's peers share a common
+sub-session key, but some messages will be sent to a subset
+of one's peers.
+
+ After computing the checksum, the client then transmits
+the information and checksum to the recipient in the message
+format specified in section 5.6.1.
+
+3.4.2. Receipt of KRB_SAFE message
+
+When an application receives a KRB_SAFE message, it verifies
+it as follows. If any error occurs, an error code is
+reported for use by the application.
+
+ The message is first checked by verifying that the pro-
+tocol version and type fields match the current version and
+KRB_SAFE, respectively. A mismatch generates a
+KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error. The
+application verifies that the checksum used is a collision-
+proof keyed checksum, and if it is not, a
+KRB_AP_ERR_INAPP_CKSUM error is generated. The recipient
+verifies that the operating system's report of the sender's
+address matches the sender's address in the message, and (if
+a recipient address is specified or the recipient requires
+an address) that one of the recipient's addresses appears as
+the recipient's address in the message. A failed match for
+either case generates a KRB_AP_ERR_BADADDR error. Then the
+timestamp and usec and/or the sequence number fields are
+checked. If timestamp and usec are expected and not
+present, or they are present but not current, the
+KRB_AP_ERR_SKEW error is generated. If the server name,
+along with the client name, time and microsecond fields from
+the Authenticator match any recently-seen (sent or
+received[20] ) such tuples, the KRB_AP_ERR_REPEAT error is
+__________________________
+[20] This means that a client and server running on the
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+generated. If an incorrect sequence number is included, or
+a sequence number is expected but not present, the
+KRB_AP_ERR_BADORDER error is generated. If neither a time-
+stamp and usec or a sequence number is present, a
+KRB_AP_ERR_MODIFIED error is generated. Finally, the check-
+sum is computed over the data and control information, and
+if it doesn't match the received checksum, a
+KRB_AP_ERR_MODIFIED error is generated.
+
+ If all the checks succeed, the application is assured
+that the message was generated by its peer and was not modi-
+fied in transit.
+
+3.5. The KRB_PRIV Exchange
+
+ The KRB_PRIV message may be used by clients requiring
+confidentiality and the ability to detect modifications of
+exchanged messages. It achieves this by encrypting the mes-
+sages and adding control information.
+
+3.5.1. Generation of a KRB_PRIV message
+
+When an application wishes to send a KRB_PRIV message, it
+collects its data and the appropriate control information
+(specified in section 5.7.1) and encrypts them under an
+encryption key (usually the last key negotiated via subkeys,
+or the session key if no negotiation has occured). As part
+of the control information, the client must choose to use
+either a timestamp or a sequence number (or both); see the
+discussion in section 3.4.1 for guidelines on which to use.
+After the user data and control information are encrypted,
+the client transmits the ciphertext and some "envelope"
+information to the recipient.
+
+3.5.2. Receipt of KRB_PRIV message
+
+When an application receives a KRB_PRIV message, it verifies
+it as follows. If any error occurs, an error code is
+reported for use by the application.
+
+ The message is first checked by verifying that the pro-
+tocol version and type fields match the current version and
+KRB_PRIV, respectively. A mismatch generates a
+KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error. The
+application then decrypts the ciphertext and processes the
+resultant plaintext. If decryption shows the data to have
+been modified, a KRB_AP_ERR_BAD_INTEGRITY error is gen-
+erated. The recipient verifies that the operating system's
+report of the sender's address matches the sender's address
+__________________________
+same host and communicating with one another using the
+KRB_SAFE messages should not share a common replay
+cache to detect KRB_SAFE replays.
+
+
+
+Section 3.5.2. - 34 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+in the message, and (if a recipient address is specified or
+the recipient requires an address) that one of the
+recipient's addresses appears as the recipient's address in
+the message. A failed match for either case generates a
+KRB_AP_ERR_BADADDR error. Then the timestamp and usec
+and/or the sequence number fields are checked. If timestamp
+and usec are expected and not present, or they are present
+but not current, the KRB_AP_ERR_SKEW error is generated. If
+the server name, along with the client name, time and
+microsecond fields from the Authenticator match any
+recently-seen such tuples, the KRB_AP_ERR_REPEAT error is
+generated. If an incorrect sequence number is included, or
+a sequence number is expected but not present, the
+KRB_AP_ERR_BADORDER error is generated. If neither a time-
+stamp and usec or a sequence number is present, a
+KRB_AP_ERR_MODIFIED error is generated.
+
+ If all the checks succeed, the application can assume
+the message was generated by its peer, and was securely
+transmitted (without intruders able to see the unencrypted
+contents).
+
+3.6. The KRB_CRED Exchange
+
+ The KRB_CRED message may be used by clients requiring
+the ability to send Kerberos credentials from one host to
+another. It achieves this by sending the tickets together
+with encrypted data containing the session keys and other
+information associated with the tickets.
+
+3.6.1. Generation of a KRB_CRED message
+
+When an application wishes to send a KRB_CRED message it
+first (using the KRB_TGS exchange) obtains credentials to be
+sent to the remote host. It then constructs a KRB_CRED mes-
+sage using the ticket or tickets so obtained, placing the
+session key needed to use each ticket in the key field of
+the corresponding KrbCredInfo sequence of the encrypted part
+of the the KRB_CRED message.
+
+ Other information associated with each ticket and
+obtained during the KRB_TGS exchange is also placed in the
+corresponding KrbCredInfo sequence in the encrypted part of
+the KRB_CRED message. The current time and, if specifically
+required by the application the nonce, s-address, and r-
+address fields, are placed in the encrypted part of the
+KRB_CRED message which is then encrypted under an encryption
+key previosuly exchanged in the KRB_AP exchange (usually the
+last key negotiated via subkeys, or the session key if no
+negotiation has occured).
+
+3.6.2. Receipt of KRB_CRED message
+
+When an application receives a KRB_CRED message, it verifies
+
+
+Section 3.6.2. - 35 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+it. If any error occurs, an error code is reported for use
+by the application. The message is verified by checking
+that the protocol version and type fields match the current
+version and KRB_CRED, respectively. A mismatch generates a
+KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error. The
+application then decrypts the ciphertext and processes the
+resultant plaintext. If decryption shows the data to have
+been modified, a KRB_AP_ERR_BAD_INTEGRITY error is gen-
+erated.
+
+ If present or required, the recipient verifies that the
+operating system's report of the sender's address matches
+the sender's address in the message, and that one of the
+recipient's addresses appears as the recipient's address in
+the message. A failed match for either case generates a
+KRB_AP_ERR_BADADDR error. The timestamp and usec fields
+(and the nonce field if required) are checked next. If the
+timestamp and usec are not present, or they are present but
+not current, the KRB_AP_ERR_SKEW error is generated.
+
+ If all the checks succeed, the application stores each
+of the new tickets in its ticket cache together with the
+session key and other information in the corresponding
+KrbCredInfo sequence from the encrypted part of the KRB_CRED
+message.
+
+4. The Kerberos Database
+
+The Kerberos server must have access to a database contain-
+ing the principal identifiers and secret keys of principals
+to be authenticated[21].
+
+4.1. Database contents
+
+A database entry should contain at least the following
+fields:
+
+Field Value
+
+name Principal's identif-
+ier
+key Principal's secret key
+p_kvno Principal's key version
+max_life Maximum lifetime for Tickets
+__________________________
+[21] The implementation of the Kerberos server need not
+combine the database and the server on the same
+machine; it is feasible to store the principal database
+in, say, a network name service, as long as the entries
+stored therein are protected from disclosure to and
+modification by unauthorized parties. However, we
+recommend against such strategies, as they can make
+system management and threat analysis quite complex.
+
+
+Section 4.1. - 36 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+max_renewable_life Maximum total lifetime for renewable Tickets
+
+The name field is an encoding of the principal's identifier.
+The key field contains an encryption key. This key is the
+principal's secret key. (The key can be encrypted before
+storage under a Kerberos "master key" to protect it in case
+the database is compromised but the master key is not. In
+that case, an extra field must be added to indicate the mas-
+ter key version used, see below.) The p_kvno field is the
+key version number of the principal's secret key. The
+max_life field contains the maximum allowable lifetime (end-
+time - starttime) for any Ticket issued for this principal.
+The max_renewable_life field contains the maximum allowable
+total lifetime for any renewable Ticket issued for this
+principal. (See section 3.1 for a description of how these
+lifetimes are used in determining the lifetime of a given
+Ticket.)
+
+ A server may provide KDC service to several realms, as
+long as the database representation provides a mechanism to
+distinguish between principal records with identifiers which
+differ only in the realm name.
+
+ When an application server's key changes, if the change
+is routine (i.e. not the result of disclosure of the old
+key), the old key should be retained by the server until all
+tickets that had been issued using that key have expired.
+Because of this, it is possible for several keys to be
+active for a single principal. Ciphertext encrypted in a
+principal's key is always tagged with the version of the key
+that was used for encryption, to help the recipient find the
+proper key for decryption.
+
+ When more than one key is active for a particular prin-
+cipal, the principal will have more than one record in the
+Kerberos database. The keys and key version numbers will
+differ between the records (the rest of the fields may or
+may not be the same). Whenever Kerberos issues a ticket, or
+responds to a request for initial authentication, the most
+recent key (known by the Kerberos server) will be used for
+encryption. This is the key with the highest key version
+number.
+
+4.2. Additional fields
+
+Project Athena's KDC implementation uses additional fields
+in its database:
+
+Field Value
+
+K_kvno Kerberos' key version
+expiration Expiration date for entry
+attributes Bit field of attributes
+mod_date Timestamp of last modification
+
+
+Section 4.2. - 37 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+mod_name Modifying principal's identifier
+
+
+The K_kvno field indicates the key version of the Kerberos
+master key under which the principal's secret key is
+encrypted.
+
+ After an entry's expiration date has passed, the KDC
+will return an error to any client attempting to gain tick-
+ets as or for the principal. (A database may want to main-
+tain two expiration dates: one for the principal, and one
+for the principal's current key. This allows password aging
+to work independently of the principal's expiration date.
+However, due to the limited space in the responses, the KDC
+must combine the key expiration and principal expiration
+date into a single value called "key_exp", which is used as
+a hint to the user to take administrative action.)
+
+ The attributes field is a bitfield used to govern the
+operations involving the principal. This field might be
+useful in conjunction with user registration procedures, for
+site-specific policy implementations (Project Athena
+currently uses it for their user registration process con-
+trolled by the system-wide database service, Moira [9]), to
+identify whether a principal can play the role of a client
+or server or both, to note whether a server is appropriate
+trusted to recieve credentials delegated by a client, or to
+identify the "string to key" conversion algorithm used for a
+principal's key[22]. Other bits are used to indicate that
+certain ticket options should not be allowed in tickets
+encrypted under a principal's key (one bit each): Disallow
+issuing postdated tickets, disallow issuing forwardable
+tickets, disallow issuing tickets based on TGT authentica-
+tion, disallow issuing renewable tickets, disallow issuing
+proxiable tickets, and disallow issuing tickets for which
+the principal is the server.
+
+ The mod_date field contains the time of last modifica-
+tion of the entry, and the mod_name field contains the name
+of the principal which last modified the entry.
+
+4.3. Frequently Changing Fields
+
+ Some KDC implementations may wish to maintain the last
+time that a request was made by a particular principal.
+Information that might be maintained includes the time of
+the last request, the time of the last request for a
+ticket-granting ticket, the time of the last use of a
+ticket-granting ticket, or other times. This information
+can then be returned to the user in the last-req field (see
+__________________________
+[22] See the discussion of the padata field in section
+5.4.2 for details on why this can be useful.
+
+
+Section 4.3. - 38 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+section 5.2).
+
+ Other frequently changing information that can be main-
+tained is the latest expiration time for any tickets that
+have been issued using each key. This field would be used
+to indicate how long old keys must remain valid to allow the
+continued use of outstanding tickets.
+
+4.4. Site Constants
+
+ The KDC implementation should have the following confi-
+gurable constants or options, to allow an administrator to
+make and enforce policy decisions:
+
++ The minimum supported lifetime (used to determine whether
+ the KDC_ERR_NEVER_VALID error should be returned). This
+ constant should reflect reasonable expectations of
+ round-trip time to the KDC, encryption/decryption time,
+ and processing time by the client and target server, and
+ it should allow for a minimum "useful" lifetime.
+
++ The maximum allowable total (renewable) lifetime of a
+ ticket (renew_till - starttime).
+
++ The maximum allowable lifetime of a ticket (endtime -
+ starttime).
+
++ Whether to allow the issue of tickets with empty address
+ fields (including the ability to specify that such tick-
+ ets may only be issued if the request specifies some
+ authorization_data).
+
++ Whether proxiable, forwardable, renewable or post-datable
+ tickets are to be issued.
+
+
+5. Message Specifications
+
+ The following sections describe the exact contents and
+encoding of protocol messages and objects. The ASN.1 base
+definitions are presented in the first subsection. The
+remaining subsections specify the protocol objects (tickets
+and authenticators) and messages. Specification of encryp-
+tion and checksum techniques, and the fields related to
+them, appear in section 6.
+
+5.1. ASN.1 Distinguished Encoding Representation
+
+ All uses of ASN.1 in Kerberos shall use the Dis-
+tinguished Encoding Representation of the data elements as
+described in the X.509 specification, section 8.7 [10].
+
+
+
+
+
+Section 5.1. - 39 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+5.2. ASN.1 Base Definitions
+
+ The following ASN.1 base definitions are used in the
+rest of this section. Note that since the underscore char-
+acter (_) is not permitted in ASN.1 names, the hyphen (-) is
+used in its place for the purposes of ASN.1 names.
+
+Realm ::= GeneralString
+PrincipalName ::= SEQUENCE {
+ name-type[0] INTEGER,
+ name-string[1] SEQUENCE OF GeneralString
+}
+
+
+Kerberos realms are encoded as GeneralStrings. Realms shall
+not contain a character with the code 0 (the ASCII NUL).
+Most realms will usually consist of several components
+separated by periods (.), in the style of Internet Domain
+Names, or separated by slashes (/) in the style of X.500
+names. Acceptable forms for realm names are specified in
+section 7. A PrincipalName is a typed sequence of com-
+ponents consisting of the following sub-fields:
+
+name-type This field specifies the type of name that fol-
+ lows. Pre-defined values for this field are
+ specified in section 7.2. The name-type should be
+ treated as a hint. Ignoring the name type, no two
+ names can be the same (i.e. at least one of the
+ components, or the realm, must be different).
+ This constraint may be eliminated in the future.
+
+name-stringThis field encodes a sequence of components that
+ form a name, each component encoded as a General-
+ String. Taken together, a PrincipalName and a
+ Realm form a principal identifier. Most Princi-
+ palNames will have only a few components (typi-
+ cally one or two).
+
+
+
+ KerberosTime ::= GeneralizedTime
+ -- Specifying UTC time zone (Z)
+
+
+ The timestamps used in Kerberos are encoded as General-
+izedTimes. An encoding shall specify the UTC time zone (Z)
+and shall not include any fractional portions of the
+seconds. It further shall not include any separators.
+Example: The only valid format for UTC time 6 minutes, 27
+seconds after 9 pm on 6 November 1985 is 19851106210627Z.
+
+ HostAddress ::= SEQUENCE {
+ addr-type[0] INTEGER,
+ address[1] OCTET STRING
+
+
+Section 5.2. - 40 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ }
+
+ HostAddresses ::= SEQUENCE OF SEQUENCE {
+ addr-type[0] INTEGER,
+ address[1] OCTET STRING
+ }
+
+
+ The host adddress encodings consists of two fields:
+
+addr-type This field specifies the type of address that
+ follows. Pre-defined values for this field are
+ specified in section 8.1.
+
+
+address This field encodes a single address of type addr-
+ type.
+
+The two forms differ slightly. HostAddress contains exactly
+one address; HostAddresses contains a sequence of possibly
+many addresses.
+
+AuthorizationData ::= SEQUENCE OF SEQUENCE {
+ ad-type[0] INTEGER,
+ ad-data[1] OCTET STRING
+}
+
+
+ad-data This field contains authorization data to be
+ interpreted according to the value of the
+ corresponding ad-type field.
+
+ad-type This field specifies the format for the ad-data
+ subfield. All negative values are reserved for
+ local use. Non-negative values are reserved for
+ registered use.
+
+ APOptions ::= BIT STRING {
+ reserved(0),
+ use-session-key(1),
+ mutual-required(2)
+ }
+
+
+ TicketFlags ::= BIT STRING {
+ reserved(0),
+ forwardable(1),
+ forwarded(2),
+ proxiable(3),
+ proxy(4),
+ may-postdate(5),
+ postdated(6),
+ invalid(7),
+ renewable(8),
+ initial(9),
+
+
+Section 5.2. - 41 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ pre-authent(10),
+ hw-authent(11),
+ transited-policy-checked(12),
+ ok-as-delegate(13)
+ }
+
+
+ KDCOptions ::= BIT STRING {
+ reserved(0),
+ forwardable(1),
+ forwarded(2),
+ proxiable(3),
+ proxy(4),
+ allow-postdate(5),
+ postdated(6),
+ unused7(7),
+ renewable(8),
+ unused9(9),
+ unused10(10),
+ unused11(11),
+ unused12(12),
+ unused13(13),
+ disable-transited-check(26),
+ renewable-ok(27),
+ enc-tkt-in-skey(28),
+ renew(30),
+ validate(31)
+ }
+
+ ASN.1 Bit strings have a length and a value. When
+ used in Kerberos for the APOptions, TicketFlags,
+ and KDCOptions, the length of the bit string on
+ generated values should be the smallest multiple
+ of 32 bits needed to include the highest order bit
+ that is set (1), but in no case less than 32 bits.
+ Implementations should accept values of bit
+ strings of any length and treat the value of flags
+ cooresponding to bits beyond the end of the bit
+ string as if the bit were reset (0). Comparisonof
+ bit strings of different length should treat the
+ smaller string as if it were padded with zeros
+ beyond the high order bits to the length of the
+ longer string[23].
+
+__________________________
+[23] Warning for implementations that unpack and repack
+data structures during the generation and verification
+of embedded checksums: Because any checksums applied to
+data structures must be checked against the original
+data the length of bit strings must be preserved within
+a data structure between the time that a checksum is
+generated through transmission to the time that the
+checksum is verified.
+
+
+
+Section 5.2. - 42 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ LastReq ::= SEQUENCE OF SEQUENCE {
+ lr-type[0] INTEGER,
+ lr-value[1] KerberosTime
+ }
+
+
+lr-type This field indicates how the following lr-value
+ field is to be interpreted. Negative values indi-
+ cate that the information pertains only to the
+ responding server. Non-negative values pertain to
+ all servers for the realm.
+
+ If the lr-type field is zero (0), then no informa-
+ tion is conveyed by the lr-value subfield. If the
+ absolute value of the lr-type field is one (1),
+ then the lr-value subfield is the time of last
+ initial request for a TGT. If it is two (2), then
+ the lr-value subfield is the time of last initial
+ request. If it is three (3), then the lr-value
+ subfield is the time of issue for the newest
+ ticket-granting ticket used. If it is four (4),
+ then the lr-value subfield is the time of the last
+ renewal. If it is five (5), then the lr-value
+ subfield is the time of last request (of any
+ type).
+
+
+lr-value This field contains the time of the last request.
+ The time must be interpreted according to the con-
+ tents of the accompanying lr-type subfield.
+
+ See section 6 for the definitions of Checksum, Check-
+sumType, EncryptedData, EncryptionKey, EncryptionType, and
+KeyType.
+
+
+5.3. Tickets and Authenticators
+
+ This section describes the format and encryption param-
+eters for tickets and authenticators. When a ticket or
+authenticator is included in a protocol message it is
+treated as an opaque object.
+
+5.3.1. Tickets
+
+ A ticket is a record that helps a client authenticate
+to a service. A Ticket contains the following information:
+
+Ticket ::= [APPLICATION 1] SEQUENCE {
+ tkt-vno[0] INTEGER,
+ realm[1] Realm,
+ sname[2] PrincipalName,
+ enc-part[3] EncryptedData
+}
+
+
+Section 5.3.1. - 43 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+-- Encrypted part of ticket
+EncTicketPart ::= [APPLICATION 3] SEQUENCE {
+ flags[0] TicketFlags,
+ key[1] EncryptionKey,
+ crealm[2] Realm,
+ cname[3] PrincipalName,
+ transited[4] TransitedEncoding,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ caddr[9] HostAddresses OPTIONAL,
+ authorization-data[10] AuthorizationData OPTIONAL
+}
+-- encoded Transited field
+TransitedEncoding ::= SEQUENCE {
+ tr-type[0] INTEGER, -- must be registered
+ contents[1] OCTET STRING
+}
+
+The encoding of EncTicketPart is encrypted in the key shared
+by Kerberos and the end server (the server's secret key).
+See section 6 for the format of the ciphertext.
+
+tkt-vno This field specifies the version number for the
+ ticket format. This document describes version
+ number 5.
+
+
+realm This field specifies the realm that issued a
+ ticket. It also serves to identify the realm part
+ of the server's principal identifier. Since a
+ Kerberos server can only issue tickets for servers
+ within its realm, the two will always be identi-
+ cal.
+
+
+sname This field specifies the name part of the server's
+ identity.
+
+
+enc-part This field holds the encrypted encoding of the
+ EncTicketPart sequence.
+
+
+flags This field indicates which of various options were
+ used or requested when the ticket was issued. It
+ is a bit-field, where the selected options are
+ indicated by the bit being set (1), and the
+ unselected options and reserved fields being reset
+ (0). Bit 0 is the most significant bit. The
+ encoding of the bits is specified in section 5.2.
+ The flags are described in more detail above in
+ section 2. The meanings of the flags are:
+
+
+Section 5.3.1. - 44 - Expires 11 January 1998
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ Bit(s) Name Description
+
+ 0 RESERVED
+ Reserved for future expansion of this
+ field.
+
+ 1 FORWARDABLE
+ The FORWARDABLE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. When set, this
+ flag tells the ticket-granting server
+ that it is OK to issue a new ticket-
+ granting ticket with a different network
+ address based on the presented ticket.
+
+ 2 FORWARDED
+ When set, this flag indicates that the
+ ticket has either been forwarded or was
+ issued based on authentication involving
+ a forwarded ticket-granting ticket.
+
+ 3 PROXIABLE
+ The PROXIABLE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. The PROXIABLE
+ flag has an interpretation identical to
+ that of the FORWARDABLE flag, except
+ that the PROXIABLE flag tells the
+ ticket-granting server that only non-
+ ticket-granting tickets may be issued
+ with different network addresses.
+
+ 4 PROXY
+ When set, this flag indicates that a
+ ticket is a proxy.
+
+ 5 MAY-POSTDATE
+ The MAY-POSTDATE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. This flag tells
+ the ticket-granting server that a post-
+ dated ticket may be issued based on this
+ ticket-granting ticket.
+
+ 6 POSTDATED
+ This flag indicates that this ticket has
+ been postdated. The end-service can
+ check the authtime field to see when the
+ original authentication occurred.
+
+ 7 INVALID
+ This flag indicates that a ticket is
+ invalid, and it must be validated by the
+ KDC before use. Application servers
+ must reject tickets which have this flag
+ set.
+
+
+
+
+
+
+
+
+Section 5.3.1. - 45 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ 8 RENEWABLE
+ The RENEWABLE flag is normally only
+ interpreted by the TGS, and can usually
+ be ignored by end servers (some particu-
+ larly careful servers may wish to disal-
+ low renewable tickets). A renewable
+ ticket can be used to obtain a replace-
+ ment ticket that expires at a later
+ date.
+
+ 9 INITIAL
+ This flag indicates that this ticket was
+ issued using the AS protocol, and not
+ issued based on a ticket-granting
+ ticket.
+
+ 10 PRE-AUTHENT
+ This flag indicates that during initial
+ authentication, the client was authenti-
+ cated by the KDC before a ticket was
+ issued. The strength of the pre-
+ authentication method is not indicated,
+ but is acceptable to the KDC.
+
+ 11 HW-AUTHENT
+ This flag indicates that the protocol
+ employed for initial authentication
+ required the use of hardware expected to
+ be possessed solely by the named client.
+ The hardware authentication method is
+ selected by the KDC and the strength of
+ the method is not indicated.
+
+
+
+
+Section 5.3.1. - 46 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ 12 TRANSITED This flag indicates that the KDC for the
+ POLICY-CHECKED realm has checked the transited field
+ against a realm defined policy for
+ trusted certifiers. If this flag is
+ reset (0), then the application server
+ must check the transited field itself,
+ and if unable to do so it must reject
+ the authentication. If the flag is set
+ (1) then the application server may skip
+ its own validation of the transited
+ field, relying on the validation
+ performed by the KDC. At its option the
+ application server may still apply its
+ own validation based on a separate
+ policy for acceptance.
+
+Section 5.3.1. - 47 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ 13 OK-AS-DELEGATE This flag indicates that the server (not
+ the client) specified in the ticket has
+ been determined by policy of the realm
+ to be a suitable recipient of
+ delegation. A client can use the
+ presence of this flag to help it make a
+ decision whether to delegate credentials
+ (either grant a proxy or a forwarded
+ ticket granting ticket) to this server.
+ The client is free to ignore the value
+ of this flag. When setting this flag,
+ an administrator should consider the
+ security and placement of the server on
+ which the service will run, as well as
+ whether the service requires the use of
+ delegated credentials.
+
+
+
+
+Section 5.3.1. - 48 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ 14 ANONYMOUS
+ This flag indicates that the principal
+ named in the ticket is a generic princi-
+ pal for the realm and does not identify
+ the individual using the ticket. The
+ purpose of the ticket is only to
+ securely distribute a session key, and
+ not to identify the user. Subsequent
+ requests using the same ticket and ses-
+ sion may be considered as originating
+ from the same user, but requests with
+ the same username but a different ticket
+ are likely to originate from different
+ users.
+
+ 15-31 RESERVED
+ Reserved for future use.
+
+
+
+key This field exists in the ticket and the KDC
+ response and is used to pass the session key from
+ Kerberos to the application server and the client.
+ The field's encoding is described in section 6.2.
+
+crealm This field contains the name of the realm in which
+ the client is registered and in which initial
+ authentication took place.
+
+
+cname This field contains the name part of the client's
+ principal identifier.
+
+
+transited This field lists the names of the Kerberos realms
+ that took part in authenticating the user to whom
+ this ticket was issued. It does not specify the
+ order in which the realms were transited. See
+ section 3.3.3.2 for details on how this field
+ encodes the traversed realms.
+
+
+authtime This field indicates the time of initial authenti-
+ cation for the named principal. It is the time of
+ issue for the original ticket on which this ticket
+ is based. It is included in the ticket to provide
+ additional information to the end service, and to
+ provide the necessary information for implementa-
+ tion of a `hot list' service at the KDC. An end
+ service that is particularly paranoid could refuse
+ to accept tickets for which the initial authenti-
+ cation occurred "too far" in the past.
+
+ This field is also returned as part of the
+ response from the KDC. When returned as part of
+ the response to initial authentication
+
+
+Section 5.3.1. - 49 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ (KRB_AS_REP), this is the current time on the Ker-
+ beros server[24].
+
+
+starttime This field in the ticket specifies the time after
+ which the ticket is valid. Together with endtime,
+ this field specifies the life of the ticket. If
+ it is absent from the ticket, its value should be
+ treated as that of the authtime field.
+
+
+endtime This field contains the time after which the
+ ticket will not be honored (its expiration time).
+ Note that individual services may place their own
+ limits on the life of a ticket and may reject
+ tickets which have not yet expired. As such, this
+ is really an upper bound on the expiration time
+ for the ticket.
+
+
+renew-tillThis field is only present in tickets that have
+ the RENEWABLE flag set in the flags field. It
+ indicates the maximum endtime that may be included
+ in a renewal. It can be thought of as the abso-
+ lute expiration time for the ticket, including all
+ renewals.
+
+
+caddr This field in a ticket contains zero (if omitted)
+ or more (if present) host addresses. These are
+ the addresses from which the ticket can be used.
+ If there are no addresses, the ticket can be used
+ from any location. The decision by the KDC to
+ issue or by the end server to accept zero-address
+ tickets is a policy decision and is left to the
+ Kerberos and end-service administrators; they may
+ refuse to issue or accept such tickets. The sug-
+ gested and default policy, however, is that such
+ tickets will only be issued or accepted when addi-
+ tional information that can be used to restrict
+ the use of the ticket is included in the
+ authorization_data field. Such a ticket is a
+ capability.
+
+ Network addresses are included in the ticket to
+ make it harder for an attacker to use stolen
+ credentials. Because the session key is not sent
+ over the network in cleartext, credentials can't
+__________________________
+[24] It is NOT recommended that this time value be used
+to adjust the workstation's clock since the workstation
+cannot reliably determine that such a KRB_AS_REP actu-
+ally came from the proper KDC in a timely manner.
+
+
+Section 5.3.1. - 50 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ be stolen simply by listening to the network; an
+ attacker has to gain access to the session key
+ (perhaps through operating system security
+ breaches or a careless user's unattended session)
+ to make use of stolen tickets.
+
+ It is important to note that the network address
+ from which a connection is received cannot be
+ reliably determined. Even if it could be, an
+ attacker who has compromised the client's worksta-
+ tion could use the credentials from there.
+ Including the network addresses only makes it more
+ difficult, not impossible, for an attacker to walk
+ off with stolen credentials and then use them from
+ a "safe" location.
+
+
+authorization-data
+ The authorization-data field is used to pass
+ authorization data from the principal on whose
+ behalf a ticket was issued to the application ser-
+ vice. If no authorization data is included, this
+ field will be left out. Experience has shown that
+ the name of this field is confusing, and that a
+ better name for this field would be restrictions.
+ Unfortunately, it is not possible to change the
+ name of this field at this time.
+
+ This field contains restrictions on any authority
+ obtained on the bases of authentication using the
+ ticket. It is possible for any principal in
+ posession of credentials to add entries to the
+ authorization data field since these entries
+ further restrict what can be done with the ticket.
+ Such additions can be made by specifying the addi-
+ tional entries when a new ticket is obtained dur-
+ ing the TGS exchange, or they may be added during
+ chained delegation using the authorization data
+ field of the authenticator.
+
+ Because entries may be added to this field by the
+ holder of credentials, it is not allowable for the
+ presence of an entry in the authorization data
+ field of a ticket to amplify the priveleges one
+ would obtain from using a ticket.
+
+ The data in this field may be specific to the end
+ service; the field will contain the names of ser-
+ vice specific objects, and the rights to those
+ objects. The format for this field is described
+ in section 5.2. Although Kerberos is not con-
+ cerned with the format of the contents of the sub-
+ fields, it does carry type information (ad-type).
+
+
+
+Section 5.3.1. - 51 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ By using the authorization_data field, a principal
+ is able to issue a proxy that is valid for a
+ specific purpose. For example, a client wishing
+ to print a file can obtain a file server proxy to
+ be passed to the print server. By specifying the
+ name of the file in the authorization_data field,
+ the file server knows that the print server can
+ only use the client's rights when accessing the
+ particular file to be printed.
+
+ A separate service providing providing authoriza-
+ tion or certifying group membership may be built
+ using the authorization-data field. In this case,
+ the entity granting authorization (not the author-
+ ized entity), obtains a ticket in its own name
+ (e.g. the ticket is issued in the name of a
+ privelege server), and this entity adds restric-
+ tions on its own authority and delegates the res-
+ tricted authority through a proxy to the client.
+ The client would then present this authorization
+ credential to the application server separately
+ from the authentication exchange.
+
+ Similarly, if one specifies the authorization-data
+ field of a proxy and leaves the host addresses
+ blank, the resulting ticket and session key can be
+ treated as a capability. See [7] for some sug-
+ gested uses of this field.
+
+ The authorization-data field is optional and does
+ not have to be included in a ticket.
+
+
+5.3.2. Authenticators
+
+ An authenticator is a record sent with a ticket to a
+server to certify the client's knowledge of the encryption
+key in the ticket, to help the server detect replays, and to
+help choose a "true session key" to use with the particular
+session. The encoding is encrypted in the ticket's session
+key shared by the client and the server:
+
+-- Unencrypted authenticator
+Authenticator ::= [APPLICATION 2] SEQUENCE {
+ authenticator-vno[0] INTEGER,
+ crealm[1] Realm,
+ cname[2] PrincipalName,
+ cksum[3] Checksum OPTIONAL,
+ cusec[4] INTEGER,
+ ctime[5] KerberosTime,
+ subkey[6] EncryptionKey OPTIONAL,
+ seq-number[7] INTEGER OPTIONAL,
+ authorization-data[8] AuthorizationData OPTIONAL
+}
+
+
+
+Section 5.3.2. - 52 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+authenticator-vno
+ This field specifies the version number for the
+ format of the authenticator. This document speci-
+ fies version 5.
+
+
+crealm and cname
+ These fields are the same as those described for
+ the ticket in section 5.3.1.
+
+
+cksum This field contains a checksum of the the applica-
+ tion data that accompanies the KRB_AP_REQ.
+
+
+cusec This field contains the microsecond part of the
+ client's timestamp. Its value (before encryption)
+ ranges from 0 to 999999. It often appears along
+ with ctime. The two fields are used together to
+ specify a reasonably accurate timestamp.
+
+
+ctime This field contains the current time on the
+ client's host.
+
+
+subkey This field contains the client's choice for an
+ encryption key which is to be used to protect this
+ specific application session. Unless an applica-
+ tion specifies otherwise, if this field is left
+ out the session key from the ticket will be used.
+
+seq-numberThis optional field includes the initial sequence
+ number to be used by the KRB_PRIV or KRB_SAFE mes-
+ sages when sequence numbers are used to detect
+ replays (It may also be used by application
+ specific messages). When included in the authen-
+ ticator this field specifies the initial sequence
+ number for messages from the client to the server.
+ When included in the AP-REP message, the initial
+ sequence number is that for messages from the
+ server to the client. When used in KRB_PRIV or
+ KRB_SAFE messages, it is incremented by one after
+ each message is sent.
+
+ For sequence numbers to adequately support the
+ detection of replays they should be non-repeating,
+ even across connection boundaries. The initial
+ sequence number should be random and uniformly
+ distributed across the full space of possible
+ sequence numbers, so that it cannot be guessed by
+ an attacker and so that it and the successive
+ sequence numbers do not repeat other sequences.
+
+
+
+Section 5.3.2. - 53 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+authorization-data
+ This field is the same as described for the ticket
+ in section 5.3.1. It is optional and will only
+ appear when additional restrictions are to be
+ placed on the use of a ticket, beyond those car-
+ ried in the ticket itself.
+
+5.4. Specifications for the AS and TGS exchanges
+
+ This section specifies the format of the messages used
+in the exchange between the client and the Kerberos server.
+The format of possible error messages appears in section
+5.9.1.
+
+5.4.1. KRB_KDC_REQ definition
+
+ The KRB_KDC_REQ message has no type of its own.
+Instead, its type is one of KRB_AS_REQ or KRB_TGS_REQ
+depending on whether the request is for an initial ticket or
+an additional ticket. In either case, the message is sent
+from the client to the Authentication Server to request
+credentials for a service.
+
+ The message fields are:
+
+AS-REQ ::= [APPLICATION 10] KDC-REQ
+TGS-REQ ::= [APPLICATION 12] KDC-REQ
+
+KDC-REQ ::= SEQUENCE {
+ pvno[1] INTEGER,
+ msg-type[2] INTEGER,
+ padata[3] SEQUENCE OF PA-DATA OPTIONAL,
+ req-body[4] KDC-REQ-BODY
+}
+
+PA-DATA ::= SEQUENCE {
+ padata-type[1] INTEGER,
+ padata-value[2] OCTET STRING,
+ -- might be encoded AP-REQ
+}
+
+KDC-REQ-BODY ::= SEQUENCE {
+ kdc-options[0] KDCOptions,
+ cname[1] PrincipalName OPTIONAL,
+ -- Used only in AS-REQ
+ realm[2] Realm, -- Server's realm
+ -- Also client's in AS-REQ
+ sname[3] PrincipalName OPTIONAL,
+ from[4] KerberosTime OPTIONAL,
+ till[5] KerberosTime OPTIONAL,
+ rtime[6] KerberosTime OPTIONAL,
+ nonce[7] INTEGER,
+ etype[8] SEQUENCE OF INTEGER,
+ -- EncryptionType,
+ -- in preference order
+
+
+Section 5.4.1. - 54 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ addresses[9] HostAddresses OPTIONAL,
+ enc-authorization-data[10] EncryptedData OPTIONAL,
+ -- Encrypted AuthorizationData
+ -- encoding
+ additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
+}
+
+The fields in this message are:
+
+
+pvno This field is included in each message, and speci-
+ fies the protocol version number. This document
+ specifies protocol version 5.
+
+
+msg-type This field indicates the type of a protocol mes-
+ sage. It will almost always be the same as the
+ application identifier associated with a message.
+ It is included to make the identifier more readily
+ accessible to the application. For the KDC-REQ
+ message, this type will be KRB_AS_REQ or
+ KRB_TGS_REQ.
+
+
+padata The padata (pre-authentication data) field con-
+ tains a sequence of authentication information
+ which may be needed before credentials can be
+ issued or decrypted. In the case of requests for
+ additional tickets (KRB_TGS_REQ), this field will
+ include an element with padata-type of PA-TGS-REQ
+ and data of an authentication header (ticket-
+ granting ticket and authenticator). The checksum
+ in the authenticator (which must be collision-
+ proof) is to be computed over the KDC-REQ-BODY
+ encoding. In most requests for initial authenti-
+ cation (KRB_AS_REQ) and most replies (KDC-REP),
+ the padata field will be left out.
+
+ This field may also contain information needed by
+ certain extensions to the Kerberos protocol. For
+ example, it might be used to initially verify the
+ identity of a client before any response is
+ returned. This is accomplished with a padata
+ field with padata-type equal to PA-ENC-TIMESTAMP
+ and padata-value defined as follows:
+
+padata-type ::= PA-ENC-TIMESTAMP
+padata-value ::= EncryptedData -- PA-ENC-TS-ENC
+
+PA-ENC-TS-ENC ::= SEQUENCE {
+ patimestamp[0] KerberosTime, -- client's time
+ pausec[1] INTEGER OPTIONAL
+}
+
+ with patimestamp containing the client's time and
+
+
+Section 5.4.1. - 55 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ pausec containing the microseconds which may be
+ omitted if a client will not generate more than
+ one request per second. The ciphertext (padata-
+ value) consists of the PA-ENC-TS-ENC sequence,
+ encrypted using the client's secret key.
+
+ The padata field can also contain information
+ needed to help the KDC or the client select the
+ key needed for generating or decrypting the
+ response. This form of the padata is useful for
+ supporting the use of certain token cards with
+ Kerberos. The details of such extensions are
+ specified in separate documents. See [11] for
+ additional uses of this field.
+
+padata-type
+ The padata-type element of the padata field indi-
+ cates the way that the padata-value element is to
+ be interpreted. Negative values of padata-type
+ are reserved for unregistered use; non-negative
+ values are used for a registered interpretation of
+ the element type.
+
+
+req-body This field is a placeholder delimiting the extent
+ of the remaining fields. If a checksum is to be
+ calculated over the request, it is calculated over
+ an encoding of the KDC-REQ-BODY sequence which is
+ enclosed within the req-body field.
+
+
+kdc-options
+ This field appears in the KRB_AS_REQ and
+ KRB_TGS_REQ requests to the KDC and indicates the
+ flags that the client wants set on the tickets as
+ well as other information that is to modify the
+ behavior of the KDC. Where appropriate, the name
+ of an option may be the same as the flag that is
+ set by that option. Although in most case, the
+ bit in the options field will be the same as that
+ in the flags field, this is not guaranteed, so it
+ is not acceptable to simply copy the options field
+ to the flags field. There are various checks that
+ must be made before honoring an option anyway.
+
+ The kdc_options field is a bit-field, where the
+ selected options are indicated by the bit being
+ set (1), and the unselected options and reserved
+ fields being reset (0). The encoding of the bits
+ is specified in section 5.2. The options are
+ described in more detail above in section 2. The
+ meanings of the options are:
+
+
+
+
+Section 5.4.1. - 56 - Expires 11 January 1998
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ Bit(s) Name Description
+ 0 RESERVED
+ Reserved for future expansion of this
+ field.
+
+ 1 FORWARDABLE
+ The FORWARDABLE option indicates that
+ the ticket to be issued is to have its
+ forwardable flag set. It may only be
+ set on the initial request, or in a sub-
+ sequent request if the ticket-granting
+ ticket on which it is based is also for-
+ wardable.
+
+ 2 FORWARDED
+ The FORWARDED option is only specified
+ in a request to the ticket-granting
+ server and will only be honored if the
+ ticket-granting ticket in the request
+ has its FORWARDABLE bit set. This
+ option indicates that this is a request
+ for forwarding. The address(es) of the
+ host from which the resulting ticket is
+ to be valid are included in the
+ addresses field of the request.
+
+ 3 PROXIABLE
+ The PROXIABLE option indicates that the
+ ticket to be issued is to have its prox-
+ iable flag set. It may only be set on
+ the initial request, or in a subsequent
+ request if the ticket-granting ticket on
+ which it is based is also proxiable.
+
+ 4 PROXY
+ The PROXY option indicates that this is
+ a request for a proxy. This option will
+ only be honored if the ticket-granting
+ ticket in the request has its PROXIABLE
+ bit set. The address(es) of the host
+ from which the resulting ticket is to be
+ valid are included in the addresses
+ field of the request.
+
+ 5 ALLOW-POSTDATE
+ The ALLOW-POSTDATE option indicates that
+ the ticket to be issued is to have its
+ MAY-POSTDATE flag set. It may only be
+ set on the initial request, or in a sub-
+ sequent request if the ticket-granting
+ ticket on which it is based also has its
+ MAY-POSTDATE flag set.
+
+
+
+
+
+
+
+Section 5.4.1. - 57 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ 6 POSTDATED
+ The POSTDATED option indicates that this
+ is a request for a postdated ticket.
+ This option will only be honored if the
+ ticket-granting ticket on which it is
+ based has its MAY-POSTDATE flag set.
+ The resulting ticket will also have its
+ INVALID flag set, and that flag may be
+ reset by a subsequent request to the KDC
+ after the starttime in the ticket has
+ been reached.
+
+ 7 UNUSED
+ This option is presently unused.
+
+ 8 RENEWABLE
+ The RENEWABLE option indicates that the
+ ticket to be issued is to have its
+ RENEWABLE flag set. It may only be set
+ on the initial request, or when the
+ ticket-granting ticket on which the
+ request is based is also renewable. If
+ this option is requested, then the rtime
+ field in the request contains the
+ desired absolute expiration time for the
+ ticket.
+
+ 9-13 UNUSED
+ These options are presently unused.
+
+ 14 REQUEST-ANONYMOUS
+ The REQUEST-ANONYMOUS option indicates
+ that the ticket to be issued is not to
+ identify the user to which it was
+ issued. Instead, the principal identif-
+ ier is to be generic, as specified by
+ the policy of the realm (e.g. usually
+ anonymous@realm). The purpose of the
+ ticket is only to securely distribute a
+ session key, and not to identify the
+ user. The ANONYMOUS flag on the ticket
+ to be returned should be set. If the
+ local realms policy does not permit
+ anonymous credentials, the request is to
+ be rejected.
+
+ 15-25 RESERVED
+ Reserved for future use.
+
+ 26 DISABLE-TRANSITED-CHECK
+ By default the KDC will check the
+ transited field of a ticket-granting-
+ ticket against the policy of the local
+ realm before it will issue derivative
+ tickets based on the ticket granting
+ ticket. If this flag is set in the
+ request, checking of the transited field
+ is disabled. Tickets issued without the
+ performance of this check will be noted
+ by the reset (0) value of the
+ TRANSITED-POLICY-CHECKED flag,
+ indicating to the application server
+ that the tranisted field must be checked
+ locally. KDC's are encouraged but not
+ required to honor the
+ DISABLE-TRANSITED-CHECK option.
+
+
+
+Section 5.4.1. - 58 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ 27 RENEWABLE-OK
+ The RENEWABLE-OK option indicates that a
+ renewable ticket will be acceptable if a
+ ticket with the requested life cannot
+ otherwise be provided. If a ticket with
+ the requested life cannot be provided,
+ then a renewable ticket may be issued
+ with a renew-till equal to the the
+ requested endtime. The value of the
+ renew-till field may still be limited by
+ local limits, or limits selected by the
+ individual principal or server.
+
+ 28 ENC-TKT-IN-SKEY
+ This option is used only by the ticket-
+ granting service. The ENC-TKT-IN-SKEY
+ option indicates that the ticket for the
+ end server is to be encrypted in the
+ session key from the additional ticket-
+ granting ticket provided.
+
+ 29 RESERVED
+ Reserved for future use.
+
+ 30 RENEW
+ This option is used only by the ticket-
+ granting service. The RENEW option
+ indicates that the present request is
+ for a renewal. The ticket provided is
+ encrypted in the secret key for the
+ server on which it is valid. This
+ option will only be honored if the
+ ticket to be renewed has its RENEWABLE
+ flag set and if the time in its renew-
+ till field has not passed. The ticket
+ to be renewed is passed in the padata
+ field as part of the authentication
+ header.
+
+ 31 VALIDATE
+ This option is used only by the ticket-
+ granting service. The VALIDATE option
+ indicates that the request is to vali-
+ date a postdated ticket. It will only
+ be honored if the ticket presented is
+ postdated, presently has its INVALID
+ flag set, and would be otherwise usable
+ at this time. A ticket cannot be vali-
+ dated before its starttime. The ticket
+ presented for validation is encrypted in
+ the key of the server for which it is
+ valid and is passed in the padata field
+ as part of the authentication header.
+
+cname and sname
+ These fields are the same as those described for
+ the ticket in section 5.3.1. sname may only be
+
+
+Section 5.4.1. - 59 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ absent when the ENC-TKT-IN-SKEY option is speci-
+ fied. If absent, the name of the server is taken
+ from the name of the client in the ticket passed
+ as additional-tickets.
+
+
+enc-authorization-data
+ The enc-authorization-data, if present (and it can
+ only be present in the TGS_REQ form), is an encod-
+ ing of the desired authorization-data encrypted
+ under the sub-session key if present in the
+ Authenticator, or alternatively from the session
+ key in the ticket-granting ticket, both from the
+ padata field in the KRB_AP_REQ.
+
+
+realm This field specifies the realm part of the
+ server's principal identifier. In the AS
+ exchange, this is also the realm part of the
+ client's principal identifier.
+
+
+from This field is included in the KRB_AS_REQ and
+ KRB_TGS_REQ ticket requests when the requested
+ ticket is to be postdated. It specifies the
+ desired start time for the requested ticket.
+
+
+
+till This field contains the expiration date requested
+ by the client in a ticket request. It is option
+ and if omitted the requested ticket is to have the
+ maximum endtime permitted according to KDC policy
+ for the parties to the authentication exchange as
+ limited by expiration date of the ticket granting
+ ticket or other preauthentication credentials.
+
+
+rtime This field is the requested renew-till time sent
+ from a client to the KDC in a ticket request. It
+ is optional.
+
+
+nonce This field is part of the KDC request and
+ response. It it intended to hold a random number
+ generated by the client. If the same number is
+ included in the encrypted response from the KDC,
+ it provides evidence that the response is fresh
+ and has not been replayed by an attacker. Nonces
+ must never be re-used. Ideally, it should be gen-
+ erated randomly, but if the correct time is known,
+ it may suffice[25].
+__________________________
+[25] Note, however, that if the time is used as the
+
+Section 5.4.1. - 60 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+etype This field specifies the desired encryption algo-
+ rithm to be used in the response.
+
+
+addresses This field is included in the initial request for
+ tickets, and optionally included in requests for
+ additional tickets from the ticket-granting
+ server. It specifies the addresses from which the
+ requested ticket is to be valid. Normally it
+ includes the addresses for the client's host. If
+ a proxy is requested, this field will contain
+ other addresses. The contents of this field are
+ usually copied by the KDC into the caddr field of
+ the resulting ticket.
+
+
+additional-tickets
+ Additional tickets may be optionally included in a
+ request to the ticket-granting server. If the
+ ENC-TKT-IN-SKEY option has been specified, then
+ the session key from the additional ticket will be
+ used in place of the server's key to encrypt the
+ new ticket. If more than one option which
+ requires additional tickets has been specified,
+ then the additional tickets are used in the order
+ specified by the ordering of the options bits (see
+ kdc-options, above).
+
+
+ The application code will be either ten (10) or twelve
+(12) depending on whether the request is for an initial
+ticket (AS-REQ) or for an additional ticket (TGS-REQ).
+
+ The optional fields (addresses, authorization-data and
+additional-tickets) are only included if necessary to per-
+form the operation specified in the kdc-options field.
+
+ It should be noted that in KRB_TGS_REQ, the protocol
+version number appears twice and two different message types
+appear: the KRB_TGS_REQ message contains these fields as
+does the authentication header (KRB_AP_REQ) that is passed
+in the padata field.
+
+5.4.2. KRB_KDC_REP definition
+
+ The KRB_KDC_REP message format is used for the reply
+from the KDC for either an initial (AS) request or a subse-
+quent (TGS) request. There is no message type for
+__________________________
+nonce, one must make sure that the workstation time is
+monotonically increasing. If the time is ever reset
+backwards, there is a small, but finite, probability
+that a nonce will be reused.
+
+
+
+Section 5.4.2. - 61 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+KRB_KDC_REP. Instead, the type will be either KRB_AS_REP or
+KRB_TGS_REP. The key used to encrypt the ciphertext part of
+the reply depends on the message type. For KRB_AS_REP, the
+ciphertext is encrypted in the client's secret key, and the
+client's key version number is included in the key version
+number for the encrypted data. For KRB_TGS_REP, the cipher-
+text is encrypted in the sub-session key from the Authenti-
+cator, or if absent, the session key from the ticket-
+granting ticket used in the request. In that case, no ver-
+sion number will be present in the EncryptedData sequence.
+
+ The KRB_KDC_REP message contains the following fields:
+
+AS-REP ::= [APPLICATION 11] KDC-REP
+TGS-REP ::= [APPLICATION 13] KDC-REP
+
+KDC-REP ::= SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ padata[2] SEQUENCE OF PA-DATA OPTIONAL,
+ crealm[3] Realm,
+ cname[4] PrincipalName,
+ ticket[5] Ticket,
+ enc-part[6] EncryptedData
+}
+
+
+EncASRepPart ::= [APPLICATION 25[27]] EncKDCRepPart
+EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
+
+
+
+EncKDCRepPart ::= SEQUENCE {
+ key[0] EncryptionKey,
+ last-req[1] LastReq,
+ nonce[2] INTEGER,
+ key-expiration[3] KerberosTime OPTIONAL,
+ flags[4] TicketFlags,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ srealm[9] Realm,
+ sname[10] PrincipalName,
+ caddr[11] HostAddresses OPTIONAL
+}
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1.
+ msg-type is either KRB_AS_REP or KRB_TGS_REP.
+__________________________
+[27] An application code in the encrypted part of a
+message provides an additional check that the message
+was decrypted properly.
+
+
+Section 5.4.2. - 62 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+padata This field is described in detail in section
+ 5.4.1. One possible use for this field is to
+ encode an alternate "mix-in" string to be used
+ with a string-to-key algorithm (such as is
+ described in section 6.3.2). This ability is use-
+ ful to ease transitions if a realm name needs to
+ change (e.g. when a company is acquired); in such
+ a case all existing password-derived entries in
+ the KDC database would be flagged as needing a
+ special mix-in string until the next password
+ change.
+
+
+crealm, cname, srealm and sname
+ These fields are the same as those described for
+ the ticket in section 5.3.1.
+
+
+ticket The newly-issued ticket, from section 5.3.1.
+
+
+enc-part This field is a place holder for the ciphertext
+ and related information that forms the encrypted
+ part of a message. The description of the
+ encrypted part of the message follows each appear-
+ ance of this field. The encrypted part is encoded
+ as described in section 6.1.
+
+
+key This field is the same as described for the ticket
+ in section 5.3.1.
+
+
+last-req This field is returned by the KDC and specifies
+ the time(s) of the last request by a principal.
+ Depending on what information is available, this
+ might be the last time that a request for a
+ ticket-granting ticket was made, or the last time
+ that a request based on a ticket-granting ticket
+ was successful. It also might cover all servers
+ for a realm, or just the particular server. Some
+ implementations may display this information to
+ the user to aid in discovering unauthorized use of
+ one's identity. It is similar in spirit to the
+ last login time displayed when logging into
+ timesharing systems.
+
+
+nonce This field is described above in section 5.4.1.
+
+
+key-expiration
+ The key-expiration field is part of the response
+ from the KDC and specifies the time that the
+
+
+Section 5.4.2. - 63 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ client's secret key is due to expire. The expira-
+ tion might be the result of password aging or an
+ account expiration. This field will usually be
+ left out of the TGS reply since the response to
+ the TGS request is encrypted in a session key and
+ no client information need be retrieved from the
+ KDC database. It is up to the application client
+ (usually the login program) to take appropriate
+ action (such as notifying the user) if the expira-
+ tion time is imminent.
+
+
+flags, authtime, starttime, endtime, renew-till and caddr
+ These fields are duplicates of those found in the
+ encrypted portion of the attached ticket (see sec-
+ tion 5.3.1), provided so the client may verify
+ they match the intended request and to assist in
+ proper ticket caching. If the message is of type
+ KRB_TGS_REP, the caddr field will only be filled
+ in if the request was for a proxy or forwarded
+ ticket, or if the user is substituting a subset of
+ the addresses from the ticket granting ticket. If
+ the client-requested addresses are not present or
+ not used, then the addresses contained in the
+ ticket will be the same as those included in the
+ ticket-granting ticket.
+
+
+5.5. Client/Server (CS) message specifications
+
+ This section specifies the format of the messages used
+for the authentication of the client to the application
+server.
+
+5.5.1. KRB_AP_REQ definition
+
+ The KRB_AP_REQ message contains the Kerberos protocol
+version number, the message type KRB_AP_REQ, an options
+field to indicate any options in use, and the ticket and
+authenticator themselves. The KRB_AP_REQ message is often
+referred to as the "authentication header".
+
+AP-REQ ::= [APPLICATION 14] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ap-options[2] APOptions,
+ ticket[3] Ticket,
+ authenticator[4] EncryptedData
+}
+
+APOptions ::= BIT STRING {
+ reserved(0),
+ use-session-key(1),
+ mutual-required(2)
+
+
+Section 5.5.1. - 64 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+}
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1.
+ msg-type is KRB_AP_REQ.
+
+
+ap-optionsThis field appears in the application request
+ (KRB_AP_REQ) and affects the way the request is
+ processed. It is a bit-field, where the selected
+ options are indicated by the bit being set (1),
+ and the unselected options and reserved fields
+ being reset (0). The encoding of the bits is
+ specified in section 5.2. The meanings of the
+ options are:
+
+ Bit(s) Name Description
+
+ 0 RESERVED
+ Reserved for future expansion of this
+ field.
+
+ 1 USE-SESSION-KEY
+ The USE-SESSION-KEY option indicates
+ that the ticket the client is presenting
+ to a server is encrypted in the session
+ key from the server's ticket-granting
+ ticket. When this option is not speci-
+ fied, the ticket is encrypted in the
+ server's secret key.
+
+ 2 MUTUAL-REQUIRED
+ The MUTUAL-REQUIRED option tells the
+ server that the client requires mutual
+ authentication, and that it must respond
+ with a KRB_AP_REP message.
+
+ 3-31 RESERVED
+ Reserved for future use.
+
+
+
+ticket This field is a ticket authenticating the client
+ to the server.
+
+
+authenticator
+ This contains the authenticator, which includes
+ the client's choice of a subkey. Its encoding is
+ described in section 5.3.2.
+
+5.5.2. KRB_AP_REP definition
+
+ The KRB_AP_REP message contains the Kerberos protocol
+version number, the message type, and an encrypted time-
+stamp. The message is sent in in response to an application
+request (KRB_AP_REQ) where the mutual authentication option
+
+
+Section 5.5.2. - 65 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+has been selected in the ap-options field.
+
+AP-REP ::= [APPLICATION 15] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[2] EncryptedData
+}
+
+EncAPRepPart ::= [APPLICATION 27[29]] SEQUENCE {
+ ctime[0] KerberosTime,
+ cusec[1] INTEGER,
+ subkey[2] EncryptionKey OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL
+}
+
+The encoded EncAPRepPart is encrypted in the shared session
+key of the ticket. The optional subkey field can be used in
+an application-arranged negotiation to choose a per associa-
+tion session key.
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1.
+ msg-type is KRB_AP_REP.
+
+
+enc-part This field is described above in section 5.4.2.
+
+
+ctime This field contains the current time on the
+ client's host.
+
+
+cusec This field contains the microsecond part of the
+ client's timestamp.
+
+
+subkey This field contains an encryption key which is to
+ be used to protect this specific application ses-
+ sion. See section 3.2.6 for specifics on how this
+ field is used to negotiate a key. Unless an
+ application specifies otherwise, if this field is
+ left out, the sub-session key from the authentica-
+ tor, or if also left out, the session key from the
+ ticket will be used.
+
+
+
+__________________________
+[29] An application code in the encrypted part of a
+message provides an additional check that the message
+was decrypted properly.
+
+
+
+Section 5.5.2. - 66 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+5.5.3. Error message reply
+
+ If an error occurs while processing the application
+request, the KRB_ERROR message will be sent in response.
+See section 5.9.1 for the format of the error message. The
+cname and crealm fields may be left out if the server cannot
+determine their appropriate values from the corresponding
+KRB_AP_REQ message. If the authenticator was decipherable,
+the ctime and cusec fields will contain the values from it.
+
+5.6. KRB_SAFE message specification
+
+ This section specifies the format of a message that can
+be used by either side (client or server) of an application
+to send a tamper-proof message to its peer. It presumes
+that a session key has previously been exchanged (for exam-
+ple, by using the KRB_AP_REQ/KRB_AP_REP messages).
+
+5.6.1. KRB_SAFE definition
+
+ The KRB_SAFE message contains user data along with a
+collision-proof checksum keyed with the last encryption key
+negotiated via subkeys, or the session key if no negotiation
+has occured. The message fields are:
+
+KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ safe-body[2] KRB-SAFE-BODY,
+ cksum[3] Checksum
+}
+
+KRB-SAFE-BODY ::= SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+}
+
+
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1.
+ msg-type is KRB_SAFE.
+
+
+safe-body This field is a placeholder for the body of the
+ KRB-SAFE message. It is to be encoded separately
+ and then have the checksum computed over it, for
+ use in the cksum field.
+
+
+
+Section 5.6.1. - 67 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+cksum This field contains the checksum of the applica-
+ tion data. Checksum details are described in sec-
+ tion 6.4. The checksum is computed over the
+ encoding of the KRB-SAFE-BODY sequence.
+
+
+user-data This field is part of the KRB_SAFE and KRB_PRIV
+ messages and contain the application specific data
+ that is being passed from the sender to the reci-
+ pient.
+
+
+timestamp This field is part of the KRB_SAFE and KRB_PRIV
+ messages. Its contents are the current time as
+ known by the sender of the message. By checking
+ the timestamp, the recipient of the message is
+ able to make sure that it was recently generated,
+ and is not a replay.
+
+
+usec This field is part of the KRB_SAFE and KRB_PRIV
+ headers. It contains the microsecond part of the
+ timestamp.
+
+
+seq-number
+ This field is described above in section 5.3.2.
+
+
+s-address This field specifies the address in use by the
+ sender of the message.
+
+
+r-address This field specifies the address in use by the
+ recipient of the message. It may be omitted for
+ some uses (such as broadcast protocols), but the
+ recipient may arbitrarily reject such messages.
+ This field along with s-address can be used to
+ help detect messages which have been incorrectly
+ or maliciously delivered to the wrong recipient.
+
+5.7. KRB_PRIV message specification
+
+ This section specifies the format of a message that can
+be used by either side (client or server) of an application
+to securely and privately send a message to its peer. It
+presumes that a session key has previously been exchanged
+(for example, by using the KRB_AP_REQ/KRB_AP_REP messages).
+
+5.7.1. KRB_PRIV definition
+
+ The KRB_PRIV message contains user data encrypted in
+the Session Key. The message fields are:
+
+__________________________
+[31] An application code in the encrypted part of a
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+
+KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[3] EncryptedData
+}
+
+EncKrbPrivPart ::= [APPLICATION 28[31]] SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL, -- sender's addr
+ r-address[5] HostAddress OPTIONAL -- recip's addr
+}
+
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1.
+ msg-type is KRB_PRIV.
+
+
+enc-part This field holds an encoding of the EncKrbPrivPart
+ sequence encrypted under the session key[32].
+ This encrypted encoding is used for the enc-part
+ field of the KRB-PRIV message. See section 6 for
+ the format of the ciphertext.
+
+
+user-data, timestamp, usec, s-address and r-address
+ These fields are described above in section 5.6.1.
+
+
+seq-number
+ This field is described above in section 5.3.2.
+
+5.8. KRB_CRED message specification
+
+ This section specifies the format of a message that can
+be used to send Kerberos credentials from one principal to
+__________________________
+message provides an additional check that the message
+was decrypted properly.
+[32] If supported by the encryption method in use, an
+initialization vector may be passed to the encryption
+procedure, in order to achieve proper cipher chaining.
+The initialization vector might come from the last
+block of the ciphertext from the previous KRB_PRIV mes-
+sage, but it is the application's choice whether or not
+to use such an initialization vector. If left out, the
+default initialization vector for the encryption algo-
+rithm will be used.
+
+
+Section 5.8. - 69 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+another. It is presented here to encourage a common mechan-
+ism to be used by applications when forwarding tickets or
+providing proxies to subordinate servers. It presumes that
+a session key has already been exchanged perhaps by using
+the KRB_AP_REQ/KRB_AP_REP messages.
+
+5.8.1. KRB_CRED definition
+
+ The KRB_CRED message contains a sequence of tickets to
+be sent and information needed to use the tickets, including
+the session key from each. The information needed to use
+the tickets is encrypted under an encryption key previously
+exchanged or transferred alongside the KRB_CRED message.
+The message fields are:
+
+KRB-CRED ::= [APPLICATION 22] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER, -- KRB_CRED
+ tickets[2] SEQUENCE OF Ticket,
+ enc-part[3] EncryptedData
+}
+
+EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
+ ticket-info[0] SEQUENCE OF KrbCredInfo,
+ nonce[1] INTEGER OPTIONAL,
+ timestamp[2] KerberosTime OPTIONAL,
+ usec[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+}
+
+KrbCredInfo ::= SEQUENCE {
+ key[0] EncryptionKey,
+ prealm[1] Realm OPTIONAL,
+ pname[2] PrincipalName OPTIONAL,
+ flags[3] TicketFlags OPTIONAL,
+ authtime[4] KerberosTime OPTIONAL,
+ starttime[5] KerberosTime OPTIONAL,
+ endtime[6] KerberosTime OPTIONAL
+ renew-till[7] KerberosTime OPTIONAL,
+ srealm[8] Realm OPTIONAL,
+ sname[9] PrincipalName OPTIONAL,
+ caddr[10] HostAddresses OPTIONAL
+}
+
+
+
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1.
+ msg-type is KRB_CRED.
+
+
+
+
+Section 5.8.1. - 70 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+tickets
+ These are the tickets obtained from the KDC
+ specifically for use by the intended recipient.
+ Successive tickets are paired with the correspond-
+ ing KrbCredInfo sequence from the enc-part of the
+ KRB-CRED message.
+
+
+enc-part This field holds an encoding of the EncKrbCredPart
+ sequence encrypted under the session key shared
+ between the sender and the intended recipient.
+ This encrypted encoding is used for the enc-part
+ field of the KRB-CRED message. See section 6 for
+ the format of the ciphertext.
+
+
+nonce If practical, an application may require the
+ inclusion of a nonce generated by the recipient of
+ the message. If the same value is included as the
+ nonce in the message, it provides evidence that
+ the message is fresh and has not been replayed by
+ an attacker. A nonce must never be re-used; it
+ should be generated randomly by the recipient of
+ the message and provided to the sender of the mes-
+ sage in an application specific manner.
+
+
+timestamp and usec
+
+ These fields specify the time that the KRB-CRED
+ message was generated. The time is used to pro-
+ vide assurance that the message is fresh.
+
+
+s-address and r-address
+ These fields are described above in section 5.6.1.
+ They are used optionally to provide additional
+ assurance of the integrity of the KRB-CRED mes-
+ sage.
+
+
+key This field exists in the corresponding ticket
+ passed by the KRB-CRED message and is used to pass
+ the session key from the sender to the intended
+ recipient. The field's encoding is described in
+ section 6.2.
+
+ The following fields are optional. If present, they
+can be associated with the credentials in the remote ticket
+file. If left out, then it is assumed that the recipient of
+the credentials already knows their value.
+
+
+prealm and pname
+
+
+Section 5.8.1. - 71 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ The name and realm of the delegated principal
+ identity.
+
+
+flags, authtime, starttime, endtime, renew-till, srealm,
+ sname, and caddr
+ These fields contain the values of the correspond-
+ ing fields from the ticket found in the ticket
+ field. Descriptions of the fields are identical
+ to the descriptions in the KDC-REP message.
+
+5.9. Error message specification
+
+ This section specifies the format for the KRB_ERROR
+message. The fields included in the message are intended to
+return as much information as possible about an error. It
+is not expected that all the information required by the
+fields will be available for all types of errors. If the
+appropriate information is not available when the message is
+composed, the corresponding field will be left out of the
+message.
+
+ Note that since the KRB_ERROR message is not protected
+by any encryption, it is quite possible for an intruder to
+synthesize or modify such a message. In particular, this
+means that the client should not use any fields in this mes-
+sage for security-critical purposes, such as setting a sys-
+tem clock or generating a fresh authenticator. The message
+can be useful, however, for advising a user on the reason
+for some failure.
+
+5.9.1. KRB_ERROR definition
+
+ The KRB_ERROR message consists of the following fields:
+
+KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ctime[2] KerberosTime OPTIONAL,
+ cusec[3] INTEGER OPTIONAL,
+ stime[4] KerberosTime,
+ susec[5] INTEGER,
+ error-code[6] INTEGER,
+ crealm[7] Realm OPTIONAL,
+ cname[8] PrincipalName OPTIONAL,
+ realm[9] Realm, -- Correct realm
+ sname[10] PrincipalName, -- Correct name
+ e-text[11] GeneralString OPTIONAL,
+ e-data[12] OCTET STRING OPTIONAL,
+ e-cksum[13] Checksum OPTIONAL
+}
+
+
+
+
+
+Section 5.9.1. - 72 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1.
+ msg-type is KRB_ERROR.
+
+
+ctime This field is described above in section 5.4.1.
+
+
+
+cusec This field is described above in section 5.5.2.
+
+
+stime This field contains the current time on the
+ server. It is of type KerberosTime.
+
+
+susec This field contains the microsecond part of the
+ server's timestamp. Its value ranges from 0 to
+ 999999. It appears along with stime. The two
+ fields are used in conjunction to specify a rea-
+ sonably accurate timestamp.
+
+
+error-codeThis field contains the error code returned by
+ Kerberos or the server when a request fails. To
+ interpret the value of this field see the list of
+ error codes in section 8. Implementations are
+ encouraged to provide for national language sup-
+ port in the display of error messages.
+
+
+crealm, cname, srealm and sname
+ These fields are described above in section 5.3.1.
+
+
+e-text This field contains additional text to help
+ explain the error code associated with the failed
+ request (for example, it might include a principal
+ name which was unknown).
+
+
+e-data This field contains additional data about the
+ error for use by the application to help it
+ recover from or handle the error. If the error-
+ code is KDC_ERR_PREAUTH_REQUIRED, then the e-data
+ field will contain an encoding of a sequence of
+ padata fields, each corresponding to an acceptable
+ pre-authentication method and optionally contain-
+ ing data for the method:
+
+
+e-cksum This field contains an optional checksum for the
+ KRB-ERROR message. The checksum is calculated
+ over the Kerberos ASN.1 encoding of the KRB-ERROR
+
+
+Section 5.9.1. - 73 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ message with the checksum absent. The checksum is
+ then added to the KRB-ERROR structure and the mes-
+ sage is re-encoded. The Checksum should be calcu-
+ lated using the session key from the ticket grant-
+ ing ticket or service ticket, where available. If
+ the error is in response to a TGS or AP request,
+ the checksum should be calculated uing the the
+ session key from the client's ticket. If the
+ error is in response to an AS request, then the
+ checksum should be calulated using the client's
+ secret key ONLY if there has been suitable preau-
+ thentication to prove knowledge of the secret key
+ by the client[33]. If a checksum can not be com-
+ puted because the key to be used is not available,
+ no checksum will be included.
+
+ METHOD-DATA ::= SEQUENCE of PA-DATA
+
+
+ If the error-code is KRB_AP_ERR_METHOD, then the
+ e-data field will contain an encoding of the fol-
+ lowing sequence:
+
+ METHOD-DATA ::= SEQUENCE {
+ method-type[0] INTEGER,
+ method-data[1] OCTET STRING OPTIONAL
+ }
+
+ method-type will indicate the required alternate
+ method; method-data will contain any required
+ additional information.
+
+
+
+6. Encryption and Checksum Specifications
+
+The Kerberos protocols described in this document are
+designed to use stream encryption ciphers, which can be
+simulated using commonly available block encryption ciphers,
+such as the Data Encryption Standard, [12] in conjunction
+with block chaining and checksum methods [13]. Encryption
+is used to prove the identities of the network entities par-
+ticipating in message exchanges. The Key Distribution
+Center for each realm is trusted by all principals
+registered in that realm to store a secret key in confi-
+dence. Proof of knowledge of this secret key is used to
+verify the authenticity of a principal.
+
+ The KDC uses the principal's secret key (in the AS
+__________________________
+[33] This prevents an attacker who generates an in-
+correct AS request from obtaining verifiable plaintext
+for use in an off-line password guessing attack.
+
+
+Section 6. - 74 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+exchange) or a shared session key (in the TGS exchange) to
+encrypt responses to ticket requests; the ability to obtain
+the secret key or session key implies the knowledge of the
+appropriate keys and the identity of the KDC. The ability
+of a principal to decrypt the KDC response and present a
+Ticket and a properly formed Authenticator (generated with
+the session key from the KDC response) to a service verifies
+the identity of the principal; likewise the ability of the
+service to extract the session key from the Ticket and prove
+its knowledge thereof in a response verifies the identity of
+the service.
+
+ The Kerberos protocols generally assume that the
+encryption used is secure from cryptanalysis; however, in
+some cases, the order of fields in the encrypted portions of
+messages are arranged to minimize the effects of poorly
+chosen keys. It is still important to choose good keys. If
+keys are derived from user-typed passwords, those passwords
+need to be well chosen to make brute force attacks more dif-
+ficult. Poorly chosen keys still make easy targets for
+intruders.
+
+ The following sections specify the encryption and
+checksum mechanisms currently defined for Kerberos. The
+encodings, chaining, and padding requirements for each are
+described. For encryption methods, it is often desirable to
+place random information (often referred to as a confounder)
+at the start of the message. The requirements for a con-
+founder are specified with each encryption mechanism.
+
+ Some encryption systems use a block-chaining method to
+improve the the security characteristics of the ciphertext.
+However, these chaining methods often don't provide an
+integrity check upon decryption. Such systems (such as DES
+in CBC mode) must be augmented with a checksum of the plain-
+text which can be verified at decryption and used to detect
+any tampering or damage. Such checksums should be good at
+detecting burst errors in the input. If any damage is
+detected, the decryption routine is expected to return an
+error indicating the failure of an integrity check. Each
+encryption type is expected to provide and verify an
+appropriate checksum. The specification of each encryption
+method sets out its checksum requirements.
+
+ Finally, where a key is to be derived from a user's
+password, an algorithm for converting the password to a key
+of the appropriate type is included. It is desirable for
+the string to key function to be one-way, and for the map-
+ping to be different in different realms. This is important
+because users who are registered in more than one realm will
+often use the same password in each, and it is desirable
+that an attacker compromising the Kerberos server in one
+realm not obtain or derive the user's key in another.
+
+
+
+Section 6. - 75 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ For an discussion of the integrity characteristics of
+the candidate encryption and checksum methods considered for
+Kerberos, the the reader is referred to [14].
+
+6.1. Encryption Specifications
+
+ The following ASN.1 definition describes all encrypted
+messages. The enc-part field which appears in the unen-
+crypted part of messages in section 5 is a sequence consist-
+ing of an encryption type, an optional key version number,
+and the ciphertext.
+
+
+EncryptedData ::= SEQUENCE {
+ etype[0] INTEGER, -- EncryptionType
+ kvno[1] INTEGER OPTIONAL,
+ cipher[2] OCTET STRING -- ciphertext
+}
+
+
+etype This field identifies which encryption algorithm
+ was used to encipher the cipher. Detailed specif-
+ ications for selected encryption types appear
+ later in this section.
+
+
+kvno This field contains the version number of the key
+ under which data is encrypted. It is only present
+ in messages encrypted under long lasting keys,
+ such as principals' secret keys.
+
+
+cipher This field contains the enciphered text, encoded
+ as an OCTET STRING.
+
+
+ The cipher field is generated by applying the specified
+encryption algorithm to data composed of the message and
+algorithm-specific inputs. Encryption mechanisms defined
+for use with Kerberos must take sufficient measures to
+guarantee the integrity of the plaintext, and we recommend
+they also take measures to protect against precomputed dic-
+tionary attacks. If the encryption algorithm is not itself
+capable of doing so, the protections can often be enhanced
+by adding a checksum and a confounder.
+
+ The suggested format for the data to be encrypted
+includes a confounder, a checksum, the encoded plaintext,
+and any necessary padding. The msg-seq field contains the
+part of the protocol message described in section 5 which is
+to be encrypted. The confounder, checksum, and padding are
+all untagged and untyped, and their length is exactly suffi-
+cient to hold the appropriate item. The type and length is
+implicit and specified by the particular encryption type
+
+
+Section 6.1. - 76 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+being used (etype). The format for the data to be encrypted
+is described in the following diagram:
+
+ +-----------+----------+-------------+-----+
+ |confounder | check | msg-seq | pad |
+ +-----------+----------+-------------+-----+
+
+The format cannot be described in ASN.1, but for those who
+prefer an ASN.1-like notation:
+
+CipherText ::= ENCRYPTED SEQUENCE {
+ confounder[0] UNTAGGED[35] OCTET STRING(conf_length) OPTIONAL,
+ check[1] UNTAGGED OCTET STRING(checksum_length) OPTIONAL,
+ msg-seq[2] MsgSequence,
+ pad UNTAGGED OCTET STRING(pad_length) OPTIONAL
+}
+
+
+ One generates a random confounder of the appropriate
+length, placing it in confounder; zeroes out check; calcu-
+lates the appropriate checksum over confounder, check, and
+msg-seq, placing the result in check; adds the necessary
+padding; then encrypts using the specified encryption type
+and the appropriate key.
+
+ Unless otherwise specified, a definition of an encryp-
+tion algorithm that specifies a checksum, a length for the
+confounder field, or an octet boundary for padding uses this
+ciphertext format[36]. Those fields which are not specified
+will be omitted.
+
+ In the interest of allowing all implementations using a
+__________________________
+[35] In the above specification, UNTAGGED OCTET
+STRING(length) is the notation for an octet string with
+its tag and length removed. It is not a valid ASN.1
+type. The tag bits and length must be removed from the
+confounder since the purpose of the confounder is so
+that the message starts with random data, but the tag
+and its length are fixed. For other fields, the length
+and tag would be redundant if they were included be-
+cause they are specified by the encryption type.
+[36] The ordering of the fields in the CipherText is
+important. Additionally, messages encoded in this for-
+mat must include a length as part of the msg-seq field.
+This allows the recipient to verify that the message
+has not been truncated. Without a length, an attacker
+could use a chosen plaintext attack to generate a mes-
+sage which could be truncated, while leaving the check-
+sum intact. Note that if the msg-seq is an encoding of
+an ASN.1 SEQUENCE or OCTET STRING, then the length is
+part of that encoding.
+
+
+
+Section 6.1. - 77 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+particular encryption type to communicate with all others
+using that type, the specification of an encryption type
+defines any checksum that is needed as part of the encryp-
+tion process. If an alternative checksum is to be used, a
+new encryption type must be defined.
+
+ Some cryptosystems require additional information
+beyond the key and the data to be encrypted. For example,
+DES, when used in cipher-block-chaining mode, requires an
+initialization vector. If required, the description for
+each encryption type must specify the source of such addi-
+tional information.
+
+6.2. Encryption Keys
+
+ The sequence below shows the encoding of an encryption
+key:
+
+ EncryptionKey ::= SEQUENCE {
+ keytype[0] INTEGER,
+ keyvalue[1] OCTET STRING
+ }
+
+
+keytype This field specifies the type of encryption key
+ that follows in the keyvalue field. It will
+ almost always correspond to the encryption algo-
+ rithm used to generate the EncryptedData, though
+ more than one algorithm may use the same type of
+ key (the mapping is many to one). This might hap-
+ pen, for example, if the encryption algorithm uses
+ an alternate checksum algorithm for an integrity
+ check, or a different chaining mechanism.
+
+
+keyvalue This field contains the key itself, encoded as an
+ octet string.
+
+ All negative values for the encryption key type are
+reserved for local use. All non-negative values are
+reserved for officially assigned type fields and interpreta-
+tions.
+
+6.3. Encryption Systems
+
+6.3.1. The NULL Encryption System (null)
+
+ If no encryption is in use, the encryption system is
+said to be the NULL encryption system. In the NULL encryp-
+tion system there is no checksum, confounder or padding.
+The ciphertext is simply the plaintext. The NULL Key is
+used by the null encryption system and is zero octets in
+length, with keytype zero (0).
+
+
+
+Section 6.3.1. - 78 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+6.3.2. DES in CBC mode with a CRC-32 checksum (des-cbc-crc)
+
+ The des-cbc-crc encryption mode encrypts information
+under the Data Encryption Standard [12] using the cipher
+block chaining mode [13]. A CRC-32 checksum (described in
+ISO 3309 [15]) is applied to the confounder and message
+sequence (msg-seq) and placed in the cksum field. DES
+blocks are 8 bytes. As a result, the data to be encrypted
+(the concatenation of confounder, checksum, and message)
+must be padded to an 8 byte boundary before encryption. The
+details of the encryption of this data are identical to
+those for the des-cbc-md5 encryption mode.
+
+ Note that, since the CRC-32 checksum is not collision-
+proof, an attacker could use a probabilistic chosen-
+plaintext attack to generate a valid message even if a con-
+founder is used [14]. The use of collision-proof checksums
+is recommended for environments where such attacks represent
+a significant threat. The use of the CRC-32 as the checksum
+for ticket or authenticator is no longer mandated as an
+interoperability requirement for Kerberos Version 5 Specifi-
+cation 1 (See section 9.1 for specific details).
+
+
+6.3.3. DES in CBC mode with an MD4 checksum (des-cbc-md4)
+
+ The des-cbc-md4 encryption mode encrypts information
+under the Data Encryption Standard [12] using the cipher
+block chaining mode [13]. An MD4 checksum (described in
+[16]) is applied to the confounder and message sequence
+(msg-seq) and placed in the cksum field. DES blocks are 8
+bytes. As a result, the data to be encrypted (the concate-
+nation of confounder, checksum, and message) must be padded
+to an 8 byte boundary before encryption. The details of the
+encryption of this data are identical to those for the des-
+cbc-md5 encryption mode.
+
+
+6.3.4. DES in CBC mode with an MD5 checksum (des-cbc-md5)
+
+ The des-cbc-md5 encryption mode encrypts information
+under the Data Encryption Standard [12] using the cipher
+block chaining mode [13]. An MD5 checksum (described in
+[17].) is applied to the confounder and message sequence
+(msg-seq) and placed in the cksum field. DES blocks are 8
+bytes. As a result, the data to be encrypted (the concate-
+nation of confounder, checksum, and message) must be padded
+to an 8 byte boundary before encryption.
+
+ Plaintext and DES ciphtertext are encoded as 8-octet
+blocks which are concatenated to make the 64-bit inputs for
+the DES algorithms. The first octet supplies the 8 most
+significant bits (with the octet's MSbit used as the DES
+input block's MSbit, etc.), the second octet the next 8
+
+
+Section 6.3.4. - 79 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+bits, ..., and the eighth octet supplies the 8 least signi-
+ficant bits.
+
+ Encryption under DES using cipher block chaining
+requires an additional input in the form of an initializa-
+tion vector. Unless otherwise specified, zero should be
+used as the initialization vector. Kerberos' use of DES
+requires an 8-octet confounder.
+
+ The DES specifications identify some "weak" and "semi-
+weak" keys; those keys shall not be used for encrypting mes-
+sages for use in Kerberos. Additionally, because of the way
+that keys are derived for the encryption of checksums, keys
+shall not be used that yield "weak" or "semi-weak" keys when
+eXclusive-ORed with the constant F0F0F0F0F0F0F0F0.
+
+ A DES key is 8 octets of data, with keytype one (1).
+This consists of 56 bits of key, and 8 parity bits (one per
+octet). The key is encoded as a series of 8 octets written
+in MSB-first order. The bits within the key are also
+encoded in MSB order. For example, if the encryption key is
+(B1,B2,...,B7,P1,B8,...,B14,P2,B15,...,B49,P7,B50,...,B56,P8)
+where B1,B2,...,B56 are the key bits in MSB order, and
+P1,P2,...,P8 are the parity bits, the first octet of the key
+would be B1,B2,...,B7,P1 (with B1 as the MSbit). [See the
+FIPS 81 introduction for reference.]
+
+ To generate a DES key from a text string (password),
+the text string normally must have the realm and each com-
+ponent of the principal's name appended[37], then padded
+with ASCII nulls to an 8 byte boundary. This string is then
+fan-folded and eXclusive-ORed with itself to form an 8 byte
+DES key. The parity is corrected on the key, and it is used
+to generate a DES CBC checksum on the initial string (with
+the realm and name appended). Next, parity is corrected on
+the CBC checksum. If the result matches a "weak" or "semi-
+weak" key as described in the DES specification, it is
+eXclusive-ORed with the constant 00000000000000F0. Finally,
+the result is returned as the key. Pseudocode follows:
+
+ string_to_key(string,realm,name) {
+ odd = 1;
+ s = string + realm;
+ for(each component in name) {
+ s = s + component;
+ }
+ tempkey = NULL;
+ pad(s); /* with nulls to 8 byte boundary */
+ for(8byteblock in s) {
+__________________________
+[37] In some cases, it may be necessary to use a dif-
+ferent "mix-in" string for compatibility reasons; see
+the discussion of padata in section 5.4.2.
+
+
+Section 6.3.4. - 80 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ if(odd == 0) {
+ odd = 1;
+ reverse(8byteblock)
+ }
+ else odd = 0;
+ tempkey = tempkey XOR 8byteblock;
+ }
+ fixparity(tempkey);
+ key = DES-CBC-check(s,tempkey);
+ fixparity(key);
+ if(is_weak_key_key(key))
+ key = key XOR 0xF0;
+ return(key);
+ }
+
+6.3.5. Triple DES EDE in outer CBC mode with an SHA1 check-
+sum (des3-cbc-sha1)
+
+ The des3-cbc-sha1 encryption encodes information using
+three Data Encryption Standard transformations with three
+DES keys. The first key is used to perform a DES ECB
+encryption on an eight-octet data block using the first DES
+key, followed by a DES ECB decryption of the result using
+the second DES key, and a DES ECB encryption of the result
+using the third DES key. Because DES blocks are 8 bytes,
+the data to be encrypted (the concatenation of confounder,
+checksum, and message) must first be padded to an 8 byte
+boundary before encryption. To support the outer CBC mode,
+the input is padded an eight-octet boundary. The first 8
+octets of the data to be encrypted (the confounder) is
+exclusive-ored with an initialization vector of zero and
+then ECB encrypted using triple DES as described above.
+Subsequent blocks of 8 octets are exclusive-ored with the
+ciphertext produced by the encryption on the previous block
+before ECB encryption.
+
+ An HMAC-SHA1 checksum (described in [18].) is applied
+to the confounder and message sequence (msg-seq) and placed
+in the cksum field.
+
+ Plaintext are encoded as 8-octet blocks which are con-
+catenated to make the 64-bit inputs for the DES algorithms.
+The first octet supplies the 8 most significant bits (with
+the octet's MSbit used as the DES input block's MSbit,
+etc.), the second octet the next 8 bits, ..., and the eighth
+octet supplies the 8 least significant bits.
+
+ Encryption under Triple DES using cipher block chaining
+requires an additional input in the form of an initializa-
+tion vector. Unless otherwise specified, zero should be
+used as the initialization vector. Kerberos' use of DES
+requires an 8-octet confounder.
+
+ The DES specifications identify some "weak" and "semi-
+
+
+Section 6.3.5. - 81 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+weak" keys; those keys shall not be used for encrypting mes-
+sages for use in Kerberos. Additionally, because of the way
+that keys are derived for the encryption of checksums, keys
+shall not be used that yield "weak" or "semi-weak" keys when
+eXclusive-ORed with the constant F0F0F0F0F0F0F0F0.
+
+ A Triple DES key is 24 octets of data, with keytype
+seven (7). This consists of 168 bits of key, and 24 parity
+bits (one per octet). The key is encoded as a series of 24
+octets written in MSB-first order, with the first 8 octets
+treated as the first DES key, the second 8 octets as the
+second key, and the third 8 octets the third DES key. The
+bits within each key are also encoded in MSB order. For
+example, if the encryption key is
+(B1,B2,...,B7,P1,B8,...,B14,P2,B15,...,B49,P7,B50,...,B56,P8)
+where B1,B2,...,B56 are the key bits in MSB order, and
+P1,P2,...,P8 are the parity bits, the first octet of the key
+would be B1,B2,...,B7,P1 (with B1 as the MSbit). [See the
+FIPS 81 introduction for reference.]
+
+ To generate a DES key from a text string (password),
+the text string normally must have the realm and each com-
+ponent of the principal's name appended[38],
+
+ The input string (with any salt data appended to it) is
+n-folded into a 24 octet (192 bit) string. To n-fold a
+number X, replicate the input value to a length that is the
+least common multiple of n and the length of X. Before each
+repetition, the input X is rotated to the right by 13 bit
+positions. The successive n-bit chunks are added together
+using 1's-complement addition (addition with end-around
+carry) to yield a n-bit result. (This transformation was
+proposed by Richard Basch)
+
+ Each successive set of 8 octets is taken as a DES key,
+and its parity is adjusted in the same manner as previously
+described. If any of the three sets of 8 octets match a
+"weak" or "semi-weak" key as described in the DES specifica-
+tion, that chunk is eXclusive-ORed with the constant
+00000000000000F0. The resulting DES keys are then used in
+sequence to perform a Triple-DES CBC encryption of the n-
+folded input string (appended with any salt data), using a
+zero initial vector. Parity, weak, and semi-weak keys are
+once again corrected and the result is returned as the 24
+octet key.
+
+ Pseudocode follows:
+
+ string_to_key(string,realm,name) {
+__________________________
+[38] In some cases, it may be necessary to use a dif-
+ferent "mix-in" string for compatibility reasons; see
+the discussion of padata in section 5.4.2.
+
+
+Section 6.3.5. - 82 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ s = string + realm;
+ for(each component in name) {
+ s = s + component;
+ }
+ tkey[24] = fold(s);
+ fixparity(tkey);
+ if(isweak(tkey[0-7])) tkey[0-7] = tkey[0-7] XOR 0xF0;
+ if(isweak(tkey[8-15])) tkey[8-15] = tkey[8-15] XOR 0xF0;
+ if(is_weak(tkey[16-23])) tkey[16-23] = tkey[16-23] XOR 0xF0;
+ key[24] = 3DES-CBC(data=fold(s),key=tkey,iv=0);
+ fixparity(key);
+ if(is_weak(key[0-7])) key[0-7] = key[0-7] XOR 0xF0;
+ if(is_weak(key[8-15])) key[8-15] = key[8-15] XOR 0xF0;
+ if(is_weak(key[16-23])) key[16-23] = key[16-23] XOR 0xF0;
+ return(key);
+ }
+
+6.4. Checksums
+
+ The following is the ASN.1 definition used for a check-
+sum:
+
+ Checksum ::= SEQUENCE {
+ cksumtype[0] INTEGER,
+ checksum[1] OCTET STRING
+ }
+
+
+cksumtype This field indicates the algorithm used to gen-
+ erate the accompanying checksum.
+
+checksum This field contains the checksum itself, encoded
+ as an octet string.
+
+ Detailed specification of selected checksum types
+appear later in this section. Negative values for the
+checksum type are reserved for local use. All non-negative
+values are reserved for officially assigned type fields and
+interpretations.
+
+ Checksums used by Kerberos can be classified by two
+properties: whether they are collision-proof, and whether
+they are keyed. It is infeasible to find two plaintexts
+which generate the same checksum value for a collision-proof
+checksum. A key is required to perturb or initialize the
+algorithm in a keyed checksum. To prevent message-stream
+modification by an active attacker, unkeyed checksums should
+only be used when the checksum and message will be subse-
+quently encrypted (e.g. the checksums defined as part of the
+encryption algorithms covered earlier in this section).
+
+ Collision-proof checksums can be made tamper-proof if
+the checksum value is encrypted before inclusion in a mes-
+sage. In such cases, the composition of the checksum and
+
+
+Section 6.4. - 83 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+the encryption algorithm must be considered a separate
+checksum algorithm (e.g. RSA-MD5 encrypted using DES is a
+new checksum algorithm of type RSA-MD5-DES). For most keyed
+checksums, as well as for the encrypted forms of unkeyed
+collision-proof checksums, Kerberos prepends a confounder
+before the checksum is calculated.
+
+6.4.1. The CRC-32 Checksum (crc32)
+
+ The CRC-32 checksum calculates a checksum based on a
+cyclic redundancy check as described in ISO 3309 [15]. The
+resulting checksum is four (4) octets in length. The CRC-32
+is neither keyed nor collision-proof. The use of this
+checksum is not recommended. An attacker using a proba-
+bilistic chosen-plaintext attack as described in [14] might
+be able to generate an alternative message that satisfies
+the checksum. The use of collision-proof checksums is
+recommended for environments where such attacks represent a
+significant threat.
+
+6.4.2. The RSA MD4 Checksum (rsa-md4)
+
+ The RSA-MD4 checksum calculates a checksum using the
+RSA MD4 algorithm [16]. The algorithm takes as input an
+input message of arbitrary length and produces as output a
+128-bit (16 octet) checksum. RSA-MD4 is believed to be
+collision-proof.
+
+6.4.3. RSA MD4 Cryptographic Checksum Using DES (rsa-md4-
+des)
+
+ The RSA-MD4-DES checksum calculates a keyed collision-
+proof checksum by prepending an 8 octet confounder before
+the text, applying the RSA MD4 checksum algorithm, and
+encrypting the confounder and the checksum using DES in
+cipher-block-chaining (CBC) mode using a variant of the key,
+where the variant is computed by eXclusive-ORing the key
+with the constant F0F0F0F0F0F0F0F0[39]. The initialization
+vector should be zero. The resulting checksum is 24 octets
+long (8 octets of which are redundant). This checksum is
+tamper-proof and believed to be collision-proof.
+
+ The DES specifications identify some "weak keys" and
+__________________________
+[39] A variant of the key is used to limit the use of a
+key to a particular function, separating the functions
+of generating a checksum from other encryption per-
+formed using the session key. The constant
+F0F0F0F0F0F0F0F0 was chosen because it maintains key
+parity. The properties of DES precluded the use of the
+complement. The same constant is used for similar pur-
+pose in the Message Integrity Check in the Privacy
+Enhanced Mail standard.
+
+
+Section 6.4.3. - 84 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+"semi-weak keys"; those keys shall not be used for generat-
+ing RSA-MD4 checksums for use in Kerberos.
+
+ The format for the checksum is described in the follow-
+ing diagram:
+
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+| des-cbc(confounder + rsa-md4(confounder+msg),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+The format cannot be described in ASN.1, but for those who
+prefer an ASN.1-like notation:
+
+rsa-md4-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(16)
+}
+
+
+
+6.4.4. The RSA MD5 Checksum (rsa-md5)
+
+ The RSA-MD5 checksum calculates a checksum using the
+RSA MD5 algorithm. [17]. The algorithm takes as input an
+input message of arbitrary length and produces as output a
+128-bit (16 octet) checksum. RSA-MD5 is believed to be
+collision-proof.
+
+6.4.5. RSA MD5 Cryptographic Checksum Using DES (rsa-md5-
+des)
+
+ The RSA-MD5-DES checksum calculates a keyed collision-
+proof checksum by prepending an 8 octet confounder before
+the text, applying the RSA MD5 checksum algorithm, and
+encrypting the confounder and the checksum using DES in
+cipher-block-chaining (CBC) mode using a variant of the key,
+where the variant is computed by eXclusive-ORing the key
+with the constant F0F0F0F0F0F0F0F0. The initialization vec-
+tor should be zero. The resulting checksum is 24 octets
+long (8 octets of which are redundant). This checksum is
+tamper-proof and believed to be collision-proof.
+
+ The DES specifications identify some "weak keys" and
+"semi-weak keys"; those keys shall not be used for encrypt-
+ing RSA-MD5 checksums for use in Kerberos.
+
+ The format for the checksum is described in the follow-
+ing diagram:
+
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+| des-cbc(confounder + rsa-md5(confounder+msg),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+The format cannot be described in ASN.1, but for those who
+
+
+Section 6.4.5. - 85 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+prefer an ASN.1-like notation:
+
+rsa-md5-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(16)
+}
+
+
+6.4.6. DES cipher-block chained checksum (des-mac)
+
+ The DES-MAC checksum is computed by prepending an 8
+octet confounder to the plaintext, performing a DES CBC-mode
+encryption on the result using the key and an initialization
+vector of zero, taking the last block of the ciphertext,
+prepending the same confounder and encrypting the pair using
+DES in cipher-block-chaining (CBC) mode using a a variant of
+the key, where the variant is computed by eXclusive-ORing
+the key with the constant F0F0F0F0F0F0F0F0. The initializa-
+tion vector should be zero. The resulting checksum is 128
+bits (16 octets) long, 64 bits of which are redundant. This
+checksum is tamper-proof and collision-proof.
+
+ The format for the checksum is described in the follow-
+ing diagram:
+
++--+--+--+--+--+--+--+--+-----+-----+-----+-----+-----+-----+-----+-----+
+| des-cbc(confounder + des-mac(conf+msg,iv=0,key),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+-----+-----+-----+-----+-----+-----+-----+-----+
+
+The format cannot be described in ASN.1, but for those who
+prefer an ASN.1-like notation:
+
+des-mac-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(8)
+}
+
+
+ The DES specifications identify some "weak" and "semi-
+weak" keys; those keys shall not be used for generating
+DES-MAC checksums for use in Kerberos, nor shall a key be
+used whose variant is "weak" or "semi-weak".
+
+6.4.7. RSA MD4 Cryptographic Checksum Using DES alternative
+(rsa-md4-des-k)
+
+ The RSA-MD4-DES-K checksum calculates a keyed
+collision-proof checksum by applying the RSA MD4 checksum
+algorithm and encrypting the results using DES in cipher-
+block-chaining (CBC) mode using a DES key as both key and
+initialization vector. The resulting checksum is 16 octets
+long. This checksum is tamper-proof and believed to be
+collision-proof. Note that this checksum type is the old
+method for encoding the RSA-MD4-DES checksum and it is no
+
+
+Section 6.4.7. - 86 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+longer recommended.
+
+6.4.8. DES cipher-block chained checksum alternative (des-
+mac-k)
+
+ The DES-MAC-K checksum is computed by performing a DES
+CBC-mode encryption of the plaintext, and using the last
+block of the ciphertext as the checksum value. It is keyed
+with an encryption key and an initialization vector; any
+uses which do not specify an additional initialization vec-
+tor will use the key as both key and initialization vector.
+The resulting checksum is 64 bits (8 octets) long. This
+checksum is tamper-proof and collision-proof. Note that
+this checksum type is the old method for encoding the DES-
+MAC checksum and it is no longer recommended.
+
+ The DES specifications identify some "weak keys" and
+"semi-weak keys"; those keys shall not be used for generat-
+ing DES-MAC checksums for use in Kerberos.
+
+7. Naming Constraints
+
+
+7.1. Realm Names
+
+ Although realm names are encoded as GeneralStrings and
+although a realm can technically select any name it chooses,
+interoperability across realm boundaries requires agreement
+on how realm names are to be assigned, and what information
+they imply.
+
+ To enforce these conventions, each realm must conform
+to the conventions itself, and it must require that any
+realms with which inter-realm keys are shared also conform
+to the conventions and require the same from its neighbors.
+
+ Kerberos realm names are case sensitive. Realm names
+that differ only in the case of the characters are not
+equivalent. There are presently four styles of realm names:
+domain, X500, other, and reserved. Examples of each style
+follow:
+
+ domain: ATHENA.MIT.EDU (example)
+ X500: C=US/O=OSF (example)
+ other: NAMETYPE:rest/of.name=without-restrictions (example)
+ reserved: reserved, but will not conflict with above
+
+
+Domain names must look like domain names: they consist of
+components separated by periods (.) and they contain neither
+colons (:) nor slashes (/). Domain names must be converted
+to upper case when used as realm names.
+
+ X.500 names contain an equal (=) and cannot contain a
+
+
+Section 7.1. - 87 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+colon (:) before the equal. The realm names for X.500 names
+will be string representations of the names with components
+separated by slashes. Leading and trailing slashes will not
+be included.
+
+ Names that fall into the other category must begin with
+a prefix that contains no equal (=) or period (.) and the
+prefix must be followed by a colon (:) and the rest of the
+name. All prefixes must be assigned before they may be
+used. Presently none are assigned.
+
+ The reserved category includes strings which do not
+fall into the first three categories. All names in this
+category are reserved. It is unlikely that names will be
+assigned to this category unless there is a very strong
+argument for not using the "other" category.
+
+ These rules guarantee that there will be no conflicts
+between the various name styles. The following additional
+constraints apply to the assignment of realm names in the
+domain and X.500 categories: the name of a realm for the
+domain or X.500 formats must either be used by the organiza-
+tion owning (to whom it was assigned) an Internet domain
+name or X.500 name, or in the case that no such names are
+registered, authority to use a realm name may be derived
+from the authority of the parent realm. For example, if
+there is no domain name for E40.MIT.EDU, then the adminis-
+trator of the MIT.EDU realm can authorize the creation of a
+realm with that name.
+
+ This is acceptable because the organization to which
+the parent is assigned is presumably the organization
+authorized to assign names to its children in the X.500 and
+domain name systems as well. If the parent assigns a realm
+name without also registering it in the domain name or X.500
+hierarchy, it is the parent's responsibility to make sure
+that there will not in the future exists a name identical to
+the realm name of the child unless it is assigned to the
+same entity as the realm name.
+
+
+7.2. Principal Names
+
+ As was the case for realm names, conventions are needed
+to ensure that all agree on what information is implied by a
+principal name. The name-type field that is part of the
+principal name indicates the kind of information implied by
+the name. The name-type should be treated as a hint.
+Ignoring the name type, no two names can be the same (i.e.
+at least one of the components, or the realm, must be dif-
+ferent). This constraint may be eliminated in the future.
+The following name types are defined:
+
+ name-type value meaning
+
+
+Section 7.2. - 88 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ NT-UNKNOWN 0 Name type not known
+ NT-PRINCIPAL 1 General principal name (e.g. username, or DCE principal)
+ NT-SRV-INST 2 Service and other unique instance (krbtgt)
+ NT-SRV-HST 3 Service with host name as instance (telnet, rcommands)
+ NT-SRV-XHST 4 Service with slash-separated host name components
+ NT-UID 5 Unique ID
+
+
+When a name implies no information other than its uniqueness
+at a particular time the name type PRINCIPAL should be used.
+The principal name type should be used for users, and it
+might also be used for a unique server. If the name is a
+unique machine generated ID that is guaranteed never to be
+reassigned then the name type of UID should be used (note
+that it is generally a bad idea to reassign names of any
+type since stale entries might remain in access control
+lists).
+
+ If the first component of a name identifies a service
+and the remaining components identify an instance of the
+service in a server specified manner, then the name type of
+SRV-INST should be used. An example of this name type is
+the Kerberos ticket-granting service whose name has a first
+component of krbtgt and a second component identifying the
+realm for which the ticket is valid.
+
+ If instance is a single component following the service
+name and the instance identifies the host on which the
+server is running, then the name type SRV-HST should be
+used. This type is typically used for Internet services
+such as telnet and the Berkeley R commands. If the separate
+components of the host name appear as successive components
+following the name of the service, then the name type SRV-
+XHST should be used. This type might be used to identify
+servers on hosts with X.500 names where the slash (/) might
+otherwise be ambiguous.
+
+ A name type of UNKNOWN should be used when the form of
+the name is not known. When comparing names, a name of type
+UNKNOWN will match principals authenticated with names of
+any type. A principal authenticated with a name of type
+UNKNOWN, however, will only match other names of type UNK-
+NOWN.
+
+ Names of any type with an initial component of "krbtgt"
+are reserved for the Kerberos ticket granting service. See
+section 8.2.3 for the form of such names.
+
+7.2.1. Name of server principals
+
+ The principal identifier for a server on a host will
+generally be composed of two parts: (1) the realm of the KDC
+with which the server is registered, and (2) a two-component
+
+
+Section 7.2.1. - 89 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+name of type NT-SRV-HST if the host name is an Internet
+domain name or a multi-component name of type NT-SRV-XHST if
+the name of the host is of a form such as X.500 that allows
+slash (/) separators. The first component of the two- or
+multi-component name will identify the service and the
+latter components will identify the host. Where the name of
+the host is not case sensitive (for example, with Internet
+domain names) the name of the host must be lower case. If
+specified by the application protocol for services such as
+telnet and the Berkeley R commands which run with system
+privileges, the first component may be the string "host"
+instead of a service specific identifier. When a host has
+an official name and one or more aliases, the official name
+of the host must be used when constructing the name of the
+server principal.
+
+8. Constants and other defined values
+
+
+8.1. Host address types
+
+ All negative values for the host address type are
+reserved for local use. All non-negative values are
+reserved for officially assigned type fields and interpreta-
+tions.
+
+ The values of the types for the following addresses are
+chosen to match the defined address family constants in the
+Berkeley Standard Distributions of Unix. They can be found
+in <sys/socket.h> with symbolic names AF_xxx (where xxx is
+an abbreviation of the address family name).
+
+
+Internet addresses
+
+ Internet addresses are 32-bit (4-octet) quantities,
+encoded in MSB order. The type of internet addresses is two
+(2).
+
+CHAOSnet addresses
+
+ CHAOSnet addresses are 16-bit (2-octet) quantities,
+encoded in MSB order. The type of CHAOSnet addresses is
+five (5).
+
+ISO addresses
+
+ ISO addresses are variable-length. The type of ISO
+addresses is seven (7).
+
+Xerox Network Services (XNS) addresses
+
+ XNS addresses are 48-bit (6-octet) quantities, encoded
+in MSB order. The type of XNS addresses is six (6).
+
+
+Section 8.1. - 90 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+AppleTalk Datagram Delivery Protocol (DDP) addresses
+
+ AppleTalk DDP addresses consist of an 8-bit node number
+and a 16-bit network number. The first octet of the address
+is the node number; the remaining two octets encode the net-
+work number in MSB order. The type of AppleTalk DDP
+addresses is sixteen (16).
+
+DECnet Phase IV addresses
+
+ DECnet Phase IV addresses are 16-bit addresses, encoded
+in LSB order. The type of DECnet Phase IV addresses is
+twelve (12).
+
+8.2. KDC messages
+
+8.2.1. IP transport
+
+ When contacting a Kerberos server (KDC) for a
+KRB_KDC_REQ request using UDP IP transport, the client shall
+send a UDP datagram containing only an encoding of the
+request to port 88 (decimal) at the KDC's IP address; the
+KDC will respond with a reply datagram containing only an
+encoding of the reply message (either a KRB_ERROR or a
+KRB_KDC_REP) to the sending port at the sender's IP address.
+
+ Kerberos servers supporting IP transport must accept
+UDP requests on port 88 (decimal). Servers may also accept
+TCP requests on port 88 (decimal). When the KRB_KDC_REQ
+message is sent to the KDC by TCP, a new connection will be
+established for each authentication exchange and the
+KRB_KDC_REP or KRB_ERROR message will be returned to the
+client on the TCP stream that was established for the
+request. The connection will be broken after the reply has
+been received (or upon time-out). Care must be taken in
+managing TCP/IP connections with the KDC to prevent denial
+of service attacks based on the number of TCP/IP connections
+with the KDC that remain open.
+
+8.2.2. OSI transport
+
+ During authentication of an OSI client to an OSI
+server, the mutual authentication of an OSI server to an OSI
+client, the transfer of credentials from an OSI client to an
+OSI server, or during exchange of private or integrity
+checked messages, Kerberos protocol messages may be treated
+as opaque objects and the type of the authentication mechan-
+ism will be:
+
+OBJECT IDENTIFIER ::= {iso (1), org(3), dod(6),internet(1), security(5),
+ kerberosv5(2)}
+
+Depending on the situation, the opaque object will be an
+authentication header (KRB_AP_REQ), an authentication reply
+(KRB_AP_REP), a safe message (KRB_SAFE), a private message
+
+
+Section 8.2.2. - 91 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+(KRB_PRIV), or a credentials message (KRB_CRED). The opaque
+data contains an application code as specified in the ASN.1
+description for each message. The application code may be
+used by Kerberos to determine the message type.
+
+8.2.3. Name of the TGS
+
+ The principal identifier of the ticket-granting service
+shall be composed of three parts: (1) the realm of the KDC
+issuing the TGS ticket (2) a two-part name of type NT-SRV-
+INST, with the first part "krbtgt" and the second part the
+name of the realm which will accept the ticket-granting
+ticket. For example, a ticket-granting ticket issued by the
+ATHENA.MIT.EDU realm to be used to get tickets from the
+ATHENA.MIT.EDU KDC has a principal identifier of
+"ATHENA.MIT.EDU" (realm), ("krbtgt", "ATHENA.MIT.EDU")
+(name). A ticket-granting ticket issued by the
+ATHENA.MIT.EDU realm to be used to get tickets from the
+MIT.EDU realm has a principal identifier of "ATHENA.MIT.EDU"
+(realm), ("krbtgt", "MIT.EDU") (name).
+
+
+8.3. Protocol constants and associated values
+
+The following tables list constants used in the protocol and defines their
+meanings.
+
+Encryption type etype value block size minimum pad size confounder size
+NULL 0 1 0 0
+des-cbc-crc 1 8 4 8
+des-cbc-md4 2 8 0 8
+des-cbc-md5 3 8 0 8
+<reserved> 4
+des3-cbc-md5 5 8 0 8
+<reserved> 6
+des3-cbc-sha1 7 8 0 8
+sign-dsa-generate 8 (pkinit)
+encrypt-rsa-priv 9 (pkinit)
+encrypt-rsa-pub 10 (pkinit)
+ENCTYPE_PK_CROSS 48 (reserved for pkcross)
+<reserved> 0x8003
+
+Checksum type sumtype value checksum size
+CRC32 1 4
+rsa-md4 2 16
+rsa-md4-des 3 24
+des-mac 4 16
+des-mac-k 5 8
+rsa-md4-des-k 6 16
+rsa-md5 7 16
+rsa-md5-des 8 24
+rsa-md5-des3 9 24
+hmac-sha1-des3 10 20 (I had this as 10, is it 12)
+
+
+Section 8.3. - 92 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+padata type padata-type value
+
+PA-TGS-REQ 1
+PA-ENC-TIMESTAMP 2
+PA-PW-SALT 3
+<reserved> 4
+PA-ENC-UNIX-TIME 5
+PA-SANDIA-SECUREID 6
+PA-SESAME 7
+PA-OSF-DCE 8
+PA-CYBERSAFE-SECUREID 9
+PA-AFS3-SALT 10
+PA-ETYPE-INFO 11
+SAM-CHALLENGE 12 (sam/otp)
+SAM-RESPONSE 13 (sam/otp)
+PA-PK-AS-REQ 14 (pkinit)
+PA-PK-AS-REP 15 (pkinit)
+PA-PK-AS-SIGN 16 (pkinit)
+PA-PK-KEY-REQ 17 (pkinit)
+PA-PK-KEY-REP 18 (pkinit)
+
+authorization data type ad-type value
+reserved values 0-63
+OSF-DCE 64
+SESAME 65
+
+alternate authentication type method-type value
+reserved values 0-63
+ATT-CHALLENGE-RESPONSE 64
+
+transited encoding type tr-type value
+DOMAIN-X500-COMPRESS 1
+reserved values all others
+
+
+
+Label Value Meaning or MIT code
+
+pvno 5 current Kerberos protocol version number
+
+message types
+
+KRB_AS_REQ 10 Request for initial authentication
+KRB_AS_REP 11 Response to KRB_AS_REQ request
+KRB_TGS_REQ 12 Request for authentication based on TGT
+KRB_TGS_REP 13 Response to KRB_TGS_REQ request
+KRB_AP_REQ 14 application request to server
+KRB_AP_REP 15 Response to KRB_AP_REQ_MUTUAL
+KRB_SAFE 20 Safe (checksummed) application message
+KRB_PRIV 21 Private (encrypted) application message
+KRB_CRED 22 Private (encrypted) message to forward credentials
+KRB_ERROR 30 Error response
+
+
+Section 8.3. - 93 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+name types
+
+KRB_NT_UNKNOWN 0 Name type not known
+KRB_NT_PRINCIPAL 1 Just the name of the principal as in DCE, or for users
+KRB_NT_SRV_INST 2 Service and other unique instance (krbtgt)
+KRB_NT_SRV_HST 3 Service with host name as instance (telnet, rcommands)
+KRB_NT_SRV_XHST 4 Service with host as remaining components
+KRB_NT_UID 5 Unique ID
+
+error codes
+
+KDC_ERR_NONE 0 No error
+KDC_ERR_NAME_EXP 1 Client's entry in database has expired
+KDC_ERR_SERVICE_EXP 2 Server's entry in database has expired
+KDC_ERR_BAD_PVNO 3 Requested protocol version number not supported
+KDC_ERR_C_OLD_MAST_KVNO 4 Client's key encrypted in old master key
+KDC_ERR_S_OLD_MAST_KVNO 5 Server's key encrypted in old master key
+KDC_ERR_C_PRINCIPAL_UNKNOWN 6 Client not found in Kerberos database
+KDC_ERR_S_PRINCIPAL_UNKNOWN 7 Server not found in Kerberos database
+KDC_ERR_PRINCIPAL_NOT_UNIQUE 8 Multiple principal entries in database
+KDC_ERR_NULL_KEY 9 The client or server has a null key
+KDC_ERR_CANNOT_POSTDATE 10 Ticket not eligible for postdating
+KDC_ERR_NEVER_VALID 11 Requested start time is later than end time
+KDC_ERR_POLICY 12 KDC policy rejects request
+KDC_ERR_BADOPTION 13 KDC cannot accommodate requested option
+KDC_ERR_ETYPE_NOSUPP 14 KDC has no support for encryption type
+KDC_ERR_SUMTYPE_NOSUPP 15 KDC has no support for checksum type
+KDC_ERR_PADATA_TYPE_NOSUPP 16 KDC has no support for padata type
+KDC_ERR_TRTYPE_NOSUPP 17 KDC has no support for transited type
+KDC_ERR_CLIENT_REVOKED 18 Clients credentials have been revoked
+KDC_ERR_SERVICE_REVOKED 19 Credentials for server have been revoked
+KDC_ERR_TGT_REVOKED 20 TGT has been revoked
+KDC_ERR_CLIENT_NOTYET 21 Client not yet valid - try again later
+KDC_ERR_SERVICE_NOTYET 22 Server not yet valid - try again later
+KDC_ERR_KEY_EXPIRED 23 Password has expired - change password to reset
+KDC_ERR_PREAUTH_FAILED 24 Pre-authentication information was invalid
+KDC_ERR_PREAUTH_REQUIRED 25 Additional pre-authenticationrequired-
+KDC_ERR_SERVER_NOMATCH 26 Requested server and ticket don't match
+KDC_ERR_MUST_USE_USER2USER 27 Server principal valid for user2user only
+KDC_ERR_PATH_NOT_ACCPETED 28 KDC Policy rejects transited path
+KRB_AP_ERR_BAD_INTEGRITY 31 Integrity check on decrypted field failed
+KRB_AP_ERR_TKT_EXPIRED 32 Ticket expired
+KRB_AP_ERR_TKT_NYV 33 Ticket not yet valid
+KRB_AP_ERR_REPEAT 34 Request is a replay
+KRB_AP_ERR_NOT_US 35 The ticket isn't for us
+KRB_AP_ERR_BADMATCH 36 Ticket and authenticator don't match
+KRB_AP_ERR_SKEW 37 Clock skew too great
+KRB_AP_ERR_BADADDR 38 Incorrect net address
+KRB_AP_ERR_BADVERSION 39 Protocol version mismatch
+KRB_AP_ERR_MSG_TYPE 40 Invalid msg type
+KRB_AP_ERR_MODIFIED 41 Message stream modified
+KRB_AP_ERR_BADORDER 42 Message out of order
+KRB_AP_ERR_BADKEYVER 44 Specified version of key is not available
+KRB_AP_ERR_NOKEY 45 Service key not available
+KRB_AP_ERR_MUT_FAIL 46 Mutual authentication failed
+KRB_AP_ERR_BADDIRECTION 47 Incorrect message direction
+KRB_AP_ERR_METHOD 48 Alternative authentication method required
+KRB_AP_ERR_BADSEQ 49 Incorrect sequence number in message
+
+
+
+Section 8.3. - 94 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+KRB_AP_ERR_INAPP_CKSUM 50 Inappropriate type of checksum in message
+KRB_ERR_GENERIC 60 Generic error (description in e-text)
+KRB_ERR_FIELD_TOOLONG 61 Field is too long for this implementation
+KDC_ERROR_CLIENT_NOT_TRUSTED 62 (pkinit)
+KDC_ERROR_KDC_NOT_TRUSTED 63 (pkinit)
+KDC_ERROR_INVALID_SIG 64 (pkinit)
+KDC_ERR_KEY_TOO_WEAK 65 (pkinit)
+
+
+9. Interoperability requirements
+
+ Version 5 of the Kerberos protocol supports a myriad of
+options. Among these are multiple encryption and checksum
+types, alternative encoding schemes for the transited field,
+optional mechanisms for pre-authentication, the handling of
+tickets with no addresses, options for mutual authentica-
+tion, user to user authentication, support for proxies, for-
+warding, postdating, and renewing tickets, the format of
+realm names, and the handling of authorization data.
+
+ In order to ensure the interoperability of realms, it
+is necessary to define a minimal configuration which must be
+supported by all implementations. This minimal configura-
+tion is subject to change as technology does. For example,
+if at some later date it is discovered that one of the
+required encryption or checksum algorithms is not secure, it
+will be replaced.
+
+9.1. Specification 1
+
+ This section defines the first specification of these
+options. Implementations which are configured in this way
+can be said to support Kerberos Version 5 Specification 1
+(5.1).
+
+Encryption and checksum methods
+
+The following encryption and checksum mechanisms must be
+supported. Implementations may support other mechanisms as
+well, but the additional mechanisms may only be used when
+communicating with principals known to also support them:
+This list is to be determined.
+Encryption: DES-CBC-MD5
+Checksums: CRC-32, DES-MAC, DES-MAC-K, and DES-MD5
+
+
+__________________________
+- This error carries additional information in the e-
+data field. The contents of the e-data field for this
+message is described in section 5.9.1.
+
+
+
+Section 9.1. - 95 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+Realm Names
+
+All implementations must understand hierarchical realms in
+both the Internet Domain and the X.500 style. When a ticket
+granting ticket for an unknown realm is requested, the KDC
+must be able to determine the names of the intermediate
+realms between the KDCs realm and the requested realm.
+
+Transited field encoding
+
+DOMAIN-X500-COMPRESS (described in section 3.3.3.2) must be
+supported. Alternative encodings may be supported, but they
+may be used only when that encoding is supported by ALL
+intermediate realms.
+
+Pre-authentication methods
+
+The TGS-REQ method must be supported. The TGS-REQ method is
+not used on the initial request. The PA-ENC-TIMESTAMP
+method must be supported by clients but whether it is
+enabled by default may be determined on a realm by realm
+basis. If not used in the initial request and the error
+KDC_ERR_PREAUTH_REQUIRED is returned specifying PA-ENC-
+TIMESTAMP as an acceptable method, the client should retry
+the initial request using the PA-ENC-TIMESTAMP pre-
+authentication method. Servers need not support the PA-
+ENC-TIMESTAMP method, but if not supported the server should
+ignore the presence of PA-ENC-TIMESTAMP pre-authentication
+in a request.
+
+Mutual authentication
+
+Mutual authentication (via the KRB_AP_REP message) must be
+supported.
+
+
+Ticket addresses and flags
+
+All KDC's must pass on tickets that carry no addresses (i.e.
+if a TGT contains no addresses, the KDC will return deriva-
+tive tickets), but each realm may set its own policy for
+issuing such tickets, and each application server will set
+its own policy with respect to accepting them.
+
+ Proxies and forwarded tickets must be supported. Indi-
+vidual realms and application servers can set their own pol-
+icy on when such tickets will be accepted.
+
+ All implementations must recognize renewable and post-
+dated tickets, but need not actually implement them. If
+these options are not supported, the starttime and endtime
+in the ticket shall specify a ticket's entire useful life.
+When a postdated ticket is decoded by a server, all imple-
+mentations shall make the presence of the postdated flag
+
+
+Section 9.1. - 96 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+visible to the calling server.
+
+User-to-user authentication
+
+Support for user to user authentication (via the ENC-TKT-
+IN-SKEY KDC option) must be provided by implementations, but
+individual realms may decide as a matter of policy to reject
+such requests on a per-principal or realm-wide basis.
+
+Authorization data
+
+Implementations must pass all authorization data subfields
+from ticket-granting tickets to any derivative tickets
+unless directed to suppress a subfield as part of the defin-
+ition of that registered subfield type (it is never
+incorrect to pass on a subfield, and no registered subfield
+types presently specify suppression at the KDC).
+
+ Implementations must make the contents of any authori-
+zation data subfields available to the server when a ticket
+is used. Implementations are not required to allow clients
+to specify the contents of the authorization data fields.
+
+9.2. Recommended KDC values
+
+Following is a list of recommended values for a KDC imple-
+mentation, based on the list of suggested configuration con-
+stants (see section 4.4).
+
+minimum lifetime 5 minutes
+
+maximum renewable lifetime1 week
+
+maximum ticket lifetime1 day
+
+empty addresses only when suitable restrictions appear
+ in authorization data
+
+proxiable, etc. Allowed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Section 9.2. - 97 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+10. REFERENCES
+
+
+
+1. B. Clifford Neuman and Theodore Y. Ts'o, "An Authenti-
+ cation Service for Computer Networks," IEEE Communica-
+ tions Magazine, Vol. 32(9), pp. 33-38 (September 1994).
+
+2. S. P. Miller, B. C. Neuman, J. I. Schiller, and J. H.
+ Saltzer, Section E.2.1: Kerberos Authentication and
+ Authorization System, M.I.T. Project Athena, Cambridge,
+ Massachusetts (December 21, 1987).
+
+3. J. G. Steiner, B. C. Neuman, and J. I. Schiller, "Ker-
+ beros: An Authentication Service for Open Network Sys-
+ tems," pp. 191-202 in Usenix Conference Proceedings,
+ Dallas, Texas (February, 1988).
+
+4. Roger M. Needham and Michael D. Schroeder, "Using
+ Encryption for Authentication in Large Networks of Com-
+ puters," Communications of the ACM, Vol. 21(12),
+ pp. 993-999 (December, 1978).
+
+5. Dorothy E. Denning and Giovanni Maria Sacco, "Time-
+ stamps in Key Distribution Protocols," Communications
+ of the ACM, Vol. 24(8), pp. 533-536 (August 1981).
+
+6. John T. Kohl, B. Clifford Neuman, and Theodore Y. Ts'o,
+ "The Evolution of the Kerberos Authentication Service,"
+ in an IEEE Computer Society Text soon to be published
+ (June 1992).
+
+7. B. Clifford Neuman, "Proxy-Based Authorization and
+ Accounting for Distributed Systems," in Proceedings of
+ the 13th International Conference on Distributed Com-
+ puting Systems, Pittsburgh, PA (May, 1993).
+
+8. Don Davis and Ralph Swick, "Workstation Services and
+ Kerberos Authentication at Project Athena," Technical
+ Memorandum TM-424, MIT Laboratory for Computer Science
+ (February 1990).
+
+9. P. J. Levine, M. R. Gretzinger, J. M. Diaz, W. E. Som-
+ merfeld, and K. Raeburn, Section E.1: Service Manage-
+ ment System, M.I.T. Project Athena, Cambridge, Mas-
+ sachusetts (1987).
+
+10. CCITT, Recommendation X.509: The Directory Authentica-
+ tion Framework, December 1988.
+
+11. J. Pato, Using Pre-Authentication to Avoid Password
+ Guessing Attacks, Open Software Foundation DCE Request
+ for Comments 26 (December 1992).
+
+
+
+Section 10. - 98 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+12. National Bureau of Standards, U.S. Department of Com-
+ merce, "Data Encryption Standard," Federal Information
+ Processing Standards Publication 46, Washington, DC
+ (1977).
+
+13. National Bureau of Standards, U.S. Department of Com-
+ merce, "DES Modes of Operation," Federal Information
+ Processing Standards Publication 81, Springfield, VA
+ (December 1980).
+
+14. Stuart G. Stubblebine and Virgil D. Gligor, "On Message
+ Integrity in Cryptographic Protocols," in Proceedings
+ of the IEEE Symposium on Research in Security and
+ Privacy, Oakland, California (May 1992).
+
+15. International Organization for Standardization, "ISO
+ Information Processing Systems - Data Communication -
+ High-Level Data Link Control Procedure - Frame Struc-
+ ture," IS 3309 (October 1984). 3rd Edition.
+
+16. R. Rivest, "The MD4 Message Digest Algorithm," RFC
+ 1320, MIT Laboratory for Computer Science (April
+ 1992).
+
+17. R. Rivest, "The MD5 Message Digest Algorithm," RFC
+ 1321, MIT Laboratory for Computer Science (April
+ 1992).
+
+18. H. Krawczyk, M. Bellare, and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication," Working Draft
+ draft-ietf-ipsec-hmac-md5-01.txt, (August 1996).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Section 10. - 99 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+A. Pseudo-code for protocol processing
+
+ This appendix provides pseudo-code describing how the
+messages are to be constructed and interpreted by clients
+and servers.
+
+A.1. KRB_AS_REQ generation
+ request.pvno := protocol version; /* pvno = 5 */
+ request.msg-type := message type; /* type = KRB_AS_REQ */
+
+ if(pa_enc_timestamp_required) then
+ request.padata.padata-type = PA-ENC-TIMESTAMP;
+ get system_time;
+ padata-body.patimestamp,pausec = system_time;
+ encrypt padata-body into request.padata.padata-value
+ using client.key; /* derived from password */
+ endif
+
+ body.kdc-options := users's preferences;
+ body.cname := user's name;
+ body.realm := user's realm;
+ body.sname := service's name; /* usually "krbtgt", "localrealm" */
+ if (body.kdc-options.POSTDATED is set) then
+ body.from := requested starting time;
+ else
+ omit body.from;
+ endif
+ body.till := requested end time;
+ if (body.kdc-options.RENEWABLE is set) then
+ body.rtime := requested final renewal time;
+ endif
+ body.nonce := random_nonce();
+ body.etype := requested etypes;
+ if (user supplied addresses) then
+ body.addresses := user's addresses;
+ else
+ omit body.addresses;
+ endif
+ omit body.enc-authorization-data;
+ request.req-body := body;
+
+ kerberos := lookup(name of local kerberos server (or servers));
+ send(packet,kerberos);
+
+ wait(for response);
+ if (timed_out) then
+ retry or use alternate server;
+ endif
+
+A.2. KRB_AS_REQ verification and KRB_AS_REP generation
+ decode message into req;
+
+ client := lookup(req.cname,req.realm);
+ server := lookup(req.sname,req.realm);
+
+
+Section A.2. - 100 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+
+ get system_time;
+ kdc_time := system_time.seconds;
+
+ if (!client) then
+ /* no client in Database */
+ error_out(KDC_ERR_C_PRINCIPAL_UNKNOWN);
+ endif
+ if (!server) then
+ /* no server in Database */
+ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
+ endif
+
+ if(client.pa_enc_timestamp_required and
+ pa_enc_timestamp not present) then
+ error_out(KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP));
+ endif
+
+ if(pa_enc_timestamp present) then
+ decrypt req.padata-value into decrypted_enc_timestamp
+ using client.key;
+ using auth_hdr.authenticator.subkey;
+ if (decrypt_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ if(decrypted_enc_timestamp is not within allowable skew) then
+ error_out(KDC_ERR_PREAUTH_FAILED);
+ endif
+ if(decrypted_enc_timestamp and usec is replay)
+ error_out(KDC_ERR_PREAUTH_FAILED);
+ endif
+ add decrypted_enc_timestamp and usec to replay cache;
+ endif
+
+ use_etype := first supported etype in req.etypes;
+
+ if (no support for req.etypes) then
+ error_out(KDC_ERR_ETYPE_NOSUPP);
+ endif
+
+ new_tkt.vno := ticket version; /* = 5 */
+ new_tkt.sname := req.sname;
+ new_tkt.srealm := req.srealm;
+ reset all flags in new_tkt.flags;
+
+ /* It should be noted that local policy may affect the */
+ /* processing of any of these flags. For example, some */
+ /* realms may refuse to issue renewable tickets */
+
+ if (req.kdc-options.FORWARDABLE is set) then
+ set new_tkt.flags.FORWARDABLE;
+ endif
+ if (req.kdc-options.PROXIABLE is set) then
+ set new_tkt.flags.PROXIABLE;
+ endif
+
+
+Section A.2. - 101 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ if (req.kdc-options.ALLOW-POSTDATE is set) then
+ set new_tkt.flags.MAY-POSTDATE;
+ endif
+ if ((req.kdc-options.RENEW is set) or
+ (req.kdc-options.VALIDATE is set) or
+ (req.kdc-options.PROXY is set) or
+ (req.kdc-options.FORWARDED is set) or
+ (req.kdc-options.ENC-TKT-IN-SKEY is set)) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+ new_tkt.session := random_session_key();
+ new_tkt.cname := req.cname;
+ new_tkt.crealm := req.crealm;
+ new_tkt.transited := empty_transited_field();
+
+ new_tkt.authtime := kdc_time;
+
+ if (req.kdc-options.POSTDATED is set) then
+ if (against_postdate_policy(req.from)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ set new_tkt.flags.POSTDATED;
+ set new_tkt.flags.INVALID;
+ new_tkt.starttime := req.from;
+ else
+ omit new_tkt.starttime; /* treated as authtime when omitted */
+ endif
+ if (req.till = 0) then
+ till := infinity;
+ else
+ till := req.till;
+ endif
+
+ new_tkt.endtime := min(till,
+ new_tkt.starttime+client.max_life,
+ new_tkt.starttime+server.max_life,
+ new_tkt.starttime+max_life_for_realm);
+
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (new_tkt.endtime < req.till)) then
+ /* we set the RENEWABLE option for later processing */
+ set req.kdc-options.RENEWABLE;
+ req.rtime := req.till;
+ endif
+
+ if (req.rtime = 0) then
+ rtime := infinity;
+ else
+ rtime := req.rtime;
+ endif
+
+ if (req.kdc-options.RENEWABLE is set) then
+ set new_tkt.flags.RENEWABLE;
+
+
+Section A.2. - 102 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ new_tkt.renew-till := min(rtime,
+ new_tkt.starttime+client.max_rlife,
+ new_tkt.starttime+server.max_rlife,
+ new_tkt.starttime+max_rlife_for_realm);
+ else
+ omit new_tkt.renew-till; /* only present if RENEWABLE */
+ endif
+
+ if (req.addresses) then
+ new_tkt.caddr := req.addresses;
+ else
+ omit new_tkt.caddr;
+ endif
+
+ new_tkt.authorization_data := empty_authorization_data();
+
+ encode to-be-encrypted part of ticket into OCTET STRING;
+ new_tkt.enc-part := encrypt OCTET STRING
+ using etype_for_key(server.key), server.key, server.p_kvno;
+
+
+ /* Start processing the response */
+
+ resp.pvno := 5;
+ resp.msg-type := KRB_AS_REP;
+ resp.cname := req.cname;
+ resp.crealm := req.realm;
+ resp.ticket := new_tkt;
+
+ resp.key := new_tkt.session;
+ resp.last-req := fetch_last_request_info(client);
+ resp.nonce := req.nonce;
+ resp.key-expiration := client.expiration;
+ resp.flags := new_tkt.flags;
+
+ resp.authtime := new_tkt.authtime;
+ resp.starttime := new_tkt.starttime;
+ resp.endtime := new_tkt.endtime;
+
+ if (new_tkt.flags.RENEWABLE) then
+ resp.renew-till := new_tkt.renew-till;
+ endif
+
+ resp.realm := new_tkt.realm;
+ resp.sname := new_tkt.sname;
+
+ resp.caddr := new_tkt.caddr;
+
+ encode body of reply into OCTET STRING;
+
+ resp.enc-part := encrypt OCTET STRING
+ using use_etype, client.key, client.p_kvno;
+ send(resp);
+
+
+
+Section A.2. - 103 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+A.3. KRB_AS_REP verification
+ decode response into resp;
+
+ if (resp.msg-type = KRB_ERROR) then
+ if(error = KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP)) then
+ set pa_enc_timestamp_required;
+ goto KRB_AS_REQ;
+ endif
+ process_error(resp);
+ return;
+ endif
+
+ /* On error, discard the response, and zero the session key */
+ /* from the response immediately */
+
+ key = get_decryption_key(resp.enc-part.kvno, resp.enc-part.etype,
+ resp.padata);
+ unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and key;
+ zero(key);
+
+ if (common_as_rep_tgs_rep_checks fail) then
+ destroy resp.key;
+ return error;
+ endif
+
+ if near(resp.princ_exp) then
+ print(warning message);
+ endif
+ save_for_later(ticket,session,client,server,times,flags);
+
+A.4. KRB_AS_REP and KRB_TGS_REP common checks
+ if (decryption_error() or
+ (req.cname != resp.cname) or
+ (req.realm != resp.crealm) or
+ (req.sname != resp.sname) or
+ (req.realm != resp.realm) or
+ (req.nonce != resp.nonce) or
+ (req.addresses != resp.caddr)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ /* make sure no flags are set that shouldn't be, and that all that */
+ /* should be are set */
+ if (!check_flags_for_compatability(req.kdc-options,resp.flags)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ if ((req.from = 0) and
+ (resp.starttime is not within allowable skew)) then
+ destroy resp.key;
+ return KRB_AP_ERR_SKEW;
+
+
+Section A.4. - 104 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ endif
+ if ((req.from != 0) and (req.from != resp.starttime)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+ if ((req.till != 0) and (resp.endtime > req.till)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ if ((req.kdc-options.RENEWABLE is set) and
+ (req.rtime != 0) and (resp.renew-till > req.rtime)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (resp.flags.RENEWABLE) and
+ (req.till != 0) and
+ (resp.renew-till > req.till)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+A.5. KRB_TGS_REQ generation
+ /* Note that make_application_request might have to recursivly */
+ /* call this routine to get the appropriate ticket-granting ticket */
+
+ request.pvno := protocol version; /* pvno = 5 */
+ request.msg-type := message type; /* type = KRB_TGS_REQ */
+
+ body.kdc-options := users's preferences;
+ /* If the TGT is not for the realm of the end-server */
+ /* then the sname will be for a TGT for the end-realm */
+ /* and the realm of the requested ticket (body.realm) */
+ /* will be that of the TGS to which the TGT we are */
+ /* sending applies */
+ body.sname := service's name;
+ body.realm := service's realm;
+
+ if (body.kdc-options.POSTDATED is set) then
+ body.from := requested starting time;
+ else
+ omit body.from;
+ endif
+ body.till := requested end time;
+ if (body.kdc-options.RENEWABLE is set) then
+ body.rtime := requested final renewal time;
+ endif
+ body.nonce := random_nonce();
+ body.etype := requested etypes;
+ if (user supplied addresses) then
+ body.addresses := user's addresses;
+ else
+ omit body.addresses;
+
+
+Section A.5. - 105 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ endif
+
+ body.enc-authorization-data := user-supplied data;
+ if (body.kdc-options.ENC-TKT-IN-SKEY) then
+ body.additional-tickets_ticket := second TGT;
+ endif
+
+ request.req-body := body;
+ check := generate_checksum (req.body,checksumtype);
+
+ request.padata[0].padata-type := PA-TGS-REQ;
+ request.padata[0].padata-value := create a KRB_AP_REQ using
+ the TGT and checksum
+
+ /* add in any other padata as required/supplied */
+
+ kerberos := lookup(name of local kerberose server (or servers));
+ send(packet,kerberos);
+
+ wait(for response);
+ if (timed_out) then
+ retry or use alternate server;
+ endif
+
+A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation
+ /* note that reading the application request requires first
+ determining the server for which a ticket was issued, and choosing the
+ correct key for decryption. The name of the server appears in the
+ plaintext part of the ticket. */
+
+ if (no KRB_AP_REQ in req.padata) then
+ error_out(KDC_ERR_PADATA_TYPE_NOSUPP);
+ endif
+ verify KRB_AP_REQ in req.padata;
+
+ /* Note that the realm in which the Kerberos server is operating is
+ determined by the instance from the ticket-granting ticket. The realm
+ in the ticket-granting ticket is the realm under which the ticket
+ granting ticket was issued. It is possible for a single Kerberos
+ server to support more than one realm. */
+
+ auth_hdr := KRB_AP_REQ;
+ tgt := auth_hdr.ticket;
+
+ if (tgt.sname is not a TGT for local realm and is not req.sname) then
+ error_out(KRB_AP_ERR_NOT_US);
+
+ realm := realm_tgt_is_for(tgt);
+
+ decode remainder of request;
+
+ if (auth_hdr.authenticator.cksum is missing) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+
+
+Section A.6. - 106 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ if (auth_hdr.authenticator.cksum type is not supported) then
+ error_out(KDC_ERR_SUMTYPE_NOSUPP);
+ endif
+ if (auth_hdr.authenticator.cksum is not both collision-proof and keyed) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+
+ set computed_checksum := checksum(req);
+ if (computed_checksum != auth_hdr.authenticatory.cksum) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ server := lookup(req.sname,realm);
+
+ if (!server) then
+ if (is_foreign_tgt_name(server)) then
+ server := best_intermediate_tgs(server);
+ else
+ /* no server in Database */
+ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
+ endif
+ endif
+
+ session := generate_random_session_key();
+
+
+ use_etype := first supported etype in req.etypes;
+
+ if (no support for req.etypes) then
+ error_out(KDC_ERR_ETYPE_NOSUPP);
+ endif
+
+ new_tkt.vno := ticket version; /* = 5 */
+ new_tkt.sname := req.sname;
+ new_tkt.srealm := realm;
+ reset all flags in new_tkt.flags;
+
+ /* It should be noted that local policy may affect the */
+ /* processing of any of these flags. For example, some */
+ /* realms may refuse to issue renewable tickets */
+
+ new_tkt.caddr := tgt.caddr;
+ resp.caddr := NULL; /* We only include this if they change */
+ if (req.kdc-options.FORWARDABLE is set) then
+ if (tgt.flags.FORWARDABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.FORWARDABLE;
+ endif
+ if (req.kdc-options.FORWARDED is set) then
+ if (tgt.flags.FORWARDABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.FORWARDED;
+
+
+Section A.6. - 107 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ new_tkt.caddr := req.addresses;
+ resp.caddr := req.addresses;
+ endif
+ if (tgt.flags.FORWARDED is set) then
+ set new_tkt.flags.FORWARDED;
+ endif
+
+ if (req.kdc-options.PROXIABLE is set) then
+ if (tgt.flags.PROXIABLE is reset)
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.PROXIABLE;
+ endif
+ if (req.kdc-options.PROXY is set) then
+ if (tgt.flags.PROXIABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.PROXY;
+ new_tkt.caddr := req.addresses;
+ resp.caddr := req.addresses;
+ endif
+
+ if (req.kdc-options.ALLOW-POSTDATE is set) then
+ if (tgt.flags.MAY-POSTDATE is reset)
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.MAY-POSTDATE;
+ endif
+ if (req.kdc-options.POSTDATED is set) then
+ if (tgt.flags.MAY-POSTDATE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.POSTDATED;
+ set new_tkt.flags.INVALID;
+ if (against_postdate_policy(req.from)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ new_tkt.starttime := req.from;
+ endif
+
+
+ if (req.kdc-options.VALIDATE is set) then
+ if (tgt.flags.INVALID is reset) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ if (tgt.starttime > kdc_time) then
+ error_out(KRB_AP_ERR_NYV);
+ endif
+ if (check_hot_list(tgt)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ tkt := tgt;
+ reset new_tkt.flags.INVALID;
+ endif
+
+
+Section A.6. - 108 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ if (req.kdc-options.(any flag except ENC-TKT-IN-SKEY, RENEW,
+ and those already processed) is set) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+ new_tkt.authtime := tgt.authtime;
+
+ if (req.kdc-options.RENEW is set) then
+ /* Note that if the endtime has already passed, the ticket would */
+ /* have been rejected in the initial authentication stage, so */
+ /* there is no need to check again here */
+ if (tgt.flags.RENEWABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ if (tgt.renew-till >= kdc_time) then
+ error_out(KRB_AP_ERR_TKT_EXPIRED);
+ endif
+ tkt := tgt;
+ new_tkt.starttime := kdc_time;
+ old_life := tgt.endttime - tgt.starttime;
+ new_tkt.endtime := min(tgt.renew-till,
+ new_tkt.starttime + old_life);
+ else
+ new_tkt.starttime := kdc_time;
+ if (req.till = 0) then
+ till := infinity;
+ else
+ till := req.till;
+ endif
+ new_tkt.endtime := min(till,
+ new_tkt.starttime+client.max_life,
+ new_tkt.starttime+server.max_life,
+ new_tkt.starttime+max_life_for_realm,
+ tgt.endtime);
+
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (new_tkt.endtime < req.till) and
+ (tgt.flags.RENEWABLE is set) then
+ /* we set the RENEWABLE option for later processing */
+ set req.kdc-options.RENEWABLE;
+ req.rtime := min(req.till, tgt.renew-till);
+ endif
+ endif
+
+ if (req.rtime = 0) then
+ rtime := infinity;
+ else
+ rtime := req.rtime;
+ endif
+
+ if ((req.kdc-options.RENEWABLE is set) and
+ (tgt.flags.RENEWABLE is set)) then
+ set new_tkt.flags.RENEWABLE;
+ new_tkt.renew-till := min(rtime,
+
+
+Section A.6. - 109 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ new_tkt.starttime+client.max_rlife,
+ new_tkt.starttime+server.max_rlife,
+ new_tkt.starttime+max_rlife_for_realm,
+ tgt.renew-till);
+ else
+ new_tkt.renew-till := OMIT; /* leave the renew-till field out */
+ endif
+ if (req.enc-authorization-data is present) then
+ decrypt req.enc-authorization-data into decrypted_authorization_data
+ using auth_hdr.authenticator.subkey;
+ if (decrypt_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ endif
+ new_tkt.authorization_data := req.auth_hdr.ticket.authorization_data +
+ decrypted_authorization_data;
+
+ new_tkt.key := session;
+ new_tkt.crealm := tgt.crealm;
+ new_tkt.cname := req.auth_hdr.ticket.cname;
+
+ if (realm_tgt_is_for(tgt) := tgt.realm) then
+ /* tgt issued by local realm */
+ new_tkt.transited := tgt.transited;
+ else
+ /* was issued for this realm by some other realm */
+ if (tgt.transited.tr-type not supported) then
+ error_out(KDC_ERR_TRTYPE_NOSUPP);
+ endif
+ new_tkt.transited := compress_transited(tgt.transited + tgt.realm)
+ endif
+
+ encode encrypted part of new_tkt into OCTET STRING;
+ if (req.kdc-options.ENC-TKT-IN-SKEY is set) then
+ if (server not specified) then
+ server = req.second_ticket.client;
+ endif
+ if ((req.second_ticket is not a TGT) or
+ (req.second_ticket.client != server)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+
+ new_tkt.enc-part := encrypt OCTET STRING using
+ using etype_for_key(second-ticket.key), second-ticket.key;
+ else
+ new_tkt.enc-part := encrypt OCTET STRING
+ using etype_for_key(server.key), server.key, server.p_kvno;
+ endif
+
+ resp.pvno := 5;
+ resp.msg-type := KRB_TGS_REP;
+ resp.crealm := tgt.crealm;
+ resp.cname := tgt.cname;
+
+
+
+Section A.6. - 110 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ resp.ticket := new_tkt;
+
+ resp.key := session;
+ resp.nonce := req.nonce;
+ resp.last-req := fetch_last_request_info(client);
+ resp.flags := new_tkt.flags;
+
+ resp.authtime := new_tkt.authtime;
+ resp.starttime := new_tkt.starttime;
+ resp.endtime := new_tkt.endtime;
+
+ omit resp.key-expiration;
+
+ resp.sname := new_tkt.sname;
+ resp.realm := new_tkt.realm;
+
+ if (new_tkt.flags.RENEWABLE) then
+ resp.renew-till := new_tkt.renew-till;
+ endif
+
+
+ encode body of reply into OCTET STRING;
+
+ if (req.padata.authenticator.subkey)
+ resp.enc-part := encrypt OCTET STRING using use_etype,
+ req.padata.authenticator.subkey;
+ else resp.enc-part := encrypt OCTET STRING using use_etype, tgt.key;
+
+ send(resp);
+
+A.7. KRB_TGS_REP verification
+ decode response into resp;
+
+ if (resp.msg-type = KRB_ERROR) then
+ process_error(resp);
+ return;
+ endif
+
+ /* On error, discard the response, and zero the session key from
+ the response immediately */
+
+ if (req.padata.authenticator.subkey)
+ unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and subkey;
+ else unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and tgt's session key;
+ if (common_as_rep_tgs_rep_checks fail) then
+ destroy resp.key;
+ return error;
+ endif
+
+ check authorization_data as necessary;
+ save_for_later(ticket,session,client,server,times,flags);
+
+
+
+Section A.7. - 111 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+A.8. Authenticator generation
+ body.authenticator-vno := authenticator vno; /* = 5 */
+ body.cname, body.crealm := client name;
+ if (supplying checksum) then
+ body.cksum := checksum;
+ endif
+ get system_time;
+ body.ctime, body.cusec := system_time;
+ if (selecting sub-session key) then
+ select sub-session key;
+ body.subkey := sub-session key;
+ endif
+ if (using sequence numbers) then
+ select initial sequence number;
+ body.seq-number := initial sequence;
+ endif
+
+A.9. KRB_AP_REQ generation
+ obtain ticket and session_key from cache;
+
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_AP_REQ */
+
+ if (desired(MUTUAL_AUTHENTICATION)) then
+ set packet.ap-options.MUTUAL-REQUIRED;
+ else
+ reset packet.ap-options.MUTUAL-REQUIRED;
+ endif
+ if (using session key for ticket) then
+ set packet.ap-options.USE-SESSION-KEY;
+ else
+ reset packet.ap-options.USE-SESSION-KEY;
+ endif
+ packet.ticket := ticket; /* ticket */
+ generate authenticator;
+ encode authenticator into OCTET STRING;
+ encrypt OCTET STRING into packet.authenticator using session_key;
+
+A.10. KRB_AP_REQ verification
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_AP_REQ) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ if (packet.ticket.tkt_vno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.ap_options.USE-SESSION-KEY is set) then
+ retrieve session key from ticket-granting ticket for
+ packet.ticket.{sname,srealm,enc-part.etype};
+
+
+Section A.10. - 112 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ else
+ retrieve service key for
+ packet.ticket.{sname,srealm,enc-part.etype,enc-part.skvno};
+ endif
+ if (no_key_available) then
+ if (cannot_find_specified_skvno) then
+ error_out(KRB_AP_ERR_BADKEYVER);
+ else
+ error_out(KRB_AP_ERR_NOKEY);
+ endif
+ endif
+ decrypt packet.ticket.enc-part into decr_ticket using retrieved key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ decrypt packet.authenticator into decr_authenticator
+ using decr_ticket.key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if (decr_authenticator.{cname,crealm} !=
+ decr_ticket.{cname,crealm}) then
+ error_out(KRB_AP_ERR_BADMATCH);
+ endif
+ if (decr_ticket.caddr is present) then
+ if (sender_address(packet) is not in decr_ticket.caddr) then
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ elseif (application requires addresses) then
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (not in_clock_skew(decr_authenticator.ctime,
+ decr_authenticator.cusec)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(decr_authenticator.{ctime,cusec,cname,crealm})) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ save_identifier(decr_authenticator.{ctime,cusec,cname,crealm});
+ get system_time;
+ if ((decr_ticket.starttime-system_time > CLOCK_SKEW) or
+ (decr_ticket.flags.INVALID is set)) then
+ /* it hasn't yet become valid */
+ error_out(KRB_AP_ERR_TKT_NYV);
+ endif
+ if (system_time-decr_ticket.endtime > CLOCK_SKEW) then
+ error_out(KRB_AP_ERR_TKT_EXPIRED);
+ endif
+ /* caller must check decr_ticket.flags for any pertinent details */
+ return(OK, decr_ticket, packet.ap_options.MUTUAL-REQUIRED);
+
+A.11. KRB_AP_REP generation
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_AP_REP */
+
+
+Section A.11. - 113 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ body.ctime := packet.ctime;
+ body.cusec := packet.cusec;
+ if (selecting sub-session key) then
+ select sub-session key;
+ body.subkey := sub-session key;
+ endif
+ if (using sequence numbers) then
+ select initial sequence number;
+ body.seq-number := initial sequence;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part;
+
+A.12. KRB_AP_REP verification
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_AP_REP) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ cleartext := decrypt(packet.enc-part) using ticket's session key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if (cleartext.ctime != authenticator.ctime) then
+ error_out(KRB_AP_ERR_MUT_FAIL);
+ endif
+ if (cleartext.cusec != authenticator.cusec) then
+ error_out(KRB_AP_ERR_MUT_FAIL);
+ endif
+ if (cleartext.subkey is present) then
+ save cleartext.subkey for future use;
+ endif
+ if (cleartext.seq-number is present) then
+ save cleartext.seq-number for future verifications;
+ endif
+ return(AUTHENTICATION_SUCCEEDED);
+
+A.13. KRB_SAFE generation
+ collect user data in buffer;
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_SAFE */
+
+ body.user-data := buffer; /* DATA */
+ if (using timestamp) then
+ get system_time;
+ body.timestamp, body.usec := system_time;
+
+
+Section A.13. - 114 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ endif
+ if (using sequence numbers) then
+ body.seq-number := sequence number;
+ endif
+ body.s-address := sender host addresses;
+ if (only one recipient) then
+ body.r-address := recipient host address;
+ endif
+ checksum.cksumtype := checksum type;
+ compute checksum over body;
+ checksum.checksum := checksum value; /* checksum.checksum */
+ packet.cksum := checksum;
+ packet.safe-body := body;
+
+A.14. KRB_SAFE verification
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_SAFE) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ if (packet.checksum.cksumtype is not both collision-proof and keyed) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+ if (safe_priv_common_checks_ok(packet)) then
+ set computed_checksum := checksum(packet.body);
+ if (computed_checksum != packet.checksum) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+ return (packet, PACKET_IS_GENUINE);
+ else
+ return common_checks_error;
+ endif
+
+A.15. KRB_SAFE and KRB_PRIV common checks
+ if (packet.s-address != O/S_sender(packet)) then
+ /* O/S report of sender not who claims to have sent it */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if ((packet.r-address is present) and
+ (packet.r-address != local_host_address)) then
+ /* was not sent to proper place */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (((packet.timestamp is present) and
+ (not in_clock_skew(packet.timestamp,packet.usec))) or
+ (packet.timestamp is not present and timestamp expected)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(packet.timestamp,packet.usec,packet.s-address)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+
+
+Section A.15. - 115 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ if (((packet.seq-number is present) and
+ ((not in_sequence(packet.seq-number)))) or
+ (packet.seq-number is not present and sequence expected)) then
+ error_out(KRB_AP_ERR_BADORDER);
+ endif
+ if (packet.timestamp not present and packet.seq-number not present) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ save_identifier(packet.{timestamp,usec,s-address},
+ sender_principal(packet));
+
+ return PACKET_IS_OK;
+
+A.16. KRB_PRIV generation
+ collect user data in buffer;
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_PRIV */
+
+ packet.enc-part.etype := encryption type;
+
+ body.user-data := buffer;
+ if (using timestamp) then
+ get system_time;
+ body.timestamp, body.usec := system_time;
+ endif
+ if (using sequence numbers) then
+ body.seq-number := sequence number;
+ endif
+ body.s-address := sender host addresses;
+ if (only one recipient) then
+ body.r-address := recipient host address;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part.cipher;
+
+
+A.17. KRB_PRIV verification
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_PRIV) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+
+ cleartext := decrypt(packet.enc-part) using negotiated key;
+ if (decryption_error()) then
+
+
+Section A.17. - 116 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+
+ if (safe_priv_common_checks_ok(cleartext)) then
+ return(cleartext.DATA, PACKET_IS_GENUINE_AND_UNMODIFIED);
+ else
+ return common_checks_error;
+ endif
+
+A.18. KRB_CRED generation
+ invoke KRB_TGS; /* obtain tickets to be provided to peer */
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_CRED */
+
+ for (tickets[n] in tickets to be forwarded) do
+ packet.tickets[n] = tickets[n].ticket;
+ done
+
+ packet.enc-part.etype := encryption type;
+
+ for (ticket[n] in tickets to be forwarded) do
+ body.ticket-info[n].key = tickets[n].session;
+ body.ticket-info[n].prealm = tickets[n].crealm;
+ body.ticket-info[n].pname = tickets[n].cname;
+ body.ticket-info[n].flags = tickets[n].flags;
+ body.ticket-info[n].authtime = tickets[n].authtime;
+ body.ticket-info[n].starttime = tickets[n].starttime;
+ body.ticket-info[n].endtime = tickets[n].endtime;
+ body.ticket-info[n].renew-till = tickets[n].renew-till;
+ body.ticket-info[n].srealm = tickets[n].srealm;
+ body.ticket-info[n].sname = tickets[n].sname;
+ body.ticket-info[n].caddr = tickets[n].caddr;
+ done
+
+ get system_time;
+ body.timestamp, body.usec := system_time;
+
+ if (using nonce) then
+ body.nonce := nonce;
+ endif
+
+ if (using s-address) then
+ body.s-address := sender host addresses;
+ endif
+ if (limited recipients) then
+ body.r-address := recipient host address;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part.cipher
+
+
+Section A.18. - 117 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ using negotiated encryption key;
+
+
+A.19. KRB_CRED verification
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_CRED) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+
+ cleartext := decrypt(packet.enc-part) using negotiated key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if ((packet.r-address is present or required) and
+ (packet.s-address != O/S_sender(packet)) then
+ /* O/S report of sender not who claims to have sent it */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if ((packet.r-address is present) and
+ (packet.r-address != local_host_address)) then
+ /* was not sent to proper place */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (not in_clock_skew(packet.timestamp,packet.usec)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(packet.timestamp,packet.usec,packet.s-address)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ if (packet.nonce is required or present) and
+ (packet.nonce != expected-nonce) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ for (ticket[n] in tickets that were forwarded) do
+ save_for_later(ticket[n],key[n],principal[n],
+ server[n],times[n],flags[n]);
+ return
+
+A.20. KRB_ERROR generation
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_ERROR */
+
+ get system_time;
+ packet.stime, packet.susec := system_time;
+ packet.realm, packet.sname := server name;
+
+ if (client time available) then
+
+
+Section A.20. - 118 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+ packet.ctime, packet.cusec := client_time;
+ endif
+ packet.error-code := error code;
+ if (client name available) then
+ packet.cname, packet.crealm := client name;
+ endif
+ if (error text available) then
+ packet.e-text := error text;
+ endif
+ if (error data available) then
+ packet.e-data := error data;
+ endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - 119 - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - cxx - Expires 11 January 1998
+
+
+
+
+
+
+
+
+
+
+ Table of Contents
+
+
+
+
+Overview .............................................. 2
+
+Background ............................................ 2
+
+1. Introduction ....................................... 3
+
+1.1. Cross-Realm Operation ............................ 5
+
+1.2. Authorization .................................... 6
+
+1.3. Environmental assumptions ........................ 7
+
+1.4. Glossary of terms ................................ 8
+
+2. Ticket flag uses and requests ...................... 10
+
+2.1. Initial and pre-authenticated tickets ............ 10
+
+2.2. Invalid tickets .................................. 11
+
+2.3. Renewable tickets ................................ 11
+
+2.4. Postdated tickets ................................ 12
+
+2.5. Proxiable and proxy tickets ...................... 12
+
+2.6. Forwardable tickets .............................. 13
+
+2.7. Other KDC options ................................ 14
+
+3. Message Exchanges .................................. 14
+
+3.1. The Authentication Service Exchange .............. 14
+
+3.1.1. Generation of KRB_AS_REQ message ............... 16
+
+3.1.2. Receipt of KRB_AS_REQ message .................. 16
+
+3.1.3. Generation of KRB_AS_REP message ............... 16
+
+3.1.4. Generation of KRB_ERROR message ................ 19
+
+3.1.5. Receipt of KRB_AS_REP message .................. 19
+
+3.1.6. Receipt of KRB_ERROR message ................... 19
+
+3.2. The Client/Server Authentication Exchange ........ 19
+
+3.2.1. The KRB_AP_REQ message ......................... 20
+
+
+ - i - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+3.2.2. Generation of a KRB_AP_REQ message ............. 20
+
+3.2.3. Receipt of KRB_AP_REQ message .................. 21
+
+3.2.4. Generation of a KRB_AP_REP message ............. 23
+
+3.2.5. Receipt of KRB_AP_REP message .................. 23
+
+3.2.6. Using the encryption key ....................... 24
+
+3.3. The Ticket-Granting Service (TGS) Exchange ....... 25
+
+3.3.1. Generation of KRB_TGS_REQ message .............. 26
+
+3.3.2. Receipt of KRB_TGS_REQ message ................. 27
+
+3.3.3. Generation of KRB_TGS_REP message .............. 28
+
+3.3.3.1. Checking for revoked tickets ................. 30
+
+3.3.3.2. Encoding the transited field ................. 30
+
+3.3.4. Receipt of KRB_TGS_REP message ................. 32
+
+3.4. The KRB_SAFE Exchange ............................ 32
+
+3.4.1. Generation of a KRB_SAFE message ............... 32
+
+3.4.2. Receipt of KRB_SAFE message .................... 33
+
+3.5. The KRB_PRIV Exchange ............................ 34
+
+3.5.1. Generation of a KRB_PRIV message ............... 34
+
+3.5.2. Receipt of KRB_PRIV message .................... 34
+
+3.6. The KRB_CRED Exchange ............................ 35
+
+3.6.1. Generation of a KRB_CRED message ............... 35
+
+3.6.2. Receipt of KRB_CRED message .................... 35
+
+4. The Kerberos Database .............................. 36
+
+4.1. Database contents ................................ 36
+
+4.2. Additional fields ................................ 37
+
+4.3. Frequently Changing Fields ....................... 38
+
+4.4. Site Constants ................................... 39
+
+5. Message Specifications ............................. 39
+
+
+
+ - ii - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+5.1. ASN.1 Distinguished Encoding Representation ...... 39
+
+5.2. ASN.1 Base Definitions ........................... 40
+
+5.3. Tickets and Authenticators ....................... 43
+
+5.3.1. Tickets ........................................ 43
+
+5.3.2. Authenticators ................................. 52
+
+5.4. Specifications for the AS and TGS exchanges ...... 54
+
+5.4.1. KRB_KDC_REQ definition ......................... 54
+
+5.4.2. KRB_KDC_REP definition ......................... 61
+
+5.5. Client/Server (CS) message specifications ........ 64
+
+5.5.1. KRB_AP_REQ definition .......................... 64
+
+5.5.2. KRB_AP_REP definition .......................... 65
+
+5.5.3. Error message reply ............................ 67
+
+5.6. KRB_SAFE message specification ................... 67
+
+5.6.1. KRB_SAFE definition ............................ 67
+
+5.7. KRB_PRIV message specification ................... 68
+
+5.7.1. KRB_PRIV definition ............................ 68
+
+5.8. KRB_CRED message specification ................... 69
+
+5.8.1. KRB_CRED definition ............................ 70
+
+5.9. Error message specification ...................... 72
+
+5.9.1. KRB_ERROR definition ........................... 72
+
+6. Encryption and Checksum Specifications ............. 74
+
+6.1. Encryption Specifications ........................ 76
+
+6.2. Encryption Keys .................................. 78
+
+6.3. Encryption Systems ............................... 78
+
+6.3.1. The NULL Encryption System (null) .............. 78
+
+6.3.2. DES in CBC mode with a CRC-32 checksum (des-
+cbc-crc) .............................................. 79
+
+6.3.3. DES in CBC mode with an MD4 checksum (des-
+
+
+ - iii - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+cbc-md4) .............................................. 79
+
+6.3.4. DES in CBC mode with an MD5 checksum (des-
+cbc-md5) .............................................. 79
+
+6.3.5. Triple DES EDE in outer CBC mode with an SHA1
+checksum (des3-cbc-sha1) .............................. 81
+
+6.4. Checksums ........................................ 83
+
+6.4.1. The CRC-32 Checksum (crc32) .................... 84
+
+6.4.2. The RSA MD4 Checksum (rsa-md4) ................. 84
+
+6.4.3. RSA MD4 Cryptographic Checksum Using DES
+(rsa-md4-des) ......................................... 84
+
+6.4.4. The RSA MD5 Checksum (rsa-md5) ................. 85
+
+6.4.5. RSA MD5 Cryptographic Checksum Using DES
+(rsa-md5-des) ......................................... 85
+
+6.4.6. DES cipher-block chained checksum (des-mac)
+
+6.4.7. RSA MD4 Cryptographic Checksum Using DES
+alternative (rsa-md4-des-k) ........................... 86
+
+6.4.8. DES cipher-block chained checksum alternative
+(des-mac-k) ........................................... 87
+
+7. Naming Constraints ................................. 87
+
+7.1. Realm Names ...................................... 87
+
+7.2. Principal Names .................................. 88
+
+7.2.1. Name of server principals ...................... 89
+
+8. Constants and other defined values ................. 90
+
+8.1. Host address types ............................... 90
+
+8.2. KDC messages ..................................... 91
+
+8.2.1. IP transport ................................... 91
+
+8.2.2. OSI transport .................................. 91
+
+8.2.3. Name of the TGS ................................ 92
+
+8.3. Protocol constants and associated values ......... 92
+
+9. Interoperability requirements ...................... 95
+
+
+
+ - iv - Expires 11 January 1998
+
+
+
+
+
+
+
+ Version 5 - Specification Revision 6
+
+
+9.1. Specification 1 .................................. 95
+
+9.2. Recommended KDC values ........................... 97
+
+10. REFERENCES ........................................ 98
+
+A. Pseudo-code for protocol processing ................ 100
+
+A.1. KRB_AS_REQ generation ............................ 100
+
+A.2. KRB_AS_REQ verification and KRB_AS_REP genera-
+tion .................................................. 100
+
+A.3. KRB_AS_REP verification .......................... 104
+
+A.4. KRB_AS_REP and KRB_TGS_REP common checks ......... 104
+
+A.5. KRB_TGS_REQ generation ........................... 105
+
+A.6. KRB_TGS_REQ verification and KRB_TGS_REP gen-
+eration ............................................... 106
+
+A.7. KRB_TGS_REP verification ......................... 111
+
+A.8. Authenticator generation ......................... 112
+
+A.9. KRB_AP_REQ generation ............................ 112
+
+A.10. KRB_AP_REQ verification ......................... 112
+
+A.11. KRB_AP_REP generation ........................... 113
+
+A.12. KRB_AP_REP verification ......................... 114
+
+A.13. KRB_SAFE generation ............................. 114
+
+A.14. KRB_SAFE verification ........................... 115
+
+A.15. KRB_SAFE and KRB_PRIV common checks ............. 115
+
+A.16. KRB_PRIV generation ............................. 116
+
+A.17. KRB_PRIV verification ........................... 116
+
+A.18. KRB_CRED generation ............................. 117
+
+A.19. KRB_CRED verification ........................... 118
+
+A.20. KRB_ERROR generation ............................ 118
+
+
+
+
+
+
+
+ - v - Expires 11 January 1998
+
+
+
+
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-01.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-01.txt
new file mode 100644
index 000000000000..78db9d78f3cb
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-01.txt
@@ -0,0 +1,6214 @@
+
+INTERNET-DRAFT Clifford Neuman
+ John Kohl
+ Theodore Ts'o
+ 21 November 1997
+
+The Kerberos Network Authentication Service (V5)
+
+STATUS OF THIS MEMO
+
+This document is an Internet-Draft. Internet-Drafts are working documents of
+the Internet Engineering Task Force (IETF), its areas, and its working
+groups. Note that other groups may also distribute working documents as
+Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum of six months and
+may be updated, replaced, or obsoleted by other documents at any time. It is
+inappropriate to use Internet-Drafts as reference material or to cite them
+other than as 'work in progress.'
+
+To learn the current status of any Internet-Draft, please check the
+'1id-abstracts.txt' listing contained in the Internet-Drafts Shadow
+Directories on ds.internic.net (US East Coast), nic.nordu.net (Europe),
+ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific Rim).
+
+The distribution of this memo is unlimited. It is filed as
+draft-ietf-cat-kerberos-r-01.txt, and expires 21 May 1998. Please send
+comments to: krb-protocol@MIT.EDU
+
+ABSTRACT
+
+This document provides an overview and specification of Version 5 of the
+Kerberos protocol, and updates RFC1510 to clarify aspects of the protocol
+and its intended use that require more detailed or clearer explanation than
+was provided in RFC1510. This document is intended to provide a detailed
+description of the protocol, suitable for implementation, together with
+descriptions of the appropriate use of protocol messages and fields within
+those messages.
+
+This document is not intended to describe Kerberos to the end user, system
+administrator, or application developer. Higher level papers describing
+Version 5 of the Kerberos system [NT94] and documenting version 4 [SNS88],
+are available elsewhere.
+
+OVERVIEW
+
+This INTERNET-DRAFT describes the concepts and model upon which the Kerberos
+network authentication system is based. It also specifies Version 5 of the
+Kerberos protocol.
+
+The motivations, goals, assumptions, and rationale behind most design
+decisions are treated cursorily; they are more fully described in a paper
+available in IEEE communications [NT94] and earlier in the Kerberos portion
+of the Athena Technical Plan [MNSS87]. The protocols have been a proposed
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+standard and are being considered for advancement for draft standard through
+the IETF standard process. Comments are encouraged on the presentation, but
+only minor refinements to the protocol as implemented or extensions that fit
+within current protocol framework will be considered at this time.
+
+Requests for addition to an electronic mailing list for discussion of
+Kerberos, kerberos@MIT.EDU, may be addressed to kerberos-request@MIT.EDU.
+This mailing list is gatewayed onto the Usenet as the group
+comp.protocols.kerberos. Requests for further information, including
+documents and code availability, may be sent to info-kerberos@MIT.EDU.
+
+BACKGROUND
+
+The Kerberos model is based in part on Needham and Schroeder's trusted
+third-party authentication protocol [NS78] and on modifications suggested by
+Denning and Sacco [DS81]. The original design and implementation of Kerberos
+Versions 1 through 4 was the work of two former Project Athena staff
+members, Steve Miller of Digital Equipment Corporation and Clifford Neuman
+(now at the Information Sciences Institute of the University of Southern
+California), along with Jerome Saltzer, Technical Director of Project
+Athena, and Jeffrey Schiller, MIT Campus Network Manager. Many other members
+of Project Athena have also contributed to the work on Kerberos.
+
+Version 5 of the Kerberos protocol (described in this document) has evolved
+from Version 4 based on new requirements and desires for features not
+available in Version 4. The design of Version 5 of the Kerberos protocol was
+led by Clifford Neuman and John Kohl with much input from the community. The
+development of the MIT reference implementation was led at MIT by John Kohl
+and Theodore T'so, with help and contributed code from many others.
+Reference implementations of both version 4 and version 5 of Kerberos are
+publicly available and commercial implementations have been developed and
+are widely used.
+
+Details on the differences between Kerberos Versions 4 and 5 can be found in
+[KNT92].
+
+1. Introduction
+
+Kerberos provides a means of verifying the identities of principals, (e.g. a
+workstation user or a network server) on an open (unprotected) network. This
+is accomplished without relying on assertions by the host operating system,
+without basing trust on host addresses, without requiring physical security
+of all the hosts on the network, and under the assumption that packets
+traveling along the network can be read, modified, and inserted at will[1].
+Kerberos performs authentication under these conditions as a trusted
+third-party authentication service by using conventional (shared secret key
+[2] cryptography. Kerberos extensions have been proposed and implemented
+that provide for the use of public key cryptography during certain phases of
+the authentication protocol. These extensions provide for authentication of
+users registered with public key certification authorities, and allow the
+system to provide certain benefits of public key cryptography in situations
+where they are needed.
+
+The basic Kerberos authentication process proceeds as follows: A client
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+sends a request to the authentication server (AS) requesting 'credentials'
+for a given server. The AS responds with these credentials, encrypted in the
+client's key. The credentials consist of 1) a 'ticket' for the server and 2)
+a temporary encryption key (often called a "session key"). The client
+transmits the ticket (which contains the client's identity and a copy of the
+session key, all encrypted in the server's key) to the server. The session
+key (now shared by the client and server) is used to authenticate the
+client, and may optionally be used to authenticate the server. It may also
+be used to encrypt further communication between the two parties or to
+exchange a separate sub-session key to be used to encrypt further
+communication.
+
+Implementation of the basic protocol consists of one or more authentication
+servers running on physically secure hosts. The authentication servers
+maintain a database of principals (i.e., users and servers) and their secret
+keys. Code libraries provide encryption and implement the Kerberos protocol.
+In order to add authentication to its transactions, a typical network
+application adds one or two calls to the Kerberos library directly or
+through the Generic Security Services Application Programming Interface,
+GSSAPI, described in separate document. These calls result in the
+transmission of the necessary messages to achieve authentication.
+
+The Kerberos protocol consists of several sub-protocols (or exchanges).
+There are two basic methods by which a client can ask a Kerberos server for
+credentials. In the first approach, the client sends a cleartext request for
+a ticket for the desired server to the AS. The reply is sent encrypted in
+the client's secret key. Usually this request is for a ticket-granting
+ticket (TGT) which can later be used with the ticket-granting server (TGS).
+In the second method, the client sends a request to the TGS. The client uses
+the TGT to authenticate itself to the TGS in the same manner as if it were
+contacting any other application server that requires Kerberos
+authentication. The reply is encrypted in the session key from the TGT.
+Though the protocol specification describes the AS and the TGS as separate
+servers, they are implemented in practice as different protocol entry points
+within a single Kerberos server.
+
+Once obtained, credentials may be used to verify the identity of the
+principals in a transaction, to ensure the integrity of messages exchanged
+between them, or to preserve privacy of the messages. The application is
+free to choose whatever protection may be necessary.
+
+To verify the identities of the principals in a transaction, the client
+transmits the ticket to the application server. Since the ticket is sent "in
+the clear" (parts of it are encrypted, but this encryption doesn't thwart
+replay) and might be intercepted and reused by an attacker, additional
+information is sent to prove that the message originated with the principal
+to whom the ticket was issued. This information (called the authenticator)
+is encrypted in the session key, and includes a timestamp. The timestamp
+proves that the message was recently generated and is not a replay.
+Encrypting the authenticator in the session key proves that it was generated
+by a party possessing the session key. Since no one except the requesting
+principal and the server know the session key (it is never sent over the
+network in the clear) this guarantees the identity of the client.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+The integrity of the messages exchanged between principals can also be
+guaranteed using the session key (passed in the ticket and contained in the
+credentials). This approach provides detection of both replay attacks and
+message stream modification attacks. It is accomplished by generating and
+transmitting a collision-proof checksum (elsewhere called a hash or digest
+function) of the client's message, keyed with the session key. Privacy and
+integrity of the messages exchanged between principals can be secured by
+encrypting the data to be passed using the session key contained in the
+ticket or the subsession key found in the authenticator.
+
+The authentication exchanges mentioned above require read-only access to the
+Kerberos database. Sometimes, however, the entries in the database must be
+modified, such as when adding new principals or changing a principal's key.
+This is done using a protocol between a client and a third Kerberos server,
+the Kerberos Administration Server (KADM). There is also a protocol for
+maintaining multiple copies of the Kerberos database. Neither of these
+protocols are described in this document.
+
+1.1. Cross-Realm Operation
+
+The Kerberos protocol is designed to operate across organizational
+boundaries. A client in one organization can be authenticated to a server in
+another. Each organization wishing to run a Kerberos server establishes its
+own 'realm'. The name of the realm in which a client is registered is part
+of the client's name, and can be used by the end-service to decide whether
+to honor a request.
+
+By establishing 'inter-realm' keys, the administrators of two realms can
+allow a client authenticated in the local realm to prove its identity to
+servers in other realms[3]. The exchange of inter-realm keys (a separate key
+may be used for each direction) registers the ticket-granting service of
+each realm as a principal in the other realm. A client is then able to
+obtain a ticket-granting ticket for the remote realm's ticket-granting
+service from its local realm. When that ticket-granting ticket is used, the
+remote ticket-granting service uses the inter-realm key (which usually
+differs from its own normal TGS key) to decrypt the ticket-granting ticket,
+and is thus certain that it was issued by the client's own TGS. Tickets
+issued by the remote ticket-granting service will indicate to the
+end-service that the client was authenticated from another realm.
+
+A realm is said to communicate with another realm if the two realms share an
+inter-realm key, or if the local realm shares an inter-realm key with an
+intermediate realm that communicates with the remote realm. An
+authentication path is the sequence of intermediate realms that are
+transited in communicating from one realm to another.
+
+Realms are typically organized hierarchically. Each realm shares a key with
+its parent and a different key with each child. If an inter-realm key is not
+directly shared by two realms, the hierarchical organization allows an
+authentication path to be easily constructed. If a hierarchical organization
+is not used, it may be necessary to consult a database in order to construct
+an authentication path between realms.
+
+Although realms are typically hierarchical, intermediate realms may be
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+bypassed to achieve cross-realm authentication through alternate
+authentication paths (these might be established to make communication
+between two realms more efficient). It is important for the end-service to
+know which realms were transited when deciding how much faith to place in
+the authentication process. To facilitate this decision, a field in each
+ticket contains the names of the realms that were involved in authenticating
+the client.
+
+The application server is ultimately responsible for accepting or rejecting
+authentication and should check the transited field. The application server
+may choose to rely on the KDC for the application server's realm to check
+the transited field. The application server's KDC will set the
+TRANSITED-POLICY-CHECKED flag in this case. The KDC's for intermediate
+realms may also check the transited field as they issue
+ticket-granting-tickets for other realms, but they are encouraged not to do
+so. A client may request that the KDC's not check the transited field by
+setting the DISABLE-TRANSITED-CHECK flag. KDC's are encouraged but not
+required to honor this flag.
+
+1.2. Authorization
+
+As an authentication service, Kerberos provides a means of verifying the
+identity of principals on a network. Authentication is usually useful
+primarily as a first step in the process of authorization, determining
+whether a client may use a service, which objects the client is allowed to
+access, and the type of access allowed for each. Kerberos does not, by
+itself, provide authorization. Possession of a client ticket for a service
+provides only for authentication of the client to that service, and in the
+absence of a separate authorization procedure, it should not be considered
+by an application as authorizing the use of that service.
+
+Such separate authorization methods may be implemented as application
+specific access control functions and may be based on files such as the
+application server, or on separately issued authorization credentials such
+as those based on proxies [Neu93] , or on other authorization services.
+
+Applications should not be modified to accept the issuance of a service
+ticket by the Kerberos server (even by an modified Kerberos server) as
+granting authority to use the service, since such applications may become
+vulnerable to the bypass of this authorization check in an environment if
+they interoperate with other KDCs or where other options for application
+authentication (e.g. the PKTAPP proposal) are provided.
+
+1.3. Environmental assumptions
+
+Kerberos imposes a few assumptions on the environment in which it can
+properly function:
+
+ * 'Denial of service' attacks are not solved with Kerberos. There are
+ places in these protocols where an intruder can prevent an application
+ from participating in the proper authentication steps. Detection and
+ solution of such attacks (some of which can appear to be nnot-uncommon
+ 'normal' failure modes for the system) is usually best left to the
+ human administrators and users.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ * Principals must keep their secret keys secret. If an intruder somehow
+ steals a principal's key, it will be able to masquerade as that
+ principal or impersonate any server to the legitimate principal.
+ * 'Password guessing' attacks are not solved by Kerberos. If a user
+ chooses a poor password, it is possible for an attacker to successfully
+ mount an offline dictionary attack by repeatedly attempting to decrypt,
+ with successive entries from a dictionary, messages obtained which are
+ encrypted under a key derived from the user's password.
+ * Each host on the network must have a clock which is 'loosely
+ synchronized' to the time of the other hosts; this synchronization is
+ used to reduce the bookkeeping needs of application servers when they
+ do replay detection. The degree of "looseness" can be configured on a
+ per-server basis, but is typically on the order of 5 minutes. If the
+ clocks are synchronized over the network, the clock synchronization
+ protocol must itself be secured from network attackers.
+ * Principal identifiers are not recycled on a short-term basis. A typical
+ mode of access control will use access control lists (ACLs) to grant
+ permissions to particular principals. If a stale ACL entry remains for
+ a deleted principal and the principal identifier is reused, the new
+ principal will inherit rights specified in the stale ACL entry. By not
+ re-using principal identifiers, the danger of inadvertent access is
+ removed.
+
+1.4. Glossary of terms
+
+Below is a list of terms used throughout this document.
+
+Authentication
+ Verifying the claimed identity of a principal.
+Authentication header
+ A record containing a Ticket and an Authenticator to be presented to a
+ server as part of the authentication process.
+Authentication path
+ A sequence of intermediate realms transited in the authentication
+ process when communicating from one realm to another.
+Authenticator
+ A record containing information that can be shown to have been recently
+ generated using the session key known only by the client and server.
+Authorization
+ The process of determining whether a client may use a service, which
+ objects the client is allowed to access, and the type of access allowed
+ for each.
+Capability
+ A token that grants the bearer permission to access an object or
+ service. In Kerberos, this might be a ticket whose use is restricted by
+ the contents of the authorization data field, but which lists no
+ network addresses, together with the session key necessary to use the
+ ticket.
+Ciphertext
+ The output of an encryption function. Encryption transforms plaintext
+ into ciphertext.
+Client
+ A process that makes use of a network service on behalf of a user. Note
+ that in some cases a Server may itself be a client of some other server
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ (e.g. a print server may be a client of a file server).
+Credentials
+ A ticket plus the secret session key necessary to successfully use that
+ ticket in an authentication exchange.
+KDC
+ Key Distribution Center, a network service that supplies tickets and
+ temporary session keys; or an instance of that service or the host on
+ which it runs. The KDC services both initial ticket and ticket-granting
+ ticket requests. The initial ticket portion is sometimes referred to as
+ the Authentication Server (or service). The ticket-granting ticket
+ portion is sometimes referred to as the ticket-granting server (or
+ service).
+Kerberos
+ Aside from the 3-headed dog guarding Hades, the name given to Project
+ Athena's authentication service, the protocol used by that service, or
+ the code used to implement the authentication service.
+Plaintext
+ The input to an encryption function or the output of a decryption
+ function. Decryption transforms ciphertext into plaintext.
+Principal
+ A uniquely named client or server instance that participates in a
+ network communication.
+Principal identifier
+ The name used to uniquely identify each different principal.
+Seal
+ To encipher a record containing several fields in such a way that the
+ fields cannot be individually replaced without either knowledge of the
+ encryption key or leaving evidence of tampering.
+Secret key
+ An encryption key shared by a principal and the KDC, distributed
+ outside the bounds of the system, with a long lifetime. In the case of
+ a human user's principal, the secret key is derived from a password.
+Server
+ A particular Principal which provides a resource to network clients.
+ The server is sometimes refered to as the Application Server.
+Service
+ A resource provided to network clients; often provided by more than one
+ server (for example, remote file service).
+Session key
+ A temporary encryption key used between two principals, with a lifetime
+ limited to the duration of a single login "session".
+Sub-session key
+ A temporary encryption key used between two principals, selected and
+ exchanged by the principals using the session key, and with a lifetime
+ limited to the duration of a single association.
+Ticket
+ A record that helps a client authenticate itself to a server; it
+ contains the client's identity, a session key, a timestamp, and other
+ information, all sealed using the server's secret key. It only serves
+ to authenticate a client when presented along with a fresh
+ Authenticator.
+
+2. Ticket flag uses and requests
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+Each Kerberos ticket contains a set of flags which are used to indicate
+various attributes of that ticket. Most flags may be requested by a client
+when the ticket is obtained; some are automatically turned on and off by a
+Kerberos server as required. The following sections explain what the various
+flags mean, and gives examples of reasons to use such a flag.
+
+2.1. Initial and pre-authenticated tickets
+
+The INITIAL flag indicates that a ticket was issued using the AS protocol
+and not issued based on a ticket-granting ticket. Application servers that
+want to require the demonstrated knowledge of a client's secret key (e.g. a
+password-changing program) can insist that this flag be set in any tickets
+they accept, and thus be assured that the client's key was recently
+presented to the application client.
+
+The PRE-AUTHENT and HW-AUTHENT flags provide addition information about the
+initial authentication, regardless of whether the current ticket was issued
+directly (in which case INITIAL will also be set) or issued on the basis of
+a ticket-granting ticket (in which case the INITIAL flag is clear, but the
+PRE-AUTHENT and HW-AUTHENT flags are carried forward from the
+ticket-granting ticket).
+
+2.2. Invalid tickets
+
+The INVALID flag indicates that a ticket is invalid. Application servers
+must reject tickets which have this flag set. A postdated ticket will
+usually be issued in this form. Invalid tickets must be validated by the KDC
+before use, by presenting them to the KDC in a TGS request with the VALIDATE
+option specified. The KDC will only validate tickets after their starttime
+has passed. The validation is required so that postdated tickets which have
+been stolen before their starttime can be rendered permanently invalid
+(through a hot-list mechanism) (see section 3.3.3.1).
+
+2.3. Renewable tickets
+
+Applications may desire to hold tickets which can be valid for long periods
+of time. However, this can expose their credentials to potential theft for
+equally long periods, and those stolen credentials would be valid until the
+expiration time of the ticket(s). Simply using short-lived tickets and
+obtaining new ones periodically would require the client to have long-term
+access to its secret key, an even greater risk. Renewable tickets can be
+used to mitigate the consequences of theft. Renewable tickets have two
+"expiration times": the first is when the current instance of the ticket
+expires, and the second is the latest permissible value for an individual
+expiration time. An application client must periodically (i.e. before it
+expires) present a renewable ticket to the KDC, with the RENEW option set in
+the KDC request. The KDC will issue a new ticket with a new session key and
+a later expiration time. All other fields of the ticket are left unmodified
+by the renewal process. When the latest permissible expiration time arrives,
+the ticket expires permanently. At each renewal, the KDC may consult a
+hot-list to determine if the ticket had been reported stolen since its last
+renewal; it will refuse to renew such stolen tickets, and thus the usable
+lifetime of stolen tickets is reduced.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+The RENEWABLE flag in a ticket is normally only interpreted by the
+ticket-granting service (discussed below in section 3.3). It can usually be
+ignored by application servers. However, some particularly careful
+application servers may wish to disallow renewable tickets.
+
+If a renewable ticket is not renewed by its expiration time, the KDC will
+not renew the ticket. The RENEWABLE flag is reset by default, but a client
+may request it be set by setting the RENEWABLE option in the KRB_AS_REQ
+message. If it is set, then the renew-till field in the ticket contains the
+time after which the ticket may not be renewed.
+
+2.4. Postdated tickets
+
+Applications may occasionally need to obtain tickets for use much later,
+e.g. a batch submission system would need tickets to be valid at the time
+the batch job is serviced. However, it is dangerous to hold valid tickets in
+a batch queue, since they will be on-line longer and more prone to theft.
+Postdated tickets provide a way to obtain these tickets from the KDC at job
+submission time, but to leave them "dormant" until they are activated and
+validated by a further request of the KDC. If a ticket theft were reported
+in the interim, the KDC would refuse to validate the ticket, and the thief
+would be foiled.
+
+The MAY-POSTDATE flag in a ticket is normally only interpreted by the
+ticket-granting service. It can be ignored by application servers. This flag
+must be set in a ticket-granting ticket in order to issue a postdated ticket
+based on the presented ticket. It is reset by default; it may be requested
+by a client by setting the ALLOW-POSTDATE option in the KRB_AS_REQ message.
+This flag does not allow a client to obtain a postdated ticket-granting
+ticket; postdated ticket-granting tickets can only by obtained by requesting
+the postdating in the KRB_AS_REQ message. The life (endtime-starttime) of a
+postdated ticket will be the remaining life of the ticket-granting ticket at
+the time of the request, unless the RENEWABLE option is also set, in which
+case it can be the full life (endtime-starttime) of the ticket-granting
+ticket. The KDC may limit how far in the future a ticket may be postdated.
+
+The POSTDATED flag indicates that a ticket has been postdated. The
+application server can check the authtime field in the ticket to see when
+the original authentication occurred. Some services may choose to reject
+postdated tickets, or they may only accept them within a certain period
+after the original authentication. When the KDC issues a POSTDATED ticket,
+it will also be marked as INVALID, so that the application client must
+present the ticket to the KDC to be validated before use.
+
+2.5. Proxiable and proxy tickets
+
+At times it may be necessary for a principal to allow a service to perform
+an operation on its behalf. The service must be able to take on the identity
+of the client, but only for a particular purpose. A principal can allow a
+service to take on the principal's identity for a particular purpose by
+granting it a proxy.
+
+The process of granting a proxy using the proxy and proxiable flags is used
+to provide credentials for use with specific services. Though conceptually
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+also a proxy, user's wishing to delegate their identity for ANY purpose must
+use the ticket forwarding mechanism described in the next section to forward
+a ticket granting ticket.
+
+The PROXIABLE flag in a ticket is normally only interpreted by the
+ticket-granting service. It can be ignored by application servers. When set,
+this flag tells the ticket-granting server that it is OK to issue a new
+ticket (but not a ticket-granting ticket) with a different network address
+based on this ticket. This flag is set if requested by the client on initial
+authentication. By default, the client will request that it be set when
+requesting a ticket granting ticket, and reset when requesting any other
+ticket.
+
+This flag allows a client to pass a proxy to a server to perform a remote
+request on its behalf, e.g. a print service client can give the print server
+a proxy to access the client's files on a particular file server in order to
+satisfy a print request.
+
+In order to complicate the use of stolen credentials, Kerberos tickets are
+usually valid from only those network addresses specifically included in the
+ticket[4]. When granting a proxy, the client must specify the new network
+address from which the proxy is to be used, or indicate that the proxy is to
+be issued for use from any address.
+
+The PROXY flag is set in a ticket by the TGS when it issues a proxy ticket.
+Application servers may check this flag and at their option they may require
+additional authentication from the agent presenting the proxy in order to
+provide an audit trail.
+
+2.6. Forwardable tickets
+
+Authentication forwarding is an instance of a proxy where the service is
+granted complete use of the client's identity. An example where it might be
+used is when a user logs in to a remote system and wants authentication to
+work from that system as if the login were local.
+
+The FORWARDABLE flag in a ticket is normally only interpreted by the
+ticket-granting service. It can be ignored by application servers. The
+FORWARDABLE flag has an interpretation similar to that of the PROXIABLE
+flag, except ticket-granting tickets may also be issued with different
+network addresses. This flag is reset by default, but users may request that
+it be set by setting the FORWARDABLE option in the AS request when they
+request their initial ticket- granting ticket.
+
+This flag allows for authentication forwarding without requiring the user to
+enter a password again. If the flag is not set, then authentication
+forwarding is not permitted, but the same result can still be achieved if
+the user engages in the AS exchange specifying the requested network
+addresses and supplies a password.
+
+The FORWARDED flag is set by the TGS when a client presents a ticket with
+the FORWARDABLE flag set and requests a forwarded ticket by specifying the
+FORWARDED KDC option and supplying a set of addresses for the new ticket. It
+is also set in all tickets issued based on tickets with the FORWARDED flag
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+set. Application servers may choose to process FORWARDED tickets differently
+than non-FORWARDED tickets.
+
+2.7. Other KDC options
+
+There are two additional options which may be set in a client's request of
+the KDC. The RENEWABLE-OK option indicates that the client will accept a
+renewable ticket if a ticket with the requested life cannot otherwise be
+provided. If a ticket with the requested life cannot be provided, then the
+KDC may issue a renewable ticket with a renew-till equal to the the
+requested endtime. The value of the renew-till field may still be adjusted
+by site-determined limits or limits imposed by the individual principal or
+server.
+
+The ENC-TKT-IN-SKEY option is honored only by the ticket-granting service.
+It indicates that the ticket to be issued for the end server is to be
+encrypted in the session key from the a additional second ticket-granting
+ticket provided with the request. See section 3.3.3 for specific details.
+
+3. Message Exchanges
+
+The following sections describe the interactions between network clients and
+servers and the messages involved in those exchanges.
+
+3.1. The Authentication Service Exchange
+
+ Summary
+ Message direction Message type Section
+ 1. Client to Kerberos KRB_AS_REQ 5.4.1
+ 2. Kerberos to client KRB_AS_REP or 5.4.2
+ KRB_ERROR 5.9.1
+
+The Authentication Service (AS) Exchange between the client and the Kerberos
+Authentication Server is initiated by a client when it wishes to obtain
+authentication credentials for a given server but currently holds no
+credentials. In its basic form, the client's secret key is used for
+encryption and decryption. This exchange is typically used at the initiation
+of a login session to obtain credentials for a Ticket-Granting Server which
+will subsequently be used to obtain credentials for other servers (see
+section 3.3) without requiring further use of the client's secret key. This
+exchange is also used to request credentials for services which must not be
+mediated through the Ticket-Granting Service, but rather require a
+principal's secret key, such as the password-changing service[5]. This
+exchange does not by itself provide any assurance of the the identity of the
+user[6].
+
+The exchange consists of two messages: KRB_AS_REQ from the client to
+Kerberos, and KRB_AS_REP or KRB_ERROR in reply. The formats for these
+messages are described in sections 5.4.1, 5.4.2, and 5.9.1.
+
+In the request, the client sends (in cleartext) its own identity and the
+identity of the server for which it is requesting credentials. The response,
+KRB_AS_REP, contains a ticket for the client to present to the server, and a
+session key that will be shared by the client and the server. The session
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+key and additional information are encrypted in the client's secret key. The
+KRB_AS_REP message contains information which can be used to detect replays,
+and to associate it with the message to which it replies. Various errors can
+occur; these are indicated by an error response (KRB_ERROR) instead of the
+KRB_AS_REP response. The error message is not encrypted. The KRB_ERROR
+message contains information which can be used to associate it with the
+message to which it replies. The lack of encryption in the KRB_ERROR message
+precludes the ability to detect replays, fabrications, or modifications of
+such messages.
+
+Without preautentication, the authentication server does not know whether
+the client is actually the principal named in the request. It simply sends a
+reply without knowing or caring whether they are the same. This is
+acceptable because nobody but the principal whose identity was given in the
+request will be able to use the reply. Its critical information is encrypted
+in that principal's key. The initial request supports an optional field that
+can be used to pass additional information that might be needed for the
+initial exchange. This field may be used for preauthentication as described
+in section [hl<>].
+
+3.1.1. Generation of KRB_AS_REQ message
+
+The client may specify a number of options in the initial request. Among
+these options are whether pre-authentication is to be performed; whether the
+requested ticket is to be renewable, proxiable, or forwardable; whether it
+should be postdated or allow postdating of derivative tickets; and whether a
+renewable ticket will be accepted in lieu of a non-renewable ticket if the
+requested ticket expiration date cannot be satisfied by a non-renewable
+ticket (due to configuration constraints; see section 4). See section A.1
+for pseudocode.
+
+The client prepares the KRB_AS_REQ message and sends it to the KDC.
+
+3.1.2. Receipt of KRB_AS_REQ message
+
+If all goes well, processing the KRB_AS_REQ message will result in the
+creation of a ticket for the client to present to the server. The format for
+the ticket is described in section 5.3.1. The contents of the ticket are
+determined as follows.
+
+3.1.3. Generation of KRB_AS_REP message
+
+The authentication server looks up the client and server principals named in
+the KRB_AS_REQ in its database, extracting their respective keys. If
+required, the server pre-authenticates the request, and if the
+pre-authentication check fails, an error message with the code
+KDC_ERR_PREAUTH_FAILED is returned. If the server cannot accommodate the
+requested encryption type, an error message with code KDC_ERR_ETYPE_NOSUPP
+is returned. Otherwise it generates a 'random' session key[7].
+
+If there are multiple encryption keys registered for a client in the
+Kerberos database (or if the key registered supports multiple encryption
+types; e.g. DES-CBC-CRC and DES-CBC-MD5), then the etype field from the AS
+request is used by the KDC to select the encryption method to be used for
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+encrypting the response to the client. If there is more than one supported,
+strong encryption type in the etype list, the first valid etype for which an
+encryption key is available is used. The encryption method used to respond
+to a TGS request is taken from the keytype of the session key found in the
+ticket granting ticket.
+
+When the etype field is present in a KDC request, whether an AS or TGS
+request, the KDC will attempt to assign the type of the random session key
+from the list of methods in the etype field. The KDC will select the
+appropriate type using the list of methods provided together with
+information from the Kerberos database indicating acceptable encryption
+methods for the application server. The KDC will not issue tickets with a
+weak session key encryption type.
+
+If the requested start time is absent, indicates a time in the past, or is
+within the window of acceptable clock skew for the KDC and the POSTDATE
+option has not been specified, then the start time of the ticket is set to
+the authentication server's current time. If it indicates a time in the
+future beyond the acceptable clock skew, but the POSTDATED option has not
+been specified then the error KDC_ERR_CANNOT_POSTDATE is returned. Otherwise
+the requested start time is checked against the policy of the local realm
+(the administrator might decide to prohibit certain types or ranges of
+postdated tickets), and if acceptable, the ticket's start time is set as
+requested and the INVALID flag is set in the new ticket. The postdated
+ticket must be validated before use by presenting it to the KDC after the
+start time has been reached.
+
+The expiration time of the ticket will be set to the minimum of the
+following:
+
+ * The expiration time (endtime) requested in the KRB_AS_REQ message.
+ * The ticket's start time plus the maximum allowable lifetime associated
+ with the client principal (the authentication server's database
+ includes a maximum ticket lifetime field in each principal's record;
+ see section 4).
+ * The ticket's start time plus the maximum allowable lifetime associated
+ with the server principal.
+ * The ticket's start time plus the maximum lifetime set by the policy of
+ the local realm.
+
+If the requested expiration time minus the start time (as determined above)
+is less than a site-determined minimum lifetime, an error message with code
+KDC_ERR_NEVER_VALID is returned. If the requested expiration time for the
+ticket exceeds what was determined as above, and if the 'RENEWABLE-OK'
+option was requested, then the 'RENEWABLE' flag is set in the new ticket,
+and the renew-till value is set as if the 'RENEWABLE' option were requested
+(the field and option names are described fully in section 5.4.1).
+
+If the RENEWABLE option has been requested or if the RENEWABLE-OK option has
+been set and a renewable ticket is to be issued, then the renew-till field
+is set to the minimum of:
+
+ * Its requested value.
+ * The start time of the ticket plus the minimum of the two maximum
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ renewable lifetimes associated with the principals' database entries.
+ * The start time of the ticket plus the maximum renewable lifetime set by
+ the policy of the local realm.
+
+The flags field of the new ticket will have the following options set if
+they have been requested and if the policy of the local realm allows:
+FORWARDABLE, MAY-POSTDATE, POSTDATED, PROXIABLE, RENEWABLE. If the new
+ticket is post-dated (the start time is in the future), its INVALID flag
+will also be set.
+
+If all of the above succeed, the server formats a KRB_AS_REP message (see
+section 5.4.2), copying the addresses in the request into the caddr of the
+response, placing any required pre-authentication data into the padata of
+the response, and encrypts the ciphertext part in the client's key using the
+requested encryption method, and sends it to the client. See section A.2 for
+pseudocode.
+
+3.1.4. Generation of KRB_ERROR message
+
+Several errors can occur, and the Authentication Server responds by
+returning an error message, KRB_ERROR, to the client, with the error-code
+and e-text fields set to appropriate values. The error message contents and
+details are described in Section 5.9.1.
+
+3.1.5. Receipt of KRB_AS_REP message
+
+If the reply message type is KRB_AS_REP, then the client verifies that the
+cname and crealm fields in the cleartext portion of the reply match what it
+requested. If any padata fields are present, they may be used to derive the
+proper secret key to decrypt the message. The client decrypts the encrypted
+part of the response using its secret key, verifies that the nonce in the
+encrypted part matches the nonce it supplied in its request (to detect
+replays). It also verifies that the sname and srealm in the response match
+those in the request (or are otherwise expected values), and that the host
+address field is also correct. It then stores the ticket, session key, start
+and expiration times, and other information for later use. The
+key-expiration field from the encrypted part of the response may be checked
+to notify the user of impending key expiration (the client program could
+then suggest remedial action, such as a password change). See section A.3
+for pseudocode.
+
+Proper decryption of the KRB_AS_REP message is not sufficient to verify the
+identity of the user; the user and an attacker could cooperate to generate a
+KRB_AS_REP format message which decrypts properly but is not from the proper
+KDC. If the host wishes to verify the identity of the user, it must require
+the user to present application credentials which can be verified using a
+securely-stored secret key for the host. If those credentials can be
+verified, then the identity of the user can be assured.
+
+3.1.6. Receipt of KRB_ERROR message
+
+If the reply message type is KRB_ERROR, then the client interprets it as an
+error and performs whatever application-specific tasks are necessary to
+recover.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+3.2. The Client/Server Authentication Exchange
+
+ Summary
+Message direction Message type Section
+Client to Application server KRB_AP_REQ 5.5.1
+[optional] Application server to client KRB_AP_REP or 5.5.2
+ KRB_ERROR 5.9.1
+
+The client/server authentication (CS) exchange is used by network
+applications to authenticate the client to the server and vice versa. The
+client must have already acquired credentials for the server using the AS or
+TGS exchange.
+
+3.2.1. The KRB_AP_REQ message
+
+The KRB_AP_REQ contains authentication information which should be part of
+the first message in an authenticated transaction. It contains a ticket, an
+authenticator, and some additional bookkeeping information (see section
+5.5.1 for the exact format). The ticket by itself is insufficient to
+authenticate a client, since tickets are passed across the network in
+cleartext[DS90], so the authenticator is used to prevent invalid replay of
+tickets by proving to the server that the client knows the session key of
+the ticket and thus is entitled to use the ticket. The KRB_AP_REQ message is
+referred to elsewhere as the 'authentication header.'
+
+3.2.2. Generation of a KRB_AP_REQ message
+
+When a client wishes to initiate authentication to a server, it obtains
+(either through a credentials cache, the AS exchange, or the TGS exchange) a
+ticket and session key for the desired service. The client may re-use any
+tickets it holds until they expire. To use a ticket the client constructs a
+new Authenticator from the the system time, its name, and optionally an
+application specific checksum, an initial sequence number to be used in
+KRB_SAFE or KRB_PRIV messages, and/or a session subkey to be used in
+negotiations for a session key unique to this particular session.
+Authenticators may not be re-used and will be rejected if replayed to a
+server[LGDSR87]. If a sequence number is to be included, it should be
+randomly chosen so that even after many messages have been exchanged it is
+not likely to collide with other sequence numbers in use.
+
+The client may indicate a requirement of mutual authentication or the use of
+a session-key based ticket by setting the appropriate flag(s) in the
+ap-options field of the message.
+
+The Authenticator is encrypted in the session key and combined with the
+ticket to form the KRB_AP_REQ message which is then sent to the end server
+along with any additional application-specific information. See section A.9
+for pseudocode.
+
+3.2.3. Receipt of KRB_AP_REQ message
+
+Authentication is based on the server's current time of day (clocks must be
+loosely synchronized), the authenticator, and the ticket. Several errors are
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+possible. If an error occurs, the server is expected to reply to the client
+with a KRB_ERROR message. This message may be encapsulated in the
+application protocol if its 'raw' form is not acceptable to the protocol.
+The format of error messages is described in section 5.9.1.
+
+The algorithm for verifying authentication information is as follows. If the
+message type is not KRB_AP_REQ, the server returns the KRB_AP_ERR_MSG_TYPE
+error. If the key version indicated by the Ticket in the KRB_AP_REQ is not
+one the server can use (e.g., it indicates an old key, and the server no
+longer possesses a copy of the old key), the KRB_AP_ERR_BADKEYVER error is
+returned. If the USE-SESSION-KEY flag is set in the ap-options field, it
+indicates to the server that the ticket is encrypted in the session key from
+the server's ticket-granting ticket rather than its secret key[10]. Since it
+is possible for the server to be registered in multiple realms, with
+different keys in each, the srealm field in the unencrypted portion of the
+ticket in the KRB_AP_REQ is used to specify which secret key the server
+should use to decrypt that ticket. The KRB_AP_ERR_NOKEY error code is
+returned if the server doesn't have the proper key to decipher the ticket.
+
+The ticket is decrypted using the version of the server's key specified by
+the ticket. If the decryption routines detect a modification of the ticket
+(each encryption system must provide safeguards to detect modified
+ciphertext; see section 6), the KRB_AP_ERR_BAD_INTEGRITY error is returned
+(chances are good that different keys were used to encrypt and decrypt).
+
+The authenticator is decrypted using the session key extracted from the
+decrypted ticket. If decryption shows it to have been modified, the
+KRB_AP_ERR_BAD_INTEGRITY error is returned. The name and realm of the client
+from the ticket are compared against the same fields in the authenticator.
+If they don't match, the KRB_AP_ERR_BADMATCH error is returned (they might
+not match, for example, if the wrong session key was used to encrypt the
+authenticator). The addresses in the ticket (if any) are then searched for
+an address matching the operating-system reported address of the client. If
+no match is found or the server insists on ticket addresses but none are
+present in the ticket, the KRB_AP_ERR_BADADDR error is returned.
+
+If the local (server) time and the client time in the authenticator differ
+by more than the allowable clock skew (e.g., 5 minutes), the KRB_AP_ERR_SKEW
+error is returned. If the server name, along with the client name, time and
+microsecond fields from the Authenticator match any recently-seen such
+tuples, the KRB_AP_ERR_REPEAT error is returned[11]. The server must
+remember any authenticator presented within the allowable clock skew, so
+that a replay attempt is guaranteed to fail. If a server loses track of any
+authenticator presented within the allowable clock skew, it must reject all
+requests until the clock skew interval has passed. This assures that any
+lost or re-played authenticators will fall outside the allowable clock skew
+and can no longer be successfully replayed (If this is not done, an attacker
+could conceivably record the ticket and authenticator sent over the network
+to a server, then disable the client's host, pose as the disabled host, and
+replay the ticket and authenticator to subvert the authentication.). If a
+sequence number is provided in the authenticator, the server saves it for
+later use in processing KRB_SAFE and/or KRB_PRIV messages. If a subkey is
+present, the server either saves it for later use or uses it to help
+generate its own choice for a subkey to be returned in a KRB_AP_REP message.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+The server computes the age of the ticket: local (server) time minus the
+start time inside the Ticket. If the start time is later than the current
+time by more than the allowable clock skew or if the INVALID flag is set in
+the ticket, the KRB_AP_ERR_TKT_NYV error is returned. Otherwise, if the
+current time is later than end time by more than the allowable clock skew,
+the KRB_AP_ERR_TKT_EXPIRED error is returned.
+
+If all these checks succeed without an error, the server is assured that the
+client possesses the credentials of the principal named in the ticket and
+thus, the client has been authenticated to the server. See section A.10 for
+pseudocode.
+
+Passing these checks provides only authentication of the named principal; it
+does not imply authorization to use the named service. Applications must
+make a separate authorization decisions based upon the authenticated name of
+the user, the requested operation, local acces control information such as
+that contained in a .k5login or .k5users file, and possibly a separate
+distributed authorization service.
+
+3.2.4. Generation of a KRB_AP_REP message
+
+Typically, a client's request will include both the authentication
+information and its initial request in the same message, and the server need
+not explicitly reply to the KRB_AP_REQ. However, if mutual authentication
+(not only authenticating the client to the server, but also the server to
+the client) is being performed, the KRB_AP_REQ message will have
+MUTUAL-REQUIRED set in its ap-options field, and a KRB_AP_REP message is
+required in response. As with the error message, this message may be
+encapsulated in the application protocol if its "raw" form is not acceptable
+to the application's protocol. The timestamp and microsecond field used in
+the reply must be the client's timestamp and microsecond field (as provided
+in the authenticator)[12]. If a sequence number is to be included, it should
+be randomly chosen as described above for the authenticator. A subkey may be
+included if the server desires to negotiate a different subkey. The
+KRB_AP_REP message is encrypted in the session key extracted from the
+ticket. See section A.11 for pseudocode.
+
+3.2.5. Receipt of KRB_AP_REP message
+
+If a KRB_AP_REP message is returned, the client uses the session key from
+the credentials obtained for the server[13] to decrypt the message, and
+verifies that the timestamp and microsecond fields match those in the
+Authenticator it sent to the server. If they match, then the client is
+assured that the server is genuine. The sequence number and subkey (if
+present) are retained for later use. See section A.12 for pseudocode.
+
+3.2.6. Using the encryption key
+
+After the KRB_AP_REQ/KRB_AP_REP exchange has occurred, the client and server
+share an encryption key which can be used by the application. The 'true
+session key' to be used for KRB_PRIV, KRB_SAFE, or other
+application-specific uses may be chosen by the application based on the
+subkeys in the KRB_AP_REP message and the authenticator[14]. In some cases,
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+the use of this session key will be implicit in the protocol; in others the
+method of use must be chosen from several alternatives. We leave the
+protocol negotiations of how to use the key (e.g. selecting an encryption or
+checksum type) to the application programmer; the Kerberos protocol does not
+constrain the implementation options, but an example of how this might be
+done follows.
+
+One way that an application may choose to negotiate a key to be used for
+subequent integrity and privacy protection is for the client to propose a
+key in the subkey field of the authenticator. The server can then choose a
+key using the proposed key from the client as input, returning the new
+subkey in the subkey field of the application reply. This key could then be
+used for subsequent communication. To make this example more concrete, if
+the encryption method in use required a 56 bit key, and for whatever reason,
+one of the parties was prevented from using a key with more than 40 unknown
+bits, this method would allow the the party which is prevented from using
+more than 40 bits to either propose (if the client) an initial key with a
+known quantity for 16 of those bits, or to mask 16 of the bits (if the
+server) with the known quantity. The application implementor is warned,
+however, that this is only an example, and that an analysis of the
+particular crytosystem to be used, and the reasons for limiting the key
+length, must be made before deciding whether it is acceptable to mask bits
+of the key.
+
+With both the one-way and mutual authentication exchanges, the peers should
+take care not to send sensitive information to each other without proper
+assurances. In particular, applications that require privacy or integrity
+should use the KRB_AP_REP response from the server to client to assure both
+client and server of their peer's identity. If an application protocol
+requires privacy of its messages, it can use the KRB_PRIV message (section
+3.5). The KRB_SAFE message (section 3.4) can be used to assure integrity.
+
+3.3. The Ticket-Granting Service (TGS) Exchange
+
+ Summary
+ Message direction Message type Section
+ 1. Client to Kerberos KRB_TGS_REQ 5.4.1
+ 2. Kerberos to client KRB_TGS_REP or 5.4.2
+ KRB_ERROR 5.9.1
+
+The TGS exchange between a client and the Kerberos Ticket-Granting Server is
+initiated by a client when it wishes to obtain authentication credentials
+for a given server (which might be registered in a remote realm), when it
+wishes to renew or validate an existing ticket, or when it wishes to obtain
+a proxy ticket. In the first case, the client must already have acquired a
+ticket for the Ticket-Granting Service using the AS exchange (the
+ticket-granting ticket is usually obtained when a client initially
+authenticates to the system, such as when a user logs in). The message
+format for the TGS exchange is almost identical to that for the AS exchange.
+The primary difference is that encryption and decryption in the TGS exchange
+does not take place under the client's key. Instead, the session key from
+the ticket-granting ticket or renewable ticket, or sub-session key from an
+Authenticator is used. As is the case for all application servers, expired
+tickets are not accepted by the TGS, so once a renewable or ticket-granting
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ticket expires, the client must use a separate exchange to obtain valid
+tickets.
+
+The TGS exchange consists of two messages: A request (KRB_TGS_REQ) from the
+client to the Kerberos Ticket-Granting Server, and a reply (KRB_TGS_REP or
+KRB_ERROR). The KRB_TGS_REQ message includes information authenticating the
+client plus a request for credentials. The authentication information
+consists of the authentication header (KRB_AP_REQ) which includes the
+client's previously obtained ticket-granting, renewable, or invalid ticket.
+In the ticket-granting ticket and proxy cases, the request may include one
+or more of: a list of network addresses, a collection of typed authorization
+data to be sealed in the ticket for authorization use by the application
+server, or additional tickets (the use of which are described later). The
+TGS reply (KRB_TGS_REP) contains the requested credentials, encrypted in the
+session key from the ticket-granting ticket or renewable ticket, or if
+present, in the sub-session key from the Authenticator (part of the
+authentication header). The KRB_ERROR message contains an error code and
+text explaining what went wrong. The KRB_ERROR message is not encrypted. The
+KRB_TGS_REP message contains information which can be used to detect
+replays, and to associate it with the message to which it replies. The
+KRB_ERROR message also contains information which can be used to associate
+it with the message to which it replies, but the lack of encryption in the
+KRB_ERROR message precludes the ability to detect replays or fabrications of
+such messages.
+
+3.3.1. Generation of KRB_TGS_REQ message
+
+Before sending a request to the ticket-granting service, the client must
+determine in which realm the application server is registered[15]. If the
+client does not already possess a ticket-granting ticket for the appropriate
+realm, then one must be obtained. This is first attempted by requesting a
+ticket-granting ticket for the destination realm from a Kerberos server for
+which the client does posess a ticket-granting ticket (using the KRB_TGS_REQ
+message recursively). The Kerberos server may return a TGT for the desired
+realm in which case one can proceed. Alternatively, the Kerberos server may
+return a TGT for a realm which is 'closer' to the desired realm (further
+along the standard hierarchical path), in which case this step must be
+repeated with a Kerberos server in the realm specified in the returned TGT.
+If neither are returned, then the request must be retried with a Kerberos
+server for a realm higher in the hierarchy. This request will itself require
+a ticket-granting ticket for the higher realm which must be obtained by
+recursively applying these directions.
+
+Once the client obtains a ticket-granting ticket for the appropriate realm,
+it determines which Kerberos servers serve that realm, and contacts one. The
+list might be obtained through a configuration file or network service or it
+may be generated from the name of the realm; as long as the secret keys
+exchanged by realms are kept secret, only denial of service results from
+using a false Kerberos server.
+
+As in the AS exchange, the client may specify a number of options in the
+KRB_TGS_REQ message. The client prepares the KRB_TGS_REQ message, providing
+an authentication header as an element of the padata field, and including
+the same fields as used in the KRB_AS_REQ message along with several
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+optional fields: the enc-authorization-data field for application server use
+and additional tickets required by some options.
+
+In preparing the authentication header, the client can select a sub-session
+key under which the response from the Kerberos server will be encrypted[16].
+If the sub-session key is not specified, the session key from the
+ticket-granting ticket will be used. If the enc-authorization-data is
+present, it must be encrypted in the sub-session key, if present, from the
+authenticator portion of the authentication header, or if not present, using
+the session key from the ticket-granting ticket.
+
+Once prepared, the message is sent to a Kerberos server for the destination
+realm. See section A.5 for pseudocode.
+
+3.3.2. Receipt of KRB_TGS_REQ message
+
+The KRB_TGS_REQ message is processed in a manner similar to the KRB_AS_REQ
+message, but there are many additional checks to be performed. First, the
+Kerberos server must determine which server the accompanying ticket is for
+and it must select the appropriate key to decrypt it. For a normal
+KRB_TGS_REQ message, it will be for the ticket granting service, and the
+TGS's key will be used. If the TGT was issued by another realm, then the
+appropriate inter-realm key must be used. If the accompanying ticket is not
+a ticket granting ticket for the current realm, but is for an application
+server in the current realm, the RENEW, VALIDATE, or PROXY options are
+specified in the request, and the server for which a ticket is requested is
+the server named in the accompanying ticket, then the KDC will decrypt the
+ticket in the authentication header using the key of the server for which it
+was issued. If no ticket can be found in the padata field, the
+KDC_ERR_PADATA_TYPE_NOSUPP error is returned.
+
+Once the accompanying ticket has been decrypted, the user-supplied checksum
+in the Authenticator must be verified against the contents of the request,
+and the message rejected if the checksums do not match (with an error code
+of KRB_AP_ERR_MODIFIED) or if the checksum is not keyed or not
+collision-proof (with an error code of KRB_AP_ERR_INAPP_CKSUM). If the
+checksum type is not supported, the KDC_ERR_SUMTYPE_NOSUPP error is
+returned. If the authorization-data are present, they are decrypted using
+the sub-session key from the Authenticator.
+
+If any of the decryptions indicate failed integrity checks, the
+KRB_AP_ERR_BAD_INTEGRITY error is returned.
+
+3.3.3. Generation of KRB_TGS_REP message
+
+The KRB_TGS_REP message shares its format with the KRB_AS_REP (KRB_KDC_REP),
+but with its type field set to KRB_TGS_REP. The detailed specification is in
+section 5.4.2.
+
+The response will include a ticket for the requested server. The Kerberos
+database is queried to retrieve the record for the requested server
+(including the key with which the ticket will be encrypted). If the request
+is for a ticket granting ticket for a remote realm, and if no key is shared
+with the requested realm, then the Kerberos server will select the realm
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+"closest" to the requested realm with which it does share a key, and use
+that realm instead. This is the only case where the response from the KDC
+will be for a different server than that requested by the client.
+
+By default, the address field, the client's name and realm, the list of
+transited realms, the time of initial authentication, the expiration time,
+and the authorization data of the newly-issued ticket will be copied from
+the ticket-granting ticket (TGT) or renewable ticket. If the transited field
+needs to be updated, but the transited type is not supported, the
+KDC_ERR_TRTYPE_NOSUPP error is returned.
+
+If the request specifies an endtime, then the endtime of the new ticket is
+set to the minimum of (a) that request, (b) the endtime from the TGT, and
+(c) the starttime of the TGT plus the minimum of the maximum life for the
+application server and the maximum life for the local realm (the maximum
+life for the requesting principal was already applied when the TGT was
+issued). If the new ticket is to be a renewal, then the endtime above is
+replaced by the minimum of (a) the value of the renew_till field of the
+ticket and (b) the starttime for the new ticket plus the life
+(endtime-starttime) of the old ticket.
+
+If the FORWARDED option has been requested, then the resulting ticket will
+contain the addresses specified by the client. This option will only be
+honored if the FORWARDABLE flag is set in the TGT. The PROXY option is
+similar; the resulting ticket will contain the addresses specified by the
+client. It will be honored only if the PROXIABLE flag in the TGT is set. The
+PROXY option will not be honored on requests for additional ticket-granting
+tickets.
+
+If the requested start time is absent, indicates a time in the past, or is
+within the window of acceptable clock skew for the KDC and the POSTDATE
+option has not been specified, then the start time of the ticket is set to
+the authentication server's current time. If it indicates a time in the
+future beyond the acceptable clock skew, but the POSTDATED option has not
+been specified or the MAY-POSTDATE flag is not set in the TGT, then the
+error KDC_ERR_CANNOT_POSTDATE is returned. Otherwise, if the ticket-granting
+ticket has the MAY-POSTDATE flag set, then the resulting ticket will be
+postdated and the requested starttime is checked against the policy of the
+local realm. If acceptable, the ticket's start time is set as requested, and
+the INVALID flag is set. The postdated ticket must be validated before use
+by presenting it to the KDC after the starttime has been reached. However,
+in no case may the starttime, endtime, or renew-till time of a newly-issued
+postdated ticket extend beyond the renew-till time of the ticket-granting
+ticket.
+
+If the ENC-TKT-IN-SKEY option has been specified and an additional ticket
+has been included in the request, the KDC will decrypt the additional ticket
+using the key for the server to which the additional ticket was issued and
+verify that it is a ticket-granting ticket. If the name of the requested
+server is missing from the request, the name of the client in the additional
+ticket will be used. Otherwise the name of the requested server will be
+compared to the name of the client in the additional ticket and if
+different, the request will be rejected. If the request succeeds, the
+session key from the additional ticket will be used to encrypt the new
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ticket that is issued instead of using the key of the server for which the
+new ticket will be used[17].
+
+If the name of the server in the ticket that is presented to the KDC as part
+of the authentication header is not that of the ticket-granting server
+itself, the server is registered in the realm of the KDC, and the RENEW
+option is requested, then the KDC will verify that the RENEWABLE flag is set
+in the ticket, that the INVALID flag is not set in the ticket, and that the
+renew_till time is still in the future. If the VALIDATE option is rqeuested,
+the KDC will check that the starttime has passed and the INVALID flag is
+set. If the PROXY option is requested, then the KDC will check that the
+PROXIABLE flag is set in the ticket. If the tests succeed, and the ticket
+passes the hotlist check described in the next paragraph, the KDC will issue
+the appropriate new ticket.
+
+3.3.3.1. Checking for revoked tickets
+
+Whenever a request is made to the ticket-granting server, the presented
+ticket(s) is(are) checked against a hot-list of tickets which have been
+canceled. This hot-list might be implemented by storing a range of issue
+timestamps for 'suspect tickets'; if a presented ticket had an authtime in
+that range, it would be rejected. In this way, a stolen ticket-granting
+ticket or renewable ticket cannot be used to gain additional tickets
+(renewals or otherwise) once the theft has been reported. Any normal ticket
+obtained before it was reported stolen will still be valid (because they
+require no interaction with the KDC), but only until their normal expiration
+time.
+
+The ciphertext part of the response in the KRB_TGS_REP message is encrypted
+in the sub-session key from the Authenticator, if present, or the session
+key key from the ticket-granting ticket. It is not encrypted using the
+client's secret key. Furthermore, the client's key's expiration date and the
+key version number fields are left out since these values are stored along
+with the client's database record, and that record is not needed to satisfy
+a request based on a ticket-granting ticket. See section A.6 for pseudocode.
+
+3.3.3.2. Encoding the transited field
+
+If the identity of the server in the TGT that is presented to the KDC as
+part of the authentication header is that of the ticket-granting service,
+but the TGT was issued from another realm, the KDC will look up the
+inter-realm key shared with that realm and use that key to decrypt the
+ticket. If the ticket is valid, then the KDC will honor the request, subject
+to the constraints outlined above in the section describing the AS exchange.
+The realm part of the client's identity will be taken from the
+ticket-granting ticket. The name of the realm that issued the
+ticket-granting ticket will be added to the transited field of the ticket to
+be issued. This is accomplished by reading the transited field from the
+ticket-granting ticket (which is treated as an unordered set of realm
+names), adding the new realm to the set, then constructing and writing out
+its encoded (shorthand) form (this may involve a rearrangement of the
+existing encoding).
+
+Note that the ticket-granting service does not add the name of its own
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+realm. Instead, its responsibility is to add the name of the previous realm.
+This prevents a malicious Kerberos server from intentionally leaving out its
+own name (it could, however, omit other realms' names).
+
+The names of neither the local realm nor the principal's realm are to be
+included in the transited field. They appear elsewhere in the ticket and
+both are known to have taken part in authenticating the principal. Since the
+endpoints are not included, both local and single-hop inter-realm
+authentication result in a transited field that is empty.
+
+Because the name of each realm transited is added to this field, it might
+potentially be very long. To decrease the length of this field, its contents
+are encoded. The initially supported encoding is optimized for the normal
+case of inter-realm communication: a hierarchical arrangement of realms
+using either domain or X.500 style realm names. This encoding (called
+DOMAIN-X500-COMPRESS) is now described.
+
+Realm names in the transited field are separated by a ",". The ",", "\",
+trailing "."s, and leading spaces (" ") are special characters, and if they
+are part of a realm name, they must be quoted in the transited field by
+preced- ing them with a "\".
+
+A realm name ending with a "." is interpreted as being prepended to the
+previous realm. For example, we can encode traversal of EDU, MIT.EDU,
+ATHENA.MIT.EDU, WASHINGTON.EDU, and CS.WASHINGTON.EDU as:
+
+ "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS.".
+
+Note that if ATHENA.MIT.EDU, or CS.WASHINGTON.EDU were end-points, that they
+would not be included in this field, and we would have:
+
+ "EDU,MIT.,WASHINGTON.EDU"
+
+A realm name beginning with a "/" is interpreted as being appended to the
+previous realm[18]. If it is to stand by itself, then it should be preceded
+by a space (" "). For example, we can encode traversal of /COM/HP/APOLLO,
+/COM/HP, /COM, and /COM/DEC as:
+
+ "/COM,/HP,/APOLLO, /COM/DEC".
+
+Like the example above, if /COM/HP/APOLLO and /COM/DEC are endpoints, they
+they would not be included in this field, and we would have:
+
+ "/COM,/HP"
+
+A null subfield preceding or following a "," indicates that all realms
+between the previous realm and the next realm have been traversed[19]. Thus,
+"," means that all realms along the path between the client and the server
+have been traversed. ",EDU, /COM," means that that all realms from the
+client's realm up to EDU (in a domain style hierarchy) have been traversed,
+and that everything from /COM down to the server's realm in an X.500 style
+has also been traversed. This could occur if the EDU realm in one hierarchy
+shares an inter-realm key directly with the /COM realm in another hierarchy.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+3.3.4. Receipt of KRB_TGS_REP message
+
+When the KRB_TGS_REP is received by the client, it is processed in the same
+manner as the KRB_AS_REP processing described above. The primary difference
+is that the ciphertext part of the response must be decrypted using the
+session key from the ticket-granting ticket rather than the client's secret
+key. See section A.7 for pseudocode.
+
+3.4. The KRB_SAFE Exchange
+
+The KRB_SAFE message may be used by clients requiring the ability to detect
+modifications of messages they exchange. It achieves this by including a
+keyed collision-proof checksum of the user data and some control
+information. The checksum is keyed with an encryption key (usually the last
+key negotiated via subkeys, or the session key if no negotiation has
+occured).
+
+3.4.1. Generation of a KRB_SAFE message
+
+When an application wishes to send a KRB_SAFE message, it collects its data
+and the appropriate control information and computes a checksum over them.
+The checksum algorithm should be a keyed one-way hash function (such as the
+RSA- MD5-DES checksum algorithm specified in section 6.4.5, or the DES MAC),
+generated using the sub-session key if present, or the session key.
+Different algorithms may be selected by changing the checksum type in the
+message. Unkeyed or non-collision-proof checksums are not suitable for this
+use.
+
+The control information for the KRB_SAFE message includes both a timestamp
+and a sequence number. The designer of an application using the KRB_SAFE
+message must choose at least one of the two mechanisms. This choice should
+be based on the needs of the application protocol.
+
+Sequence numbers are useful when all messages sent will be received by one's
+peer. Connection state is presently required to maintain the session key, so
+maintaining the next sequence number should not present an additional
+problem.
+
+If the application protocol is expected to tolerate lost messages without
+them being resent, the use of the timestamp is the appropriate replay
+detection mechanism. Using timestamps is also the appropriate mechanism for
+multi-cast protocols where all of one's peers share a common sub-session
+key, but some messages will be sent to a subset of one's peers.
+
+After computing the checksum, the client then transmits the information and
+checksum to the recipient in the message format specified in section 5.6.1.
+
+3.4.2. Receipt of KRB_SAFE message
+
+When an application receives a KRB_SAFE message, it verifies it as follows.
+If any error occurs, an error code is reported for use by the application.
+
+The message is first checked by verifying that the protocol version and type
+fields match the current version and KRB_SAFE, respectively. A mismatch
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+generates a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error. The
+application verifies that the checksum used is a collision-proof keyed
+checksum, and if it is not, a KRB_AP_ERR_INAPP_CKSUM error is generated. The
+recipient verifies that the operating system's report of the sender's
+address matches the sender's address in the message, and (if a recipient
+address is specified or the recipient requires an address) that one of the
+recipient's addresses appears as the recipient's address in the message. A
+failed match for either case generates a KRB_AP_ERR_BADADDR error. Then the
+timestamp and usec and/or the sequence number fields are checked. If
+timestamp and usec are expected and not present, or they are present but not
+current, the KRB_AP_ERR_SKEW error is generated. If the server name, along
+with the client name, time and microsecond fields from the Authenticator
+match any recently-seen (sent or received[20] ) such tuples, the
+KRB_AP_ERR_REPEAT error is generated. If an incorrect sequence number is
+included, or a sequence number is expected but not present, the
+KRB_AP_ERR_BADORDER error is generated. If neither a time-stamp and usec or
+a sequence number is present, a KRB_AP_ERR_MODIFIED error is generated.
+Finally, the checksum is computed over the data and control information, and
+if it doesn't match the received checksum, a KRB_AP_ERR_MODIFIED error is
+generated.
+
+If all the checks succeed, the application is assured that the message was
+generated by its peer and was not modi- fied in transit.
+
+3.5. The KRB_PRIV Exchange
+
+The KRB_PRIV message may be used by clients requiring confidentiality and
+the ability to detect modifications of exchanged messages. It achieves this
+by encrypting the messages and adding control information.
+
+3.5.1. Generation of a KRB_PRIV message
+
+When an application wishes to send a KRB_PRIV message, it collects its data
+and the appropriate control information (specified in section 5.7.1) and
+encrypts them under an encryption key (usually the last key negotiated via
+subkeys, or the session key if no negotiation has occured). As part of the
+control information, the client must choose to use either a timestamp or a
+sequence number (or both); see the discussion in section 3.4.1 for
+guidelines on which to use. After the user data and control information are
+encrypted, the client transmits the ciphertext and some 'envelope'
+information to the recipient.
+
+3.5.2. Receipt of KRB_PRIV message
+
+When an application receives a KRB_PRIV message, it verifies it as follows.
+If any error occurs, an error code is reported for use by the application.
+
+The message is first checked by verifying that the protocol version and type
+fields match the current version and KRB_PRIV, respectively. A mismatch
+generates a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error. The
+application then decrypts the ciphertext and processes the resultant
+plaintext. If decryption shows the data to have been modified, a
+KRB_AP_ERR_BAD_INTEGRITY error is generated. The recipient verifies that the
+operating system's report of the sender's address matches the sender's
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+address in the message, and (if a recipient address is specified or the
+recipient requires an address) that one of the recipient's addresses appears
+as the recipient's address in the message. A failed match for either case
+generates a KRB_AP_ERR_BADADDR error. Then the timestamp and usec and/or the
+sequence number fields are checked. If timestamp and usec are expected and
+not present, or they are present but not current, the KRB_AP_ERR_SKEW error
+is generated. If the server name, along with the client name, time and
+microsecond fields from the Authenticator match any recently-seen such
+tuples, the KRB_AP_ERR_REPEAT error is generated. If an incorrect sequence
+number is included, or a sequence number is expected but not present, the
+KRB_AP_ERR_BADORDER error is generated. If neither a time-stamp and usec or
+a sequence number is present, a KRB_AP_ERR_MODIFIED error is generated.
+
+If all the checks succeed, the application can assume the message was
+generated by its peer, and was securely transmitted (without intruders able
+to see the unencrypted contents).
+
+3.6. The KRB_CRED Exchange
+
+The KRB_CRED message may be used by clients requiring the ability to send
+Kerberos credentials from one host to another. It achieves this by sending
+the tickets together with encrypted data containing the session keys and
+other information associated with the tickets.
+
+3.6.1. Generation of a KRB_CRED message
+
+When an application wishes to send a KRB_CRED message it first (using the
+KRB_TGS exchange) obtains credentials to be sent to the remote host. It then
+constructs a KRB_CRED message using the ticket or tickets so obtained,
+placing the session key needed to use each ticket in the key field of the
+corresponding KrbCredInfo sequence of the encrypted part of the the KRB_CRED
+message.
+
+Other information associated with each ticket and obtained during the
+KRB_TGS exchange is also placed in the corresponding KrbCredInfo sequence in
+the encrypted part of the KRB_CRED message. The current time and, if
+specifically required by the application the nonce, s-address, and r-address
+fields, are placed in the encrypted part of the KRB_CRED message which is
+then encrypted under an encryption key previosuly exchanged in the KRB_AP
+exchange (usually the last key negotiated via subkeys, or the session key if
+no negotiation has occured).
+
+3.6.2. Receipt of KRB_CRED message
+
+When an application receives a KRB_CRED message, it verifies it. If any
+error occurs, an error code is reported for use by the application. The
+message is verified by checking that the protocol version and type fields
+match the current version and KRB_CRED, respectively. A mismatch generates a
+KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error. The application then
+decrypts the ciphertext and processes the resultant plaintext. If decryption
+shows the data to have been modified, a KRB_AP_ERR_BAD_INTEGRITY error is
+generated.
+
+If present or required, the recipient verifies that the operating system's
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+report of the sender's address matches the sender's address in the message,
+and that one of the recipient's addresses appears as the recipient's address
+in the message. A failed match for either case generates a
+KRB_AP_ERR_BADADDR error. The timestamp and usec fields (and the nonce field
+if required) are checked next. If the timestamp and usec are not present, or
+they are present but not current, the KRB_AP_ERR_SKEW error is generated.
+
+If all the checks succeed, the application stores each of the new tickets in
+its ticket cache together with the session key and other information in the
+corresponding KrbCredInfo sequence from the encrypted part of the KRB_CRED
+message.
+
+4. The Kerberos Database
+
+The Kerberos server must have access to a database contain- ing the
+principal identifiers and secret keys of principals to be authenticated[21].
+
+4.1. Database contents
+
+A database entry should contain at least the following fields:
+
+Field Value
+
+name Principal's identifier
+key Principal's secret key
+p_kvno Principal's key version
+max_life Maximum lifetime for Tickets
+max_renewable_life Maximum total lifetime for renewable Tickets
+
+The name field is an encoding of the principal's identifier. The key field
+contains an encryption key. This key is the principal's secret key. (The key
+can be encrypted before storage under a Kerberos "master key" to protect it
+in case the database is compromised but the master key is not. In that case,
+an extra field must be added to indicate the master key version used, see
+below.) The p_kvno field is the key version number of the principal's secret
+key. The max_life field contains the maximum allowable lifetime (endtime -
+starttime) for any Ticket issued for this principal. The max_renewable_life
+field contains the maximum allowable total lifetime for any renewable Ticket
+issued for this principal. (See section 3.1 for a description of how these
+lifetimes are used in determining the lifetime of a given Ticket.)
+
+A server may provide KDC service to several realms, as long as the database
+representation provides a mechanism to distinguish between principal records
+with identifiers which differ only in the realm name.
+
+When an application server's key changes, if the change is routine (i.e. not
+the result of disclosure of the old key), the old key should be retained by
+the server until all tickets that had been issued using that key have
+expired. Because of this, it is possible for several keys to be active for a
+single principal. Ciphertext encrypted in a principal's key is always tagged
+with the version of the key that was used for encryption, to help the
+recipient find the proper key for decryption.
+
+When more than one key is active for a particular principal, the principal
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+will have more than one record in the Kerberos database. The keys and key
+version numbers will differ between the records (the rest of the fields may
+or may not be the same). Whenever Kerberos issues a ticket, or responds to a
+request for initial authentication, the most recent key (known by the
+Kerberos server) will be used for encryption. This is the key with the
+highest key version number.
+
+4.2. Additional fields
+
+Project Athena's KDC implementation uses additional fields in its database:
+
+Field Value
+
+K_kvno Kerberos' key version
+expiration Expiration date for entry
+attributes Bit field of attributes
+mod_date Timestamp of last modification
+mod_name Modifying principal's identifier
+
+The K_kvno field indicates the key version of the Kerberos master key under
+which the principal's secret key is encrypted.
+
+After an entry's expiration date has passed, the KDC will return an error to
+any client attempting to gain tickets as or for the principal. (A database
+may want to maintain two expiration dates: one for the principal, and one
+for the principal's current key. This allows password aging to work
+independently of the principal's expiration date. However, due to the
+limited space in the responses, the KDC must combine the key expiration and
+principal expiration date into a single value called 'key_exp', which is
+used as a hint to the user to take administrative action.)
+
+The attributes field is a bitfield used to govern the operations involving
+the principal. This field might be useful in conjunction with user
+registration procedures, for site-specific policy implementations (Project
+Athena currently uses it for their user registration process controlled by
+the system-wide database service, Moira [LGDSR87]), to identify whether a
+principal can play the role of a client or server or both, to note whether a
+server is appropriate trusted to recieve credentials delegated by a client,
+or to identify the 'string to key' conversion algorithm used for a
+principal's key[22]. Other bits are used to indicate that certain ticket
+options should not be allowed in tickets encrypted under a principal's key
+(one bit each): Disallow issuing postdated tickets, disallow issuing
+forwardable tickets, disallow issuing tickets based on TGT authentication,
+disallow issuing renewable tickets, disallow issuing proxiable tickets, and
+disallow issuing tickets for which the principal is the server.
+
+The mod_date field contains the time of last modification of the entry, and
+the mod_name field contains the name of the principal which last modified
+the entry.
+
+4.3. Frequently Changing Fields
+
+Some KDC implementations may wish to maintain the last time that a request
+was made by a particular principal. Information that might be maintained
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+includes the time of the last request, the time of the last request for a
+ticket-granting ticket, the time of the last use of a ticket-granting
+ticket, or other times. This information can then be returned to the user in
+the last-req field (see section 5.2).
+
+Other frequently changing information that can be maintained is the latest
+expiration time for any tickets that have been issued using each key. This
+field would be used to indicate how long old keys must remain valid to allow
+the continued use of outstanding tickets.
+
+4.4. Site Constants
+
+The KDC implementation should have the following configurable constants or
+options, to allow an administrator to make and enforce policy decisions:
+
+ * The minimum supported lifetime (used to determine whether the
+ KDC_ERR_NEVER_VALID error should be returned). This constant should
+ reflect reasonable expectations of round-trip time to the KDC,
+ encryption/decryption time, and processing time by the client and
+ target server, and it should allow for a minimum 'useful' lifetime.
+ * The maximum allowable total (renewable) lifetime of a ticket
+ (renew_till - starttime).
+ * The maximum allowable lifetime of a ticket (endtime - starttime).
+ * Whether to allow the issue of tickets with empty address fields
+ (including the ability to specify that such tickets may only be issued
+ if the request specifies some authorization_data).
+ * Whether proxiable, forwardable, renewable or post-datable tickets are
+ to be issued.
+
+5. Message Specifications
+
+The following sections describe the exact contents and encoding of protocol
+messages and objects. The ASN.1 base definitions are presented in the first
+subsection. The remaining subsections specify the protocol objects (tickets
+and authenticators) and messages. Specification of encryption and checksum
+techniques, and the fields related to them, appear in section 6.
+
+5.1. ASN.1 Distinguished Encoding Representation
+
+All uses of ASN.1 in Kerberos shall use the Distinguished Encoding
+Representation of the data elements as described in the X.509 specification,
+section 8.7 [X509-88].
+
+5.2. ASN.1 Base Definitions
+
+The following ASN.1 base definitions are used in the rest of this section.
+Note that since the underscore character (_) is not permitted in ASN.1
+names, the hyphen (-) is used in its place for the purposes of ASN.1 names.
+
+Realm ::= GeneralString
+PrincipalName ::= SEQUENCE {
+ name-type[0] INTEGER,
+ name-string[1] SEQUENCE OF GeneralString
+}
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+Kerberos realms are encoded as GeneralStrings. Realms shall not contain a
+character with the code 0 (the ASCII NUL). Most realms will usually consist
+of several components separated by periods (.), in the style of Internet
+Domain Names, or separated by slashes (/) in the style of X.500 names.
+Acceptable forms for realm names are specified in section 7. A PrincipalName
+is a typed sequence of components consisting of the following sub-fields:
+
+name-type
+ This field specifies the type of name that follows. Pre-defined values
+ for this field are specified in section 7.2. The name-type should be
+ treated as a hint. Ignoring the name type, no two names can be the same
+ (i.e. at least one of the components, or the realm, must be different).
+ This constraint may be eliminated in the future.
+name-string
+ This field encodes a sequence of components that form a name, each
+ component encoded as a GeneralString. Taken together, a PrincipalName
+ and a Realm form a principal identifier. Most PrincipalNames will have
+ only a few components (typically one or two).
+
+KerberosTime ::= GeneralizedTime
+ -- Specifying UTC time zone (Z)
+
+The timestamps used in Kerberos are encoded as GeneralizedTimes. An encoding
+shall specify the UTC time zone (Z) and shall not include any fractional
+portions of the seconds. It further shall not include any separators.
+Example: The only valid format for UTC time 6 minutes, 27 seconds after 9 pm
+on 6 November 1985 is 19851106210627Z.
+
+HostAddress ::= SEQUENCE {
+ addr-type[0] INTEGER,
+ address[1] OCTET STRING
+}
+
+HostAddresses ::= SEQUENCE OF HostAddress
+
+The host adddress encodings consists of two fields:
+
+addr-type
+ This field specifies the type of address that follows. Pre-defined
+ values for this field are specified in section 8.1.
+address
+ This field encodes a single address of type addr-type.
+
+The two forms differ slightly. HostAddress contains exactly one address;
+HostAddresses contains a sequence of possibly many addresses.
+
+AuthorizationData ::= SEQUENCE OF SEQUENCE {
+ ad-type[0] INTEGER,
+ ad-data[1] OCTET STRING
+}
+
+ad-data
+ This field contains authorization data to be interpreted according to
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ the value of the corresponding ad-type field.
+ad-type
+ This field specifies the format for the ad-data subfield. All negative
+ values are reserved for local use. Non-negative values are reserved for
+ registered use.
+
+Each sequence of type and data is refered to as an authorization element.
+Elements may be application specific, however, there is a common set of
+recursive elements that should be understood by all implementations. These
+elements contain other elements embedded within them, and the interpretation
+of the encapsulating element determines which of the embedded elements must
+be interpreted, and which may be ignored. Definitions for these common
+elements may be found in Appendix B.
+
+TicketExtensions ::= SEQUENCE OF SEQUENCE {
+ te-type[0] INTEGER,
+ te-data[1] OCTET STRING
+}
+
+
+
+te-data
+ This field contains opaque data that must be caried with the ticket to
+ support extensions to the Kerberos protocol including but not limited
+ to some forms of inter-realm key exchange and plaintext authorization
+ data. See appendix C for some common uses of this field.
+te-type
+ This field specifies the format for the te-data subfield. All negative
+ values are reserved for local use. Non-negative values are reserved for
+ registered use.
+
+APOptions ::= BIT STRING {
+ reserved(0),
+ use-session-key(1),
+ mutual-required(2)
+}
+
+TicketFlags ::= BIT STRING {
+ reserved(0),
+ forwardable(1),
+ forwarded(2),
+ proxiable(3),
+ proxy(4),
+ may-postdate(5),
+ postdated(6),
+ invalid(7),
+ renewable(8),
+ initial(9),
+ pre-authent(10),
+ hw-authent(11),
+ transited-policy-checked(12),
+ ok-as-delegate(13)
+}
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+KDCOptions ::= BIT STRING {
+ reserved(0),
+ forwardable(1),
+ forwarded(2),
+ proxiable(3),
+ proxy(4),
+ allow-postdate(5),
+ postdated(6),
+ unused7(7),
+ renewable(8),
+ unused9(9),
+ unused10(10),
+ unused11(11),
+ unused12(12),
+ unused13(13),
+ disable-transited-check(26),
+ renewable-ok(27),
+ enc-tkt-in-skey(28),
+ renew(30),
+ validate(31)
+}
+
+ASN.1 Bit strings have a length and a value. When used in Kerberos for the
+APOptions, TicketFlags, and KDCOptions, the length of the bit string on
+generated values should be the smallest multiple of 32 bits needed to
+include the highest order bit that is set (1), but in no case less than 32
+bits. Implementations should accept values of bit strings of any length and
+treat the value of flags cooresponding to bits beyond the end of the bit
+string as if the bit were reset (0). Comparisonof bit strings of different
+length should treat the smaller string as if it were padded with zeros
+beyond the high order bits to the length of the longer string[23].
+
+LastReq ::= SEQUENCE OF SEQUENCE {
+ lr-type[0] INTEGER,
+ lr-value[1] KerberosTime
+}
+
+lr-type
+ This field indicates how the following lr-value field is to be
+ interpreted. Negative values indicate that the information pertains
+ only to the responding server. Non-negative values pertain to all
+ servers for the realm. If the lr-type field is zero (0), then no
+ information is conveyed by the lr-value subfield. If the absolute value
+ of the lr-type field is one (1), then the lr-value subfield is the time
+ of last initial request for a TGT. If it is two (2), then the lr-value
+ subfield is the time of last initial request. If it is three (3), then
+ the lr-value subfield is the time of issue for the newest
+ ticket-granting ticket used. If it is four (4), then the lr-value
+ subfield is the time of the last renewal. If it is five (5), then the
+ lr-value subfield is the time of last request (of any type).
+lr-value
+ This field contains the time of the last request. the time must be
+ interpreted according to the contents of the accompanying lr-type
+ subfield.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+See section 6 for the definitions of Checksum, ChecksumType, EncryptedData,
+EncryptionKey, EncryptionType, and KeyType.
+
+5.3. Tickets and Authenticators
+
+This section describes the format and encryption parameters for tickets and
+authenticators. When a ticket or authenticator is included in a protocol
+message it is treated as an opaque object.
+
+5.3.1. Tickets
+
+A ticket is a record that helps a client authenticate to a service. A Ticket
+contains the following information:
+
+Ticket ::= [APPLICATION 1] SEQUENCE {
+ tkt-vno[0] INTEGER,
+ realm[1] Realm,
+ sname[2] PrincipalName,
+ enc-part[3] EncryptedData,
+ extensions[4] TicketExtensions OPTIONAL
+}
+
+-- Encrypted part of ticket
+EncTicketPart ::= [APPLICATION 3] SEQUENCE {
+ flags[0] TicketFlags,
+ key[1] EncryptionKey,
+ crealm[2] Realm,
+ cname[3] PrincipalName,
+ transited[4] TransitedEncoding,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ caddr[9] HostAddresses OPTIONAL,
+ authorization-data[10] AuthorizationData OPTIONAL
+}
+-- encoded Transited field
+TransitedEncoding ::= SEQUENCE {
+ tr-type[0] INTEGER, -- must be registered
+ contents[1] OCTET STRING
+}
+
+The encoding of EncTicketPart is encrypted in the key shared by Kerberos and
+the end server (the server's secret key). See section 6 for the format of
+the ciphertext.
+
+tkt-vno
+ This field specifies the version number for the ticket format. This
+ document describes version number 5.
+realm
+ This field specifies the realm that issued a ticket. It also serves to
+ identify the realm part of the server's principal identifier. Since a
+ Kerberos server can only issue tickets for servers within its realm,
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ the two will always be identical.
+sname
+ This field specifies the name part of the server's identity.
+enc-part
+ This field holds the encrypted encoding of the EncTicketPart sequence.
+extensions
+ This optional field contains a sequence of extentions that may be used
+ to carry information that must be carried with the ticket to support
+ several extensions, including but not limited to plaintext
+ authorization data, tokens for exchanging inter-realm keys, and other
+ information that must be associated with a ticket for use by the
+ application server. See Appendix C for definitions of some common
+ extensions.
+
+ Note that some older versions of Kerberos did not support this field.
+ Because this is an optional field it will not break older clients, but
+ older clients might strip this field from the ticket before sending it
+ to the application server. This limits the usefulness of this ticket
+ field to environments where the ticket will not be parsed and
+ reconstructed by these older Kerberos clients.
+
+ If it is known that the client will strip this field from the ticket,
+ as an interim measure the KDC may append this field to the end of the
+ enc-part of the ticket and append a traler indicating the lenght of the
+ appended extensions field. (this paragraph is open for discussion,
+ including the form of the traler).
+flags
+ This field indicates which of various options were used or requested
+ when the ticket was issued. It is a bit-field, where the selected
+ options are indicated by the bit being set (1), and the unselected
+ options and reserved fields being reset (0). Bit 0 is the most
+ significant bit. The encoding of the bits is specified in section 5.2.
+ The flags are described in more detail above in section 2. The meanings
+ of the flags are:
+
+ Bit(s) Name Description
+
+ 0 RESERVED
+ Reserved for future expansion of this
+ field.
+
+ 1 FORWARDABLE
+ The FORWARDABLE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. When set, this
+ flag tells the ticket-granting server
+ that it is OK to issue a new ticket-
+ granting ticket with a different network
+ address based on the presented ticket.
+
+ 2 FORWARDED
+ When set, this flag indicates that the
+ ticket has either been forwarded or was
+ issued based on authentication involving
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ a forwarded ticket-granting ticket.
+
+ 3 PROXIABLE
+ The PROXIABLE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. The PROXIABLE
+ flag has an interpretation identical to
+ that of the FORWARDABLE flag, except
+ that the PROXIABLE flag tells the
+ ticket-granting server that only non-
+ ticket-granting tickets may be issued
+ with different network addresses.
+
+ 4 PROXY
+ When set, this flag indicates that a
+ ticket is a proxy.
+
+ 5 MAY-POSTDATE
+ The MAY-POSTDATE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. This flag tells
+ the ticket-granting server that a post-
+ dated ticket may be issued based on this
+ ticket-granting ticket.
+
+ 6 POSTDATED
+ This flag indicates that this ticket has
+ been postdated. The end-service can
+ check the authtime field to see when the
+ original authentication occurred.
+
+ 7 INVALID
+ This flag indicates that a ticket is
+ invalid, and it must be validated by the
+ KDC before use. Application servers
+ must reject tickets which have this flag
+ set.
+
+ 8 RENEWABLE
+ The RENEWABLE flag is normally only
+ interpreted by the TGS, and can usually
+ be ignored by end servers (some particu-
+ larly careful servers may wish to disal-
+ low renewable tickets). A renewable
+ ticket can be used to obtain a replace-
+ ment ticket that expires at a later
+ date.
+
+ 9 INITIAL
+ This flag indicates that this ticket was
+ issued using the AS protocol, and not
+ issued based on a ticket-granting
+ ticket.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ 10 PRE-AUTHENT
+ This flag indicates that during initial
+ authentication, the client was authenti-
+ cated by the KDC before a ticket was
+ issued. The strength of the pre-
+ authentication method is not indicated,
+ but is acceptable to the KDC.
+
+ 11 HW-AUTHENT
+ This flag indicates that the protocol
+ employed for initial authentication
+ required the use of hardware expected to
+ be possessed solely by the named client.
+ The hardware authentication method is
+ selected by the KDC and the strength of
+ the method is not indicated.
+
+ 12 TRANSITED This flag indicates that the KDC for the
+ POLICY-CHECKED realm has checked the transited field
+ against a realm defined policy for
+ trusted certifiers. If this flag is
+ reset (0), then the application server
+ must check the transited field itself,
+ and if unable to do so it must reject
+ the authentication. If the flag is set
+ (1) then the application server may skip
+ its own validation of the transited
+ field, relying on the validation
+ performed by the KDC. At its option the
+ application server may still apply its
+ own validation based on a separate
+ policy for acceptance.
+
+ 13 OK-AS-DELEGATE This flag indicates that the server (not
+ the client) specified in the ticket has
+ been determined by policy of the realm
+ to be a suitable recipient of
+ delegation. A client can use the
+ presence of this flag to help it make a
+ decision whether to delegate credentials
+ (either grant a proxy or a forwarded
+ ticket granting ticket) to this server.
+ The client is free to ignore the value
+ of this flag. When setting this flag,
+ an administrator should consider the
+ Security and placement of the server on
+ which the service will run, as well as
+ whether the service requires the use of
+ delegated credentials.
+
+ 14 ANONYMOUS
+ This flag indicates that the principal
+ named in the ticket is a generic princi-
+ pal for the realm and does not identify
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ the individual using the ticket. The
+ purpose of the ticket is only to
+ securely distribute a session key, and
+ not to identify the user. Subsequent
+ requests using the same ticket and ses-
+ sion may be considered as originating
+ from the same user, but requests with
+ the same username but a different ticket
+ are likely to originate from different
+ users.
+
+ 15-31 RESERVED
+ Reserved for future use.
+
+key
+ This field exists in the ticket and the KDC response and is used to
+ pass the session key from Kerberos to the application server and the
+ client. The field's encoding is described in section 6.2.
+crealm
+ This field contains the name of the realm in which the client is
+ registered and in which initial authentication took place.
+cname
+ This field contains the name part of the client's principal identifier.
+transited
+ This field lists the names of the Kerberos realms that took part in
+ authenticating the user to whom this ticket was issued. It does not
+ specify the order in which the realms were transited. See section
+ 3.3.3.2 for details on how this field encodes the traversed realms.
+authtime
+ This field indicates the time of initial authentication for the named
+ principal. It is the time of issue for the original ticket on which
+ this ticket is based. It is included in the ticket to provide
+ additional information to the end service, and to provide the necessary
+ information for implementation of a `hot list' service at the KDC. An
+ end service that is particularly paranoid could refuse to accept
+ tickets for which the initial authentication occurred "too far" in the
+ past. This field is also returned as part of the response from the KDC.
+ When returned as part of the response to initial authentication
+ (KRB_AS_REP), this is the current time on the Ker- beros server[24].
+starttime
+ This field in the ticket specifies the time after which the ticket is
+ valid. Together with endtime, this field specifies the life of the
+ ticket. If it is absent from the ticket, its value should be treated as
+ that of the authtime field.
+endtime
+ This field contains the time after which the ticket will not be honored
+ (its expiration time). Note that individual services may place their
+ own limits on the life of a ticket and may reject tickets which have
+ not yet expired. As such, this is really an upper bound on the
+ expiration time for the ticket.
+renew-till
+ This field is only present in tickets that have the RENEWABLE flag set
+ in the flags field. It indicates the maximum endtime that may be
+ included in a renewal. It can be thought of as the absolute expiration
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ time for the ticket, including all renewals.
+caddr
+ This field in a ticket contains zero (if omitted) or more (if present)
+ host addresses. These are the addresses from which the ticket can be
+ used. If there are no addresses, the ticket can be used from any
+ location. The decision by the KDC to issue or by the end server to
+ accept zero-address tickets is a policy decision and is left to the
+ Kerberos and end-service administrators; they may refuse to issue or
+ accept such tickets. The suggested and default policy, however, is that
+ such tickets will only be issued or accepted when additional
+ information that can be used to restrict the use of the ticket is
+ included in the authorization_data field. Such a ticket is a
+ capability.
+
+ Network addresses are included in the ticket to make it harder for an
+ attacker to use stolen credentials. Because the session key is not sent
+ over the network in cleartext, credentials can't be stolen simply by
+ listening to the network; an attacker has to gain access to the session
+ key (perhaps through operating system security breaches or a careless
+ user's unattended session) to make use of stolen tickets.
+
+ It is important to note that the network address from which a
+ connection is received cannot be reliably determined. Even if it could
+ be, an attacker who has compromised the client's worksta- tion could
+ use the credentials from there. Including the network addresses only
+ makes it more difficult, not impossible, for an attacker to walk off
+ with stolen credentials and then use them from a "safe" location.
+authorization-data
+ The authorization-data field is used to pass authorization data from
+ the principal on whose behalf a ticket was issued to the application
+ service. If no authorization data is included, this field will be left
+ out. Experience has shown that the name of this field is confusing, and
+ that a better name for this field would be restrictions. Unfortunately,
+ it is not possible to change the name of this field at this time.
+
+ This field contains restrictions on any authority obtained on the basis
+ of authentication using the ticket. It is possible for any principal in
+ posession of credentials to add entries to the authorization data field
+ since these entries further restrict what can be done with the ticket.
+ Such additions can be made by specifying the additional entries when a
+ new ticket is obtained during the TGS exchange, or they may be added
+ during chained delegation using the authorization data field of the
+ authenticator.
+
+ Because entries may be added to this field by the holder of
+ credentials, it is not allowable for the presence of an entry in the
+ authorization data field of a ticket to amplify the priveleges one
+ would obtain from using a ticket.
+
+ The data in this field may be specific to the end service; the field
+ will contain the names of service specific objects, and the rights to
+ those objects. The format for this field is described in section 5.2.
+ Although Kerberos is not concerned with the format of the contents of
+ the sub-fields, it does carry type information (ad-type).
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+ By using the authorization_data field, a principal is able to issue a
+ proxy that is valid for a specific purpose. For example, a client
+ wishing to print a file can obtain a file server proxy to be passed to
+ the print server. By specifying the name of the file in the
+ authorization_data field, the file server knows that the print server
+ can only use the client's rights when accessing the particular file to
+ be printed.
+
+ A separate service providing authorization or certifying group
+ membership may be built using the authorization-data field. In this
+ case, the entity granting authorization (not the authorized entity),
+ obtains a ticket in its own name (e.g. the ticket is issued in the name
+ of a privelege server), and this entity adds restrictions on its own
+ authority and delegates the restricted authority through a proxy to the
+ client. The client would then present this authorization credential to
+ the application server separately from the authentication exchange.
+
+ Similarly, if one specifies the authorization-data field of a proxy and
+ leaves the host addresses blank, the resulting ticket and session key
+ can be treated as a capability. See [Neu93] for some suggested uses of
+ this field.
+
+ The authorization-data field is optional and does not have to be
+ included in a ticket.
+
+5.3.2. Authenticators
+
+An authenticator is a record sent with a ticket to a server to certify the
+client's knowledge of the encryption key in the ticket, to help the server
+detect replays, and to help choose a "true session key" to use with the
+particular session. The encoding is encrypted in the ticket's session key
+shared by the client and the server:
+
+-- Unencrypted authenticator
+Authenticator ::= [APPLICATION 2] SEQUENCE {
+ authenticator-vno[0] INTEGER,
+ crealm[1] Realm,
+ cname[2] PrincipalName,
+ cksum[3] Checksum OPTIONAL,
+ cusec[4] INTEGER,
+ ctime[5] KerberosTime,
+ subkey[6] EncryptionKey OPTIONAL,
+ seq-number[7] INTEGER OPTIONAL,
+ authorization-data[8] AuthorizationData OPTIONAL
+}
+
+
+authenticator-vno
+ This field specifies the version number for the format of the
+ authenticator. This document specifies version 5.
+crealm and cname
+ These fields are the same as those described for the ticket in section
+ 5.3.1.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+cksum
+ This field contains a checksum of the the applica- tion data that
+ accompanies the KRB_AP_REQ.
+cusec
+ This field contains the microsecond part of the client's timestamp. Its
+ value (before encryption) ranges from 0 to 999999. It often appears
+ along with ctime. The two fields are used together to specify a
+ reasonably accurate timestamp.
+ctime
+ This field contains the current time on the client's host.
+subkey
+ This field contains the client's choice for an encryption key which is
+ to be used to protect this specific application session. Unless an
+ application specifies otherwise, if this field is left out the session
+ key from the ticket will be used.
+seq-number
+ This optional field includes the initial sequence number to be used by
+ the KRB_PRIV or KRB_SAFE messages when sequence numbers are used to
+ detect replays (It may also be used by application specific messages).
+ When included in the authenticator this field specifies the initial
+ sequence number for messages from the client to the server. When
+ included in the AP-REP message, the initial sequence number is that for
+ messages from the server to the client. When used in KRB_PRIV or
+ KRB_SAFE messages, it is incremented by one after each message is sent.
+
+ For sequence numbers to adequately support the detection of replays
+ they should be non-repeating, even across connection boundaries. The
+ initial sequence number should be random and uniformly distributed
+ across the full space of possible sequence numbers, so that it cannot
+ be guessed by an attacker and so that it and the successive sequence
+ numbers do not repeat other sequences.
+authorization-data
+ This field is the same as described for the ticket in section 5.3.1. It
+ is optional and will only appear when additional restrictions are to be
+ placed on the use of a ticket, beyond those carried in the ticket
+ itself.
+
+5.4. Specifications for the AS and TGS exchanges
+
+This section specifies the format of the messages used in the exchange
+between the client and the Kerberos server. The format of possible error
+messages appears in section 5.9.1.
+
+5.4.1. KRB_KDC_REQ definition
+
+The KRB_KDC_REQ message has no type of its own. Instead, its type is one of
+KRB_AS_REQ or KRB_TGS_REQ depending on whether the request is for an initial
+ticket or an additional ticket. In either case, the message is sent from the
+client to the Authentication Server to request credentials for a service.
+
+The message fields are:
+
+AS-REQ ::= [APPLICATION 10] KDC-REQ
+TGS-REQ ::= [APPLICATION 12] KDC-REQ
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+KDC-REQ ::= SEQUENCE {
+ pvno[1] INTEGER,
+ msg-type[2] INTEGER,
+ padata[3] SEQUENCE OF PA-DATA OPTIONAL,
+ req-body[4] KDC-REQ-BODY
+}
+
+PA-DATA ::= SEQUENCE {
+ padata-type[1] INTEGER,
+ padata-value[2] OCTET STRING,
+ -- might be encoded AP-REQ
+}
+
+KDC-REQ-BODY ::= SEQUENCE {
+ kdc-options[0] KDCOptions,
+ cname[1] PrincipalName OPTIONAL,
+ -- Used only in AS-REQ
+ realm[2] Realm, -- Server's realm
+ -- Also client's in AS-REQ
+ sname[3] PrincipalName OPTIONAL,
+ from[4] KerberosTime OPTIONAL,
+ till[5] KerberosTime OPTIONAL,
+ rtime[6] KerberosTime OPTIONAL,
+ nonce[7] INTEGER,
+ etype[8] SEQUENCE OF INTEGER,
+ -- EncryptionType,
+ -- in preference order
+ addresses[9] HostAddresses OPTIONAL,
+ enc-authorization-data[10] EncryptedData OPTIONAL,
+ -- Encrypted AuthorizationData
+ -- encoding
+ additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
+}
+
+The fields in this message are:
+
+pvno
+ This field is included in each message, and specifies the protocol
+ version number. This document specifies protocol version 5.
+msg-type
+ This field indicates the type of a protocol message. It will almost
+ always be the same as the application identifier associated with a
+ message. It is included to make the identifier more readily accessible
+ to the application. For the KDC-REQ message, this type will be
+ KRB_AS_REQ or KRB_TGS_REQ.
+padata
+ The padata (pre-authentication data) field contains a sequence of
+ authentication information which may be needed before credentials can
+ be issued or decrypted. In the case of requests for additional tickets
+ (KRB_TGS_REQ), this field will include an element with padata-type of
+ PA-TGS-REQ and data of an authentication header (ticket-granting ticket
+ and authenticator). The checksum in the authenticator (which must be
+ collision-proof) is to be computed over the KDC-REQ-BODY encoding. In
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ most requests for initial authentication (KRB_AS_REQ) and most replies
+ (KDC-REP), the padata field will be left out.
+
+ This field may also contain information needed by certain extensions to
+ the Kerberos protocol. For example, it might be used to initially
+ verify the identity of a client before any response is returned. This
+ is accomplished with a padata field with padata-type equal to
+ PA-ENC-TIMESTAMP and padata-value defined as follows:
+
+ padata-type ::= PA-ENC-TIMESTAMP
+ padata-value ::= EncryptedData -- PA-ENC-TS-ENC
+
+ PA-ENC-TS-ENC ::= SEQUENCE {
+ patimestamp[0] KerberosTime, -- client's time
+ pausec[1] INTEGER OPTIONAL
+ }
+
+ with patimestamp containing the client's time and pausec containing the
+ microseconds which may be omitted if a client will not generate more
+ than one request per second. The ciphertext (padata-value) consists of
+ the PA-ENC-TS-ENC sequence, encrypted using the client's secret key.
+
+ [use-specified-kvno item is here for discussion and may be removed] It
+ may also be used by the client to specify the version of a key that is
+ being used for accompanying preauthentication, and/or which should be
+ used to encrypt the reply from the KDC.
+
+ PA-USE-SPECIFIED-KVNO ::= Integer
+
+ The KDC should only accept and abide by the value of the
+ use-specified-kvno preauthentication data field when the specified key
+ is still valid and until use of a new key is confirmed. This situation
+ is likely to occur primarily during the period during which an updated
+ key is propagating to other KDC's in a realm.
+
+ The padata field can also contain information needed to help the KDC or
+ the client select the key needed for generating or decrypting the
+ response. This form of the padata is useful for supporting the use of
+ certain token cards with Kerberos. The details of such extensions are
+ specified in separate documents. See [Pat92] for additional uses of
+ this field.
+padata-type
+ The padata-type element of the padata field indicates the way that the
+ padata-value element is to be interpreted. Negative values of
+ padata-type are reserved for unregistered use; non-negative values are
+ used for a registered interpretation of the element type.
+req-body
+ This field is a placeholder delimiting the extent of the remaining
+ fields. If a checksum is to be calculated over the request, it is
+ calculated over an encoding of the KDC-REQ-BODY sequence which is
+ enclosed within the req-body field.
+kdc-options
+ This field appears in the KRB_AS_REQ and KRB_TGS_REQ requests to the
+ KDC and indicates the flags that the client wants set on the tickets as
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ well as other information that is to modify the behavior of the KDC.
+ Where appropriate, the name of an option may be the same as the flag
+ that is set by that option. Although in most case, the bit in the
+ options field will be the same as that in the flags field, this is not
+ guaranteed, so it is not acceptable to simply copy the options field to
+ the flags field. There are various checks that must be made before
+ honoring an option anyway.
+
+ The kdc_options field is a bit-field, where the selected options are
+ indicated by the bit being set (1), and the unselected options and
+ reserved fields being reset (0). The encoding of the bits is specified
+ in section 5.2. The options are described in more detail above in
+ section 2. The meanings of the options are:
+
+ Bit(s) Name Description
+ 0 RESERVED
+ Reserved for future expansion of this
+ field.
+
+ 1 FORWARDABLE
+ The FORWARDABLE option indicates that
+ the ticket to be issued is to have its
+ forwardable flag set. It may only be
+ set on the initial request, or in a sub-
+ sequent request if the ticket-granting
+ ticket on which it is based is also for-
+ wardable.
+
+ 2 FORWARDED
+ The FORWARDED option is only specified
+ in a request to the ticket-granting
+ server and will only be honored if the
+ ticket-granting ticket in the request
+ has its FORWARDABLE bit set. This
+ option indicates that this is a request
+ for forwarding. The address(es) of the
+ host from which the resulting ticket is
+ to be valid are included in the
+ addresses field of the request.
+
+ 3 PROXIABLE
+ The PROXIABLE option indicates that the
+ ticket to be issued is to have its prox-
+ iable flag set. It may only be set on
+ the initial request, or in a subsequent
+ request if the ticket-granting ticket on
+ which it is based is also proxiable.
+
+ 4 PROXY
+ The PROXY option indicates that this is
+ a request for a proxy. This option will
+ only be honored if the ticket-granting
+ ticket in the request has its PROXIABLE
+ bit set. The address(es) of the host
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ from which the resulting ticket is to be
+ valid are included in the addresses
+ field of the request.
+
+ 5 ALLOW-POSTDATE
+ The ALLOW-POSTDATE option indicates that
+ the ticket to be issued is to have its
+ MAY-POSTDATE flag set. It may only be
+ set on the initial request, or in a sub-
+ sequent request if the ticket-granting
+ ticket on which it is based also has its
+ MAY-POSTDATE flag set.
+
+ 6 POSTDATED
+ The POSTDATED option indicates that this
+ is a request for a postdated ticket.
+ This option will only be honored if the
+ ticket-granting ticket on which it is
+ based has its MAY-POSTDATE flag set.
+ The resulting ticket will also have its
+ INVALID flag set, and that flag may be
+ reset by a subsequent request to the KDC
+ after the starttime in the ticket has
+ been reached.
+
+ 7 UNUSED
+ This option is presently unused.
+
+ 8 RENEWABLE
+ The RENEWABLE option indicates that the
+ ticket to be issued is to have its
+ RENEWABLE flag set. It may only be set
+ on the initial request, or when the
+ ticket-granting ticket on which the
+ request is based is also renewable. If
+ this option is requested, then the rtime
+ field in the request contains the
+ desired absolute expiration time for the
+ ticket.
+
+ 9-13 UNUSED
+ These options are presently unused.
+
+ 14 REQUEST-ANONYMOUS
+ The REQUEST-ANONYMOUS option indicates
+ that the ticket to be issued is not to
+ identify the user to which it was
+ issued. Instead, the principal identif-
+ ier is to be generic, as specified by
+ the policy of the realm (e.g. usually
+ anonymous@realm). The purpose of the
+ ticket is only to securely distribute a
+ session key, and not to identify the
+ user. The ANONYMOUS flag on the ticket
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ to be returned should be set. If the
+ local realms policy does not permit
+ anonymous credentials, the request is to
+ be rejected.
+
+ 15-25 RESERVED
+ Reserved for future use.
+
+ 26 DISABLE-TRANSITED-CHECK
+ By default the KDC will check the
+ transited field of a ticket-granting-
+ ticket against the policy of the local
+ realm before it will issue derivative
+ tickets based on the ticket granting
+ ticket. If this flag is set in the
+ request, checking of the transited field
+ is disabled. Tickets issued without the
+ performance of this check will be noted
+ by the reset (0) value of the
+ TRANSITED-POLICY-CHECKED flag,
+ indicating to the application server
+ that the tranisted field must be checked
+ locally. KDC's are encouraged but not
+ required to honor the
+ DISABLE-TRANSITED-CHECK option.
+
+ 27 RENEWABLE-OK
+ The RENEWABLE-OK option indicates that a
+ renewable ticket will be acceptable if a
+ ticket with the requested life cannot
+ otherwise be provided. If a ticket with
+ the requested life cannot be provided,
+ then a renewable ticket may be issued
+ with a renew-till equal to the the
+ requested endtime. The value of the
+ renew-till field may still be limited by
+ local limits, or limits selected by the
+ individual principal or server.
+
+ 28 ENC-TKT-IN-SKEY
+ This option is used only by the ticket-
+ granting service. The ENC-TKT-IN-SKEY
+ option indicates that the ticket for the
+ end server is to be encrypted in the
+ session key from the additional ticket-
+ granting ticket provided.
+
+ 29 RESERVED
+ Reserved for future use.
+
+ 30 RENEW
+ This option is used only by the ticket-
+ granting service. The RENEW option
+ indicates that the present request is
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ for a renewal. The ticket provided is
+ encrypted in the secret key for the
+ server on which it is valid. This
+ option will only be honored if the
+ ticket to be renewed has its RENEWABLE
+ flag set and if the time in its renew-
+ till field has not passed. The ticket
+ to be renewed is passed in the padata
+ field as part of the authentication
+ header.
+
+ 31 VALIDATE
+ This option is used only by the ticket-
+ granting service. The VALIDATE option
+ indicates that the request is to vali-
+ date a postdated ticket. It will only
+ be honored if the ticket presented is
+ postdated, presently has its INVALID
+ flag set, and would be otherwise usable
+ at this time. A ticket cannot be vali-
+ dated before its starttime. The ticket
+ presented for validation is encrypted in
+ the key of the server for which it is
+ valid and is passed in the padata field
+ as part of the authentication header.
+
+cname and sname
+ These fields are the same as those described for the ticket in section
+ 5.3.1. sname may only be absent when the ENC-TKT-IN-SKEY option is
+ specified. If absent, the name of the server is taken from the name of
+ the client in the ticket passed as additional-tickets.
+enc-authorization-data
+ The enc-authorization-data, if present (and it can only be present in
+ the TGS_REQ form), is an encoding of the desired authorization-data
+ encrypted under the sub-session key if present in the Authenticator, or
+ alternatively from the session key in the ticket-granting ticket, both
+ from the padata field in the KRB_AP_REQ.
+realm
+ This field specifies the realm part of the server's principal
+ identifier. In the AS exchange, this is also the realm part of the
+ client's principal identifier.
+from
+ This field is included in the KRB_AS_REQ and KRB_TGS_REQ ticket
+ requests when the requested ticket is to be postdated. It specifies the
+ desired start time for the requested ticket. If this field is omitted
+ then the KDC should use the current time instead.
+till
+ This field contains the expiration date requested by the client in a
+ ticket request. It is optional and if omitted the requested ticket is
+ to have the maximum endtime permitted according to KDC policy for the
+ parties to the authentication exchange as limited by expiration date of
+ the ticket granting ticket or other preauthentication credentials.
+rtime
+ This field is the requested renew-till time sent from a client to the
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ KDC in a ticket request. It is optional.
+nonce
+ This field is part of the KDC request and response. It it intended to
+ hold a random number generated by the client. If the same number is
+ included in the encrypted response from the KDC, it provides evidence
+ that the response is fresh and has not been replayed by an attacker.
+ Nonces must never be re-used. Ideally, it should be generated randomly,
+ but if the correct time is known, it may suffice[25].
+etype
+ This field specifies the desired encryption algorithm to be used in the
+ response.
+addresses
+ This field is included in the initial request for tickets, and
+ optionally included in requests for additional tickets from the
+ ticket-granting server. It specifies the addresses from which the
+ requested ticket is to be valid. Normally it includes the addresses for
+ the client's host. If a proxy is requested, this field will contain
+ other addresses. The contents of this field are usually copied by the
+ KDC into the caddr field of the resulting ticket.
+additional-tickets
+ Additional tickets may be optionally included in a request to the
+ ticket-granting server. If the ENC-TKT-IN-SKEY option has been
+ specified, then the session key from the additional ticket will be used
+ in place of the server's key to encrypt the new ticket. If more than
+ one option which requires additional tickets has been specified, then
+ the additional tickets are used in the order specified by the ordering
+ of the options bits (see kdc-options, above).
+
+The application code will be either ten (10) or twelve (12) depending on
+whether the request is for an initial ticket (AS-REQ) or for an additional
+ticket (TGS-REQ).
+
+The optional fields (addresses, authorization-data and additional-tickets)
+are only included if necessary to perform the operation specified in the
+kdc-options field.
+
+It should be noted that in KRB_TGS_REQ, the protocol version number appears
+twice and two different message types appear: the KRB_TGS_REQ message
+contains these fields as does the authentication header (KRB_AP_REQ) that is
+passed in the padata field.
+
+5.4.2. KRB_KDC_REP definition
+
+The KRB_KDC_REP message format is used for the reply from the KDC for either
+an initial (AS) request or a subsequent (TGS) request. There is no message
+type for KRB_KDC_REP. Instead, the type will be either KRB_AS_REP or
+KRB_TGS_REP. The key used to encrypt the ciphertext part of the reply
+depends on the message type. For KRB_AS_REP, the ciphertext is encrypted in
+the client's secret key, and the client's key version number is included in
+the key version number for the encrypted data. For KRB_TGS_REP, the
+ciphertext is encrypted in the sub-session key from the Authenticator, or if
+absent, the session key from the ticket-granting ticket used in the request.
+In that case, no version number will be present in the EncryptedData
+sequence.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+The KRB_KDC_REP message contains the following fields:
+
+AS-REP ::= [APPLICATION 11] KDC-REP
+TGS-REP ::= [APPLICATION 13] KDC-REP
+
+KDC-REP ::= SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ padata[2] SEQUENCE OF PA-DATA OPTIONAL,
+ crealm[3] Realm,
+ cname[4] PrincipalName,
+ ticket[5] Ticket,
+ enc-part[6] EncryptedData
+}
+
+EncASRepPart ::= [APPLICATION 25[27]] EncKDCRepPart
+EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
+
+EncKDCRepPart ::= SEQUENCE {
+ key[0] EncryptionKey,
+ last-req[1] LastReq,
+ nonce[2] INTEGER,
+ key-expiration[3] KerberosTime OPTIONAL,
+ flags[4] TicketFlags,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ srealm[9] Realm,
+ sname[10] PrincipalName,
+ caddr[11] HostAddresses OPTIONAL
+}
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is either
+ KRB_AS_REP or KRB_TGS_REP.
+padata
+ This field is described in detail in section 5.4.1. One possible use
+ for this field is to encode an alternate "mix-in" string to be used
+ with a string-to-key algorithm (such as is described in section 6.3.2).
+ This ability is useful to ease transitions if a realm name needs to
+ change (e.g. when a company is acquired); in such a case all existing
+ password-derived entries in the KDC database would be flagged as
+ needing a special mix-in string until the next password change.
+crealm, cname, srealm and sname
+ These fields are the same as those described for the ticket in section
+ 5.3.1.
+ticket
+ The newly-issued ticket, from section 5.3.1.
+enc-part
+ This field is a place holder for the ciphertext and related information
+ that forms the encrypted part of a message. The description of the
+ encrypted part of the message follows each appearance of this field.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ The encrypted part is encoded as described in section 6.1.
+key
+ This field is the same as described for the ticket in section 5.3.1.
+last-req
+ This field is returned by the KDC and specifies the time(s) of the last
+ request by a principal. Depending on what information is available,
+ this might be the last time that a request for a ticket-granting ticket
+ was made, or the last time that a request based on a ticket-granting
+ ticket was successful. It also might cover all servers for a realm, or
+ just the particular server. Some implementations may display this
+ information to the user to aid in discovering unauthorized use of one's
+ identity. It is similar in spirit to the last login time displayed when
+ logging into timesharing systems.
+nonce
+ This field is described above in section 5.4.1.
+key-expiration
+ The key-expiration field is part of the response from the KDC and
+ specifies the time that the client's secret key is due to expire. The
+ expiration might be the result of password aging or an account
+ expiration. This field will usually be left out of the TGS reply since
+ the response to the TGS request is encrypted in a session key and no
+ client information need be retrieved from the KDC database. It is up to
+ the application client (usually the login program) to take appropriate
+ action (such as notifying the user) if the expiration time is imminent.
+flags, authtime, starttime, endtime, renew-till and caddr
+ These fields are duplicates of those found in the encrypted portion of
+ the attached ticket (see section 5.3.1), provided so the client may
+ verify they match the intended request and to assist in proper ticket
+ caching. If the message is of type KRB_TGS_REP, the caddr field will
+ only be filled in if the request was for a proxy or forwarded ticket,
+ or if the user is substituting a subset of the addresses from the
+ ticket granting ticket. If the client-requested addresses are not
+ present or not used, then the addresses contained in the ticket will be
+ the same as those included in the ticket-granting ticket.
+
+5.5. Client/Server (CS) message specifications
+
+This section specifies the format of the messages used for the
+authentication of the client to the application server.
+
+5.5.1. KRB_AP_REQ definition
+
+The KRB_AP_REQ message contains the Kerberos protocol version number, the
+message type KRB_AP_REQ, an options field to indicate any options in use,
+and the ticket and authenticator themselves. The KRB_AP_REQ message is often
+referred to as the 'authentication header'.
+
+AP-REQ ::= [APPLICATION 14] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ap-options[2] APOptions,
+ ticket[3] Ticket,
+ authenticator[4] EncryptedData
+}
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+APOptions ::= BIT STRING {
+ reserved(0),
+ use-session-key(1),
+ mutual-required(2)
+}
+
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_AP_REQ.
+ap-options
+ This field appears in the application request (KRB_AP_REQ) and affects
+ the way the request is processed. It is a bit-field, where the selected
+ options are indicated by the bit being set (1), and the unselected
+ options and reserved fields being reset (0). The encoding of the bits
+ is specified in section 5.2. The meanings of the options are:
+
+ Bit(s) Name Description
+ 0 RESERVED
+ Reserved for future expansion of this
+ field.
+
+ 1 USE-SESSION-KEY
+ The USE-SESSION-KEY option indicates
+ that the ticket the client is presenting
+ to a server is encrypted in the session
+ key from the server's ticket-granting
+ ticket. When this option is not speci-
+ fied, the ticket is encrypted in the
+ server's secret key.
+
+ 2 MUTUAL-REQUIRED
+ The MUTUAL-REQUIRED option tells the
+ server that the client requires mutual
+ authentication, and that it must respond
+ with a KRB_AP_REP message.
+
+ 3-31 RESERVED
+ Reserved for future use.
+ticket
+ This field is a ticket authenticating the client to the server.
+authenticator
+ This contains the authenticator, which includes the client's choice of
+ a subkey. Its encoding is described in section 5.3.2.
+
+5.5.2. KRB_AP_REP definition
+
+The KRB_AP_REP message contains the Kerberos protocol version number, the
+message type, and an encrypted time- stamp. The message is sent in in
+response to an application request (KRB_AP_REQ) where the mutual
+authentication option has been selected in the ap-options field.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+AP-REP ::= [APPLICATION 15] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[2] EncryptedData
+}
+
+EncAPRepPart ::= [APPLICATION 27[29]] SEQUENCE {
+ ctime[0] KerberosTime,
+ cusec[1] INTEGER,
+ subkey[2] EncryptionKey OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL
+}
+
+The encoded EncAPRepPart is encrypted in the shared session key of the
+ticket. The optional subkey field can be used in an application-arranged
+negotiation to choose a per association session key.
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_AP_REP.
+enc-part
+ This field is described above in section 5.4.2.
+ctime
+ This field contains the current time on the client's host.
+cusec
+ This field contains the microsecond part of the client's timestamp.
+subkey
+ This field contains an encryption key which is to be used to protect
+ this specific application session. See section 3.2.6 for specifics on
+ how this field is used to negotiate a key. Unless an application
+ specifies otherwise, if this field is left out, the sub-session key
+ from the authenticator, or if also left out, the session key from the
+ ticket will be used.
+
+5.5.3. Error message reply
+
+If an error occurs while processing the application request, the KRB_ERROR
+message will be sent in response. See section 5.9.1 for the format of the
+error message. The cname and crealm fields may be left out if the server
+cannot determine their appropriate values from the corresponding KRB_AP_REQ
+message. If the authenticator was decipherable, the ctime and cusec fields
+will contain the values from it.
+
+5.6. KRB_SAFE message specification
+
+This section specifies the format of a message that can be used by either
+side (client or server) of an application to send a tamper-proof message to
+its peer. It presumes that a session key has previously been exchanged (for
+example, by using the KRB_AP_REQ/KRB_AP_REP messages).
+
+5.6.1. KRB_SAFE definition
+
+The KRB_SAFE message contains user data along with a collision-proof
+checksum keyed with the last encryption key negotiated via subkeys, or the
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+session key if no negotiation has occured. The message fields are:
+
+KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ safe-body[2] KRB-SAFE-BODY,
+ cksum[3] Checksum
+}
+
+KRB-SAFE-BODY ::= SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+}
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_SAFE.
+safe-body
+ This field is a placeholder for the body of the KRB-SAFE message. It is
+ to be encoded separately and then have the checksum computed over it,
+ for use in the cksum field.
+cksum
+ This field contains the checksum of the application data. Checksum
+ details are described in section 6.4. The checksum is computed over the
+ encoding of the KRB-SAFE-BODY sequence.
+user-data
+ This field is part of the KRB_SAFE and KRB_PRIV messages and contain
+ the application specific data that is being passed from the sender to
+ the recipient.
+timestamp
+ This field is part of the KRB_SAFE and KRB_PRIV messages. Its contents
+ are the current time as known by the sender of the message. By checking
+ the timestamp, the recipient of the message is able to make sure that
+ it was recently generated, and is not a replay.
+usec
+ This field is part of the KRB_SAFE and KRB_PRIV headers. It contains
+ the microsecond part of the timestamp.
+seq-number
+ This field is described above in section 5.3.2.
+s-address
+ This field specifies the address in use by the sender of the message.
+r-address
+ This field specifies the address in use by the recipient of the
+ message. It may be omitted for some uses (such as broadcast protocols),
+ but the recipient may arbitrarily reject such messages. This field
+ along with s-address can be used to help detect messages which have
+ been incorrectly or maliciously delivered to the wrong recipient.
+
+5.7. KRB_PRIV message specification
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+This section specifies the format of a message that can be used by either
+side (client or server) of an application to securely and privately send a
+message to its peer. It presumes that a session key has previously been
+exchanged (for example, by using the KRB_AP_REQ/KRB_AP_REP messages).
+
+5.7.1. KRB_PRIV definition
+
+The KRB_PRIV message contains user data encrypted in the Session Key. The
+message fields are:
+
+KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[3] EncryptedData
+}
+
+EncKrbPrivPart ::= [APPLICATION 28[31]] SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL, -- sender's addr
+ r-address[5] HostAddress OPTIONAL -- recip's addr
+}
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_PRIV.
+enc-part
+ This field holds an encoding of the EncKrbPrivPart sequence encrypted
+ under the session key[32]. This encrypted encoding is used for the
+ enc-part field of the KRB-PRIV message. See section 6 for the format of
+ the ciphertext.
+user-data, timestamp, usec, s-address and r-address
+ These fields are described above in section 5.6.1.
+seq-number
+ This field is described above in section 5.3.2.
+
+5.8. KRB_CRED message specification
+
+This section specifies the format of a message that can be used to send
+Kerberos credentials from one principal to another. It is presented here to
+encourage a common mechanism to be used by applications when forwarding
+tickets or providing proxies to subordinate servers. It presumes that a
+session key has already been exchanged perhaps by using the
+KRB_AP_REQ/KRB_AP_REP messages.
+
+5.8.1. KRB_CRED definition
+
+The KRB_CRED message contains a sequence of tickets to be sent and
+information needed to use the tickets, including the session key from each.
+The information needed to use the tickets is encrypted under an encryption
+key previously exchanged or transferred alongside the KRB_CRED message. The
+message fields are:
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+KRB-CRED ::= [APPLICATION 22] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER, -- KRB_CRED
+ tickets[2] SEQUENCE OF Ticket,
+ enc-part[3] EncryptedData
+}
+
+EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
+ ticket-info[0] SEQUENCE OF KrbCredInfo,
+ nonce[1] INTEGER OPTIONAL,
+ timestamp[2] KerberosTime OPTIONAL,
+ usec[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+}
+
+KrbCredInfo ::= SEQUENCE {
+ key[0] EncryptionKey,
+ prealm[1] Realm OPTIONAL,
+ pname[2] PrincipalName OPTIONAL,
+ flags[3] TicketFlags OPTIONAL,
+ authtime[4] KerberosTime OPTIONAL,
+ starttime[5] KerberosTime OPTIONAL,
+ endtime[6] KerberosTime OPTIONAL
+ renew-till[7] KerberosTime OPTIONAL,
+ srealm[8] Realm OPTIONAL,
+ sname[9] PrincipalName OPTIONAL,
+ caddr[10] HostAddresses OPTIONAL
+}
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_CRED.
+tickets
+ These are the tickets obtained from the KDC specifically for use by the
+ intended recipient. Successive tickets are paired with the
+ corresponding KrbCredInfo sequence from the enc-part of the KRB-CRED
+ message.
+enc-part
+ This field holds an encoding of the EncKrbCredPart sequence encrypted
+ under the session key shared between the sender and the intended
+ recipient. This encrypted encoding is used for the enc-part field of
+ the KRB-CRED message. See section 6 for the format of the ciphertext.
+nonce
+ If practical, an application may require the inclusion of a nonce
+ generated by the recipient of the message. If the same value is
+ included as the nonce in the message, it provides evidence that the
+ message is fresh and has not been replayed by an attacker. A nonce must
+ never be re-used; it should be generated randomly by the recipient of
+ the message and provided to the sender of the message in an application
+ specific manner.
+timestamp and usec
+ These fields specify the time that the KRB-CRED message was generated.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ The time is used to provide assurance that the message is fresh.
+s-address and r-address
+ These fields are described above in section 5.6.1. They are used
+ optionally to provide additional assurance of the integrity of the
+ KRB-CRED message.
+key
+ This field exists in the corresponding ticket passed by the KRB-CRED
+ message and is used to pass the session key from the sender to the
+ intended recipient. The field's encoding is described in section 6.2.
+
+The following fields are optional. If present, they can be associated with
+the credentials in the remote ticket file. If left out, then it is assumed
+that the recipient of the credentials already knows their value.
+
+prealm and pname
+ The name and realm of the delegated principal identity.
+flags, authtime, starttime, endtime, renew-till, srealm, sname, and caddr
+ These fields contain the values of the correspond- ing fields from the
+ ticket found in the ticket field. Descriptions of the fields are
+ identical to the descriptions in the KDC-REP message.
+
+5.9. Error message specification
+
+This section specifies the format for the KRB_ERROR message. The fields
+included in the message are intended to return as much information as
+possible about an error. It is not expected that all the information
+required by the fields will be available for all types of errors. If the
+appropriate information is not available when the message is composed, the
+corresponding field will be left out of the message.
+
+Note that since the KRB_ERROR message is not protected by any encryption, it
+is quite possible for an intruder to synthesize or modify such a message. In
+particular, this means that the client should not use any fields in this
+message for security-critical purposes, such as setting a system clock or
+generating a fresh authenticator. The message can be useful, however, for
+advising a user on the reason for some failure.
+
+5.9.1. KRB_ERROR definition
+
+The KRB_ERROR message consists of the following fields:
+
+KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ctime[2] KerberosTime OPTIONAL,
+ cusec[3] INTEGER OPTIONAL,
+ stime[4] KerberosTime,
+ susec[5] INTEGER,
+ error-code[6] INTEGER,
+ crealm[7] Realm OPTIONAL,
+ cname[8] PrincipalName OPTIONAL,
+ realm[9] Realm, -- Correct realm
+ sname[10] PrincipalName, -- Correct name
+ e-text[11] GeneralString OPTIONAL,
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ e-data[12] OCTET STRING OPTIONAL,
+ e-cksum[13] Checksum OPTIONAL,
+ e-typed-data[14] SEQUENCE of ETypedData OPTIONAL
+}
+
+ETypedData ::= SEQUENCE {
+ e-data-type [1] INTEGER,
+ e-data-value [2] OCTET STRING,
+}
+
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_ERROR.
+ctime
+ This field is described above in section 5.4.1.
+cusec
+ This field is described above in section 5.5.2.
+stime
+ This field contains the current time on the server. It is of type
+ KerberosTime.
+susec
+ This field contains the microsecond part of the server's timestamp. Its
+ value ranges from 0 to 999999. It appears along with stime. The two
+ fields are used in conjunction to specify a reasonably accurate
+ timestamp.
+error-code
+ This field contains the error code returned by Kerberos or the server
+ when a request fails. To interpret the value of this field see the list
+ of error codes in section 8. Implementations are encouraged to provide
+ for national language support in the display of error messages.
+crealm, cname, srealm and sname
+ These fields are described above in section 5.3.1.
+e-text
+ This field contains additional text to help explain the error code
+ associated with the failed request (for example, it might include a
+ principal name which was unknown).
+e-data
+ This field contains additional data about the error for use by the
+ application to help it recover from or handle the error. If the
+ errorcode is KDC_ERR_PREAUTH_REQUIRED, then the e-data field will
+ contain an encoding of a sequence of padata fields, each corresponding
+ to an acceptable pre-authentication method and optionally containing
+ data for the method:
+
+ METHOD-DATA ::= SEQUENCE of PA-DATA
+
+ If the error-code is KRB_AP_ERR_METHOD, then the e-data field will
+ contain an encoding of the following sequence:
+
+ METHOD-DATA ::= SEQUENCE {
+ method-type[0] INTEGER,
+ method-data[1] OCTET STRING OPTIONAL
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ }
+
+ method-type will indicate the required alternate method; method-data
+ will contain any required additional information.
+e-cksum
+ This field contains an optional checksum for the KRB-ERROR message. The
+ checksum is calculated over the Kerberos ASN.1 encoding of the
+ KRB-ERROR message with the checksum absent. The checksum is then added
+ to the KRB-ERROR structure and the message is re-encoded. The Checksum
+ should be calculated using the session key from the ticket granting
+ ticket or service ticket, where available. If the error is in response
+ to a TGS or AP request, the checksum should be calculated uing the the
+ session key from the client's ticket. If the error is in response to an
+ AS request, then the checksum should be calulated using the client's
+ secret key ONLY if there has been suitable preauthentication to prove
+ knowledge of the secret key by the client[33]. If a checksum can not be
+ computed because the key to be used is not available, no checksum will
+ be included.
+e-typed-data
+ [This field for discussion, may be deleted from final spec] This field
+ contains optional data that may be used to help the client recover from
+ the indicated error. [This could contain the METHOD-DATA specified
+ since I don't think anyone actually uses it yet. It could also contain
+ the PA-DATA sequence for the preauth required error if we had a clear
+ way to transition to the use of this field from the use of the untype
+ e-data field.] For example, this field may specify the key version of
+ the key used to verify preauthentication:
+
+ e-data-type := 20 -- Key version number
+ e-data-value := Integer -- Key version number used to verify
+ preauthentication
+
+6. Encryption and Checksum Specifications
+
+The Kerberos protocols described in this document are designed to use stream
+encryption ciphers, which can be simulated using commonly available block
+encryption ciphers, such as the Data Encryption Standard, [DES77] in
+conjunction with block chaining and checksum methods [DESM80]. Encryption is
+used to prove the identities of the network entities participating in
+message exchanges. The Key Distribution Center for each realm is trusted by
+all principals registered in that realm to store a secret key in confidence.
+Proof of knowledge of this secret key is used to verify the authenticity of
+a principal.
+
+The KDC uses the principal's secret key (in the AS exchange) or a shared
+session key (in the TGS exchange) to encrypt responses to ticket requests;
+the ability to obtain the secret key or session key implies the knowledge of
+the appropriate keys and the identity of the KDC. The ability of a principal
+to decrypt the KDC response and present a Ticket and a properly formed
+Authenticator (generated with the session key from the KDC response) to a
+service verifies the identity of the principal; likewise the ability of the
+service to extract the session key from the Ticket and prove its knowledge
+thereof in a response verifies the identity of the service.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+The Kerberos protocols generally assume that the encryption used is secure
+from cryptanalysis; however, in some cases, the order of fields in the
+encrypted portions of messages are arranged to minimize the effects of
+poorly chosen keys. It is still important to choose good keys. If keys are
+derived from user-typed passwords, those passwords need to be well chosen to
+make brute force attacks more difficult. Poorly chosen keys still make easy
+targets for intruders.
+
+The following sections specify the encryption and checksum mechanisms
+currently defined for Kerberos. The encodings, chaining, and padding
+requirements for each are described. For encryption methods, it is often
+desirable to place random information (often referred to as a confounder) at
+the start of the message. The requirements for a confounder are specified
+with each encryption mechanism.
+
+Some encryption systems use a block-chaining method to improve the the
+security characteristics of the ciphertext. However, these chaining methods
+often don't provide an integrity check upon decryption. Such systems (such
+as DES in CBC mode) must be augmented with a checksum of the plain-text
+which can be verified at decryption and used to detect any tampering or
+damage. Such checksums should be good at detecting burst errors in the
+input. If any damage is detected, the decryption routine is expected to
+return an error indicating the failure of an integrity check. Each
+encryption type is expected to provide and verify an appropriate checksum.
+The specification of each encryption method sets out its checksum
+requirements.
+
+Finally, where a key is to be derived from a user's password, an algorithm
+for converting the password to a key of the appropriate type is included. It
+is desirable for the string to key function to be one-way, and for the
+mapping to be different in different realms. This is important because users
+who are registered in more than one realm will often use the same password
+in each, and it is desirable that an attacker compromising the Kerberos
+server in one realm not obtain or derive the user's key in another.
+
+For an discussion of the integrity characteristics of the candidate
+encryption and checksum methods considered for Kerberos, the the reader is
+referred to [SG92].
+
+6.1. Encryption Specifications
+
+The following ASN.1 definition describes all encrypted messages. The
+enc-part field which appears in the unencrypted part of messages in section
+5 is a sequence consisting of an encryption type, an optional key version
+number, and the ciphertext.
+
+EncryptedData ::= SEQUENCE {
+ etype[0] INTEGER, -- EncryptionType
+ kvno[1] INTEGER OPTIONAL,
+ cipher[2] OCTET STRING -- ciphertext
+}
+
+
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+etype
+ This field identifies which encryption algorithm was used to encipher
+ the cipher. Detailed specifications for selected encryption types
+ appear later in this section.
+kvno
+ This field contains the version number of the key under which data is
+ encrypted. It is only present in messages encrypted under long lasting
+ keys, such as principals' secret keys.
+cipher
+ This field contains the enciphered text, encoded as an OCTET STRING.
+
+The cipher field is generated by applying the specified encryption algorithm
+to data composed of the message and algorithm-specific inputs. Encryption
+mechanisms defined for use with Kerberos must take sufficient measures to
+guarantee the integrity of the plaintext, and we recommend they also take
+measures to protect against precomputed dictionary attacks. If the
+encryption algorithm is not itself capable of doing so, the protections can
+often be enhanced by adding a checksum and a confounder.
+
+The suggested format for the data to be encrypted includes a confounder, a
+checksum, the encoded plaintext, and any necessary padding. The msg-seq
+field contains the part of the protocol message described in section 5 which
+is to be encrypted. The confounder, checksum, and padding are all untagged
+and untyped, and their length is exactly sufficient to hold the appropriate
+item. The type and length is implicit and specified by the particular
+encryption type being used (etype). The format for the data to be encrypted
+is described in the following diagram:
+
+ +-----------+----------+-------------+-----+
+ |confounder | check | msg-seq | pad |
+ +-----------+----------+-------------+-----+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+CipherText ::= ENCRYPTED SEQUENCE {
+ confounder[0] UNTAGGED[35] OCTET STRING(conf_length) OPTIONAL,
+ check[1] UNTAGGED OCTET STRING(checksum_length) OPTIONAL,
+ msg-seq[2] MsgSequence,
+ pad UNTAGGED OCTET STRING(pad_length) OPTIONAL
+}
+
+One generates a random confounder of the appropriate length, placing it in
+confounder; zeroes out check; calculates the appropriate checksum over
+confounder, check, and msg-seq, placing the result in check; adds the
+necessary padding; then encrypts using the specified encryption type and the
+appropriate key.
+
+Unless otherwise specified, a definition of an encryption algorithm that
+specifies a checksum, a length for the confounder field, or an octet
+boundary for padding uses this ciphertext format[36]. Those fields which are
+not specified will be omitted.
+
+In the interest of allowing all implementations using a particular
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+encryption type to communicate with all others using that type, the
+specification of an encryption type defines any checksum that is needed as
+part of the encryption process. If an alternative checksum is to be used, a
+new encryption type must be defined.
+
+Some cryptosystems require additional information beyond the key and the
+data to be encrypted. For example, DES, when used in cipher-block-chaining
+mode, requires an initialization vector. If required, the description for
+each encryption type must specify the source of such additional information.
+6.2. Encryption Keys
+
+The sequence below shows the encoding of an encryption key:
+
+ EncryptionKey ::= SEQUENCE {
+ keytype[0] INTEGER,
+ keyvalue[1] OCTET STRING
+ }
+
+keytype
+ This field specifies the type of encryption key that follows in the
+ keyvalue field. It will almost always correspond to the encryption
+ algorithm used to generate the EncryptedData, though more than one
+ algorithm may use the same type of key (the mapping is many to one).
+ This might happen, for example, if the encryption algorithm uses an
+ alternate checksum algorithm for an integrity check, or a different
+ chaining mechanism.
+keyvalue
+ This field contains the key itself, encoded as an octet string.
+
+All negative values for the encryption key type are reserved for local use.
+All non-negative values are reserved for officially assigned type fields and
+interpreta- tions.
+
+6.3. Encryption Systems
+
+6.3.1. The NULL Encryption System (null)
+
+If no encryption is in use, the encryption system is said to be the NULL
+encryption system. In the NULL encryption system there is no checksum,
+confounder or padding. The ciphertext is simply the plaintext. The NULL Key
+is used by the null encryption system and is zero octets in length, with
+keytype zero (0).
+
+6.3.2. DES in CBC mode with a CRC-32 checksum (des-cbc-crc)
+
+The des-cbc-crc encryption mode encrypts information under the Data
+Encryption Standard [DES77] using the cipher block chaining mode [DESM80]. A
+CRC-32 checksum (described in ISO 3309 [ISO3309]) is applied to the
+confounder and message sequence (msg-seq) and placed in the cksum field. DES
+blocks are 8 bytes. As a result, the data to be encrypted (the concatenation
+of confounder, checksum, and message) must be padded to an 8 byte boundary
+before encryption. The details of the encryption of this data are identical
+to those for the des-cbc-md5 encryption mode.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+Note that, since the CRC-32 checksum is not collision-proof, an attacker
+could use a probabilistic chosen-plaintext attack to generate a valid
+message even if a confounder is used [SG92]. The use of collision-proof
+checksums is recommended for environments where such attacks represent a
+significant threat. The use of the CRC-32 as the checksum for ticket or
+authenticator is no longer mandated as an interoperability requirement for
+Kerberos Version 5 Specification 1 (See section 9.1 for specific details).
+
+6.3.3. DES in CBC mode with an MD4 checksum (des-cbc-md4)
+
+The des-cbc-md4 encryption mode encrypts information under the Data
+Encryption Standard [DES77] using the cipher block chaining mode [DESM80].
+An MD4 checksum (described in [MD492]) is applied to the confounder and
+message sequence (msg-seq) and placed in the cksum field. DES blocks are 8
+bytes. As a result, the data to be encrypted (the concatenation of
+confounder, checksum, and message) must be padded to an 8 byte boundary
+before encryption. The details of the encryption of this data are identical
+to those for the des-cbc-md5 encryption mode.
+
+6.3.4. DES in CBC mode with an MD5 checksum (des-cbc-md5)
+
+The des-cbc-md5 encryption mode encrypts information under the Data
+Encryption Standard [DES77] using the cipher block chaining mode [DESM80].
+An MD5 checksum (described in [MD5-92].) is applied to the confounder and
+message sequence (msg-seq) and placed in the cksum field. DES blocks are 8
+bytes. As a result, the data to be encrypted (the concatenation of
+confounder, checksum, and message) must be padded to an 8 byte boundary
+before encryption.
+
+Plaintext and DES ciphtertext are encoded as blocks of 8 octets which are
+concatenated to make the 64-bit inputs for the DES algorithms. The first
+octet supplies the 8 most significant bits (with the octet's MSbit used as
+the DES input block's MSbit, etc.), the second octet the next 8 bits, ...,
+and the eighth octet supplies the 8 least significant bits.
+
+Encryption under DES using cipher block chaining requires an additional
+input in the form of an initialization vector. Unless otherwise specified,
+zero should be used as the initialization vector. Kerberos' use of DES
+requires an 8 octet confounder.
+
+The DES specifications identify some 'weak' and 'semi-weak' keys; those keys
+shall not be used for encrypting messages for use in Kerberos. Additionally,
+because of the way that keys are derived for the encryption of checksums,
+keys shall not be used that yield 'weak' or 'semi-weak' keys when
+eXclusive-ORed with the hexadecimal constant F0F0F0F0F0F0F0F0.
+
+A DES key is 8 octets of data, with keytype one (1). This consists of 56
+bits of key, and 8 parity bits (one per octet). The key is encoded as a
+series of 8 octets written in MSB-first order. The bits within the key are
+also encoded in MSB order. For example, if the encryption key is
+(B1,B2,...,B7,P1,B8,...,B14,P2,B15,...,B49,P7,B50,...,B56,P8) where
+B1,B2,...,B56 are the key bits in MSB order, and P1,P2,...,P8 are the parity
+bits, the first octet of the key would be B1,B2,...,B7,P1 (with B1 as the
+MSbit). [See the FIPS 81 introduction for reference.]
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+String to key transformation
+
+To generate a DES key from a text string (password), the text string
+normally must have the realm and each component of the principal's name
+appended[37], then padded with ASCII nulls to an 8 byte boundary. This
+string is then fan-folded and eXclusive-ORed with itself to form an 8 byte
+DES key. The parity is corrected on the key, and it is used to generate a
+DES CBC checksum on the initial string (with the realm and name appended).
+Next, parity is corrected on the CBC checksum. If the result matches a
+'weak' or 'semi-weak' key as described in the DES specification, it is
+eXclusive-ORed with the constant 00000000000000F0. Finally, the result is
+returned as the key. Pseudocode follows:
+
+ string_to_key(string,realm,name) {
+ odd = 1;
+ s = string + realm;
+ for(each component in name) {
+ s = s + component;
+ }
+ tempkey = NULL;
+ pad(s); /* with nulls to 8 byte boundary */
+ for(8byteblock in s) {
+ if(odd == 0) {
+ odd = 1;
+ reverse(8byteblock)
+ }
+ else odd = 0;
+ tempkey = tempkey XOR 8byteblock;
+ }
+ fixparity(tempkey);
+ key = DES-CBC-check(s,tempkey);
+ fixparity(key);
+ if(is_weak_key_key(key))
+ key = key XOR 0xF0;
+ return(key);
+ }
+
+6.3.5. Triple DES EDE in outer CBC mode with an SHA1 check-sum
+(des3-cbc-sha1)
+
+The des3-cbc-sha1 encryption encodes information using three Data Encryption
+Standard transformations with three DES keys. The first key is used to
+perform a DES ECB encryption on an eight-octet data block using the first
+DES key, followed by a DES ECB decryption of the result using the second DES
+key, and a DES ECB encryption of the result using the third DES key. Because
+DES blocks are 8 bytes, the data to be encrypted (the concatenation of
+confounder, checksum, and message) must first be padded to an 8 byte
+boundary before encryption. To support the outer CBC mode, the input is
+padded to an eight-octet boundary. The first 8 octets of the data to be
+encrypted (the confounder) is exclusive-ored with an initialization vector
+of zero and then ECB encrypted using triple DES as described above.
+Subsequent blocks of 8 octets are exclusive-ored with the ciphertext
+produced by the encryption on the previous block before ECB encryption.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+An HMAC-SHA1 checksum (described in [KBC96].) is applied to the confounder
+and message sequence (msg-seq) and placed in the cksum field.
+
+Plaintext are encoded as blocks of 8 octets which are concatenated to make
+the 64-bit inputs for the DES algorithms. The first octet supplies the 8
+most significant bits (with the octet's MSbit used as the DES input block's
+MSbit, etc.), the second octet the next 8 bits, ..., and the eighth octet
+supplies the 8 least significant bits.
+
+Encryption under Triple DES using cipher block chaining requires an
+additional input in the form of an initialization vector. Unless otherwise
+specified, zero should be used as the initialization vector. Kerberos' use
+of DES requires an 8 octet confounder.
+
+The DES specifications identify some 'weak' and 'semi-weak' keys; those keys
+shall not be used for encrypting messages for use in Kerberos. Additionally,
+because of the way that keys are derived for the encryption of checksums,
+keys shall not be used that yield 'weak' or 'semi-weak' keys when
+eXclusive-ORed with the hexadecimal constant F0F0F0F0F0F0F0F0.
+
+A Triple DES key is 24 octets of data, with keytype seven (7). This consists
+of 168 bits of key, and 24 parity bits (one per octet). The key is encoded
+as a series of 24 octets written in MSB-first order, with the first 8 octets
+treated as the first DES key, the second 8 octets as the second key, and the
+third 8 octets the third DES key. The bits within each key are also encoded
+in MSB order. For example, if the encryption key is
+(B1,B2,...,B7,P1,B8,...,B14,P2,B15,...,B49,P7,B50,...,B56,P8) where
+B1,B2,...,B56 are the key bits in MSB order, and P1,P2,...,P8 are the parity
+bits, the first octet of the key would be B1,B2,...,B7,P1 (with B1 as the
+MSbit). [See the FIPS 81 introduction for reference.]
+
+Key derivation for specified operations (Horowitz)
+
+[Discussion is needed for this section, especially since it does not simply
+derive key generation, but also specifies encryption using triple DES in a
+manner that is different than the basic template that was specified for
+single DES and similar systems]
+
+In the Kerberos protocol cryptographic keys are used in a number of places.
+In order to minimize the effect of compromising a key, it is desirable to
+use a different key in each of these places. Key derivation [Horowitz96] can
+be used to construct different keys for each operation from the keys
+transported on the network or derived from the password specified by the
+user.
+
+For each place where a key is used in Kerberos, a ``key usage'' is specified
+for that purpose. The key, key usage, and encryption/checksum type together
+describe the transformation from plaintext to ciphertext. For backwards
+compatibility, this key derivation is only specified here for encryption
+methods based on triple DES. Encryption methods specified for use by
+Kerberos in the future should specify the key derivation function to be
+used.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+Kerberos requires that the ciphertext component of EncryptedData be
+tamper-resistant as well as confidential. This implies encryption and
+integrity functions, which must each use their own separate keys. So, for
+each key usage, two keys must be generated, one for encryption (Ke), and one
+for integrity (Ki):
+
+ Ke = DK(protocol key, key usage | 0xAA)
+ Ki = DK(protocol key, key usage | 0x55)
+
+where the key usage is represented as a 32 bit integer in network byte
+order. The ciphertest must be generated from the plaintext as follows:
+
+ ciphertext = E(Ke, confounder | length | plaintext | padding) |
+ H(Ki, confounder | length | plaintext | padding)
+
+The confounder and padding are specific to the encryption algorithm E.
+
+When generating a checksum only, there is no need for a confounder or
+padding. Again, a new key (Kc) must be used. Checksums must be generated
+from the plaintext as follows:
+
+ Kc = DK(protocol key, key usage | 0x99)
+ MAC = H(Kc, length | plaintext)
+
+
+Note that each enctype is described by an encryption algorithm E and a keyed
+hash algorithm H, and each checksum type is described by a keyed hash
+algorithm H. HMAC, with an appropriate hash, is recommended for use as H.
+
+The key usage value will be taken from the following list of places where
+keys are used in the Kerberos protocol, with key usage values and Kerberos
+specification section numbers:
+
+ 1. AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
+ client key (section 5.4.1)
+ 2. AS-REP Ticket and TGS-REP Ticket (includes tgs session key or
+ application session key), encrypted with the service key
+ (section 5.4.2)
+ 3. AS-REP encrypted part (includes tgs session key or application
+ session key), encrypted with the client key (section 5.4.2)
+
+ 4. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ session key (section 5.4.1)
+ 5. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ authenticator subkey (section 5.4.1)
+ 6. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
+ with the tgs session key (sections 5.3.2, 5.4.1)
+ 7. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes tgs
+ authenticator subkey), encrypted with the tgs session key
+ (section 5.3.2)
+ 8. TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs session key (section 5.4.2)
+ 9. TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs authenticator subkey (section 5.4.2)
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+ 10. AP-REQ Authenticator cksum, keyed with the application session
+ key (section 5.3.2)
+ 11. AP-REQ Authenticator (includes application authenticator
+ subkey), encrypted with the application session key (section
+ 5.3.2)
+ 12. AP-REP encrypted part (includes application session subkey),
+ encrypted with the application session key (section 5.5.2)
+
+ 13. KRB-PRIV encrypted part, encrypted with a key chosen by the
+ application (section 5.7.1)
+ 14. KRB-CRED encrypted part, encrypted with a key chosen by the
+ application (section 5.6.1)
+ 15. KRB-SAFE cksum, keyed with a key chosen by the application
+ (section 5.8.1)
+
+ 16. Data which is defined in some specification outside of
+ Kerberos to be encrypted using Kerberos encryption type.
+ 17. Data which is defined in some specification outside of
+ Kerberos to be checksummed using Kerberos checksum type.
+
+ 18. KRB-ERROR checksum (e-cksum in section 5.9.1)
+ 19. AD-KDCIssued checksum (ad-checksum in appendix B.1)
+ 20. Checksum for Mandatory Ticket Extensions (appendix B.6)
+ 21. Checksum in Authorization Data in Ticket Extensions (appendix B.7)
+
+String to key transformation
+
+To generate a DES key from a text string (password), the text string
+normally must have the realm and each component of the principal's name
+appended[38].
+
+The input string (with any salt data appended to it) is n-folded into a 24
+octet (192 bit) string. To n-fold a number X, replicate the input value to a
+length that is the least common multiple of n and the length of X. Before
+each repetition, the input X is rotated to the right by 13 bit positions.
+The successive n-bit chunks are added together using 1's-complement addition
+(addition with end-around carry) to yield a n-bit result. (This
+transformation was proposed by Richard Basch)
+
+Each successive set of 8 octets is taken as a DES key, and its parity is
+adjusted in the same manner as previously described. If any of the three
+sets of 8 octets match a 'weak' or 'semi-weak key as described in the DES
+specification, that chunk is eXclusive-ORed with the hexadecimal constant
+00000000000000F0. The resulting DES keys are then used in sequence to
+perform a Triple-DES CBC encryption of the n-folded input string (appended
+with any salt data), using a zero initial vector. Parity, weak, and
+semi-weak keys are once again corrected and the result is returned as the 24
+octet key.
+
+Pseudocode follows:
+
+ string_to_key(string,realm,name) {
+ s = string + realm;
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ for(each component in name) {
+ s = s + component;
+ }
+ tkey[24] = fold(s);
+ fixparity(tkey);
+ if(isweak(tkey[0-7])) tkey[0-7] = tkey[0-7] XOR 0xF0;
+ if(isweak(tkey[8-15])) tkey[8-15] = tkey[8-15] XOR 0xF0;
+ if(is_weak(tkey[16-23])) tkey[16-23] = tkey[16-23] XOR 0xF0;
+ key[24] = 3DES-CBC(data=fold(s),key=tkey,iv=0);
+ fixparity(key);
+ if(is_weak(key[0-7])) key[0-7] = key[0-7] XOR 0xF0;
+ if(is_weak(key[8-15])) key[8-15] = key[8-15] XOR 0xF0;
+ if(is_weak(key[16-23])) key[16-23] = key[16-23] XOR 0xF0;
+ return(key);
+ }
+
+6.4. Checksums
+
+The following is the ASN.1 definition used for a checksum:
+
+ Checksum ::= SEQUENCE {
+ cksumtype[0] INTEGER,
+ checksum[1] OCTET STRING
+ }
+
+cksumtype
+ This field indicates the algorithm used to generate the accompanying
+ checksum.
+checksum
+ This field contains the checksum itself, encoded as an octet string.
+
+Detailed specification of selected checksum types appear later in this
+section. Negative values for the checksum type are reserved for local use.
+All non-negative values are reserved for officially assigned type fields and
+interpretations.
+
+Checksums used by Kerberos can be classified by two properties: whether they
+are collision-proof, and whether they are keyed. It is infeasible to find
+two plaintexts which generate the same checksum value for a collision-proof
+checksum. A key is required to perturb or initialize the algorithm in a
+keyed checksum. To prevent message-stream modification by an active
+attacker, unkeyed checksums should only be used when the checksum and
+message will be subsequently encrypted (e.g. the checksums defined as part
+of the encryption algorithms covered earlier in this section).
+
+Collision-proof checksums can be made tamper-proof if the checksum value is
+encrypted before inclusion in a message. In such cases, the composition of
+the checksum and the encryption algorithm must be considered a separate
+checksum algorithm (e.g. RSA-MD5 encrypted using DES is a new checksum
+algorithm of type RSA-MD5-DES). For most keyed checksums, as well as for the
+encrypted forms of unkeyed collision-proof checksums, Kerberos prepends a
+confounder before the checksum is calculated.
+
+6.4.1. The CRC-32 Checksum (crc32)
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+The CRC-32 checksum calculates a checksum based on a cyclic redundancy check
+as described in ISO 3309 [ISO3309]. The resulting checksum is four (4)
+octets in length. The CRC-32 is neither keyed nor collision-proof. The use
+of this checksum is not recommended. An attacker using a probabilistic
+chosen-plaintext attack as described in [SG92] might be able to generate an
+alternative message that satisfies the checksum. The use of collision-proof
+checksums is recommended for environments where such attacks represent a
+significant threat.
+
+6.4.2. The RSA MD4 Checksum (rsa-md4)
+
+The RSA-MD4 checksum calculates a checksum using the RSA MD4 algorithm
+[MD4-92]. The algorithm takes as input an input message of arbitrary length
+and produces as output a 128-bit (16 octet) checksum. RSA-MD4 is believed to
+be collision-proof.
+
+6.4.3. RSA MD4 Cryptographic Checksum Using DES (rsa-md4-des)
+
+The RSA-MD4-DES checksum calculates a keyed collision-proof checksum by
+prepending an 8 octet confounder before the text, applying the RSA MD4
+checksum algorithm, and encrypting the confounder and the checksum using DES
+in cipher-block-chaining (CBC) mode using a variant of the key, where the
+variant is computed by eXclusive-ORing the key with the constant
+F0F0F0F0F0F0F0F0[39]. The initialization vector should be zero. The
+resulting checksum is 24 octets long (8 octets of which are redundant). This
+checksum is tamper-proof and believed to be collision-proof.
+
+The DES specifications identify some weak keys' and 'semi-weak keys'; those
+keys shall not be used for generating RSA-MD4 checksums for use in Kerberos.
+
+The format for the checksum is described in the follow- ing diagram:
+
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+| des-cbc(confounder + rsa-md4(confounder+msg),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+rsa-md4-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(16)
+}
+
+6.4.4. The RSA MD5 Checksum (rsa-md5)
+
+The RSA-MD5 checksum calculates a checksum using the RSA MD5 algorithm.
+[MD5-92]. The algorithm takes as input an input message of arbitrary length
+and produces as output a 128-bit (16 octet) checksum. RSA-MD5 is believed to
+be collision-proof.
+
+6.4.5. RSA MD5 Cryptographic Checksum Using DES (rsa-md5-des)
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+The RSA-MD5-DES checksum calculates a keyed collision-proof checksum by
+prepending an 8 octet confounder before the text, applying the RSA MD5
+checksum algorithm, and encrypting the confounder and the checksum using DES
+in cipher-block-chaining (CBC) mode using a variant of the key, where the
+variant is computed by eXclusive-ORing the key with the hexadecimal constant
+F0F0F0F0F0F0F0F0. The initialization vector should be zero. The resulting
+checksum is 24 octets long (8 octets of which are redundant). This checksum
+is tamper-proof and believed to be collision-proof.
+
+The DES specifications identify some 'weak keys' and 'semi-weak keys'; those
+keys shall not be used for encrypting RSA-MD5 checksums for use in Kerberos.
+
+The format for the checksum is described in the following diagram:
+
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+| des-cbc(confounder + rsa-md5(confounder+msg),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+rsa-md5-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(16)
+}
+
+6.4.6. DES cipher-block chained checksum (des-mac)
+
+The DES-MAC checksum is computed by prepending an 8 octet confounder to the
+plaintext, performing a DES CBC-mode encryption on the result using the key
+and an initialization vector of zero, taking the last block of the
+ciphertext, prepending the same confounder and encrypting the pair using DES
+in cipher-block-chaining (CBC) mode using a a variant of the key, where the
+variant is computed by eXclusive-ORing the key with the hexadecimal constant
+F0F0F0F0F0F0F0F0. The initialization vector should be zero. The resulting
+checksum is 128 bits (16 octets) long, 64 bits of which are redundant. This
+checksum is tamper-proof and collision-proof.
+
+The format for the checksum is described in the following diagram:
+
++--+--+--+--+--+--+--+--+-----+-----+-----+-----+-----+-----+-----+-----+
+| des-cbc(confounder + des-mac(conf+msg,iv=0,key),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+-----+-----+-----+-----+-----+-----+-----+-----+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+des-mac-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(8)
+}
+
+The DES specifications identify some 'weak' and 'semi-weak' keys; those keys
+shall not be used for generating DES-MAC checksums for use in Kerberos, nor
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+shall a key be used whose variant is 'weak' or 'semi-weak'.
+
+6.4.7. RSA MD4 Cryptographic Checksum Using DES alternative (rsa-md4-des-k)
+
+The RSA-MD4-DES-K checksum calculates a keyed collision-proof checksum by
+applying the RSA MD4 checksum algorithm and encrypting the results using DES
+in cipher-block-chaining (CBC) mode using a DES key as both key and
+initialization vector. The resulting checksum is 16 octets long. This
+checksum is tamper-proof and believed to be collision-proof. Note that this
+checksum type is the old method for encoding the RSA-MD4-DES checksum and it
+is no longer recommended.
+
+6.4.8. DES cipher-block chained checksum alternative (des-mac-k)
+
+The DES-MAC-K checksum is computed by performing a DES CBC-mode encryption
+of the plaintext, and using the last block of the ciphertext as the checksum
+value. It is keyed with an encryption key and an initialization vector; any
+uses which do not specify an additional initialization vector will use the
+key as both key and initialization vector. The resulting checksum is 64 bits
+(8 octets) long. This checksum is tamper-proof and collision-proof. Note
+that this checksum type is the old method for encoding the DES-MAC checksum
+and it is no longer recommended. The DES specifications identify some 'weak
+keys' and 'semi-weak keys'; those keys shall not be used for generating
+DES-MAC checksums for use in Kerberos.
+
+7. Naming Constraints
+
+7.1. Realm Names
+
+Although realm names are encoded as GeneralStrings and although a realm can
+technically select any name it chooses, interoperability across realm
+boundaries requires agreement on how realm names are to be assigned, and
+what information they imply.
+
+To enforce these conventions, each realm must conform to the conventions
+itself, and it must require that any realms with which inter-realm keys are
+shared also conform to the conventions and require the same from its
+neighbors.
+
+Kerberos realm names are case sensitive. Realm names that differ only in the
+case of the characters are not equivalent. There are presently four styles
+of realm names: domain, X500, other, and reserved. Examples of each style
+follow:
+
+ domain: ATHENA.MIT.EDU (example)
+ X500: C=US/O=OSF (example)
+ other: NAMETYPE:rest/of.name=without-restrictions (example)
+ reserved: reserved, but will not conflict with above
+
+Domain names must look like domain names: they consist of components
+separated by periods (.) and they contain neither colons (:) nor slashes
+(/). Domain names must be converted to upper case when used as realm names.
+
+X.500 names contain an equal (=) and cannot contain a colon (:) before the
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+equal. The realm names for X.500 names will be string representations of the
+names with components separated by slashes. Leading and trailing slashes
+will not be included.
+
+Names that fall into the other category must begin with a prefix that
+contains no equal (=) or period (.) and the prefix must be followed by a
+colon (:) and the rest of the name. All prefixes must be assigned before
+they may be used. Presently none are assigned.
+
+The reserved category includes strings which do not fall into the first
+three categories. All names in this category are reserved. It is unlikely
+that names will be assigned to this category unless there is a very strong
+argument for not using the 'other' category.
+
+These rules guarantee that there will be no conflicts between the various
+name styles. The following additional constraints apply to the assignment of
+realm names in the domain and X.500 categories: the name of a realm for the
+domain or X.500 formats must either be used by the organization owning (to
+whom it was assigned) an Internet domain name or X.500 name, or in the case
+that no such names are registered, authority to use a realm name may be
+derived from the authority of the parent realm. For example, if there is no
+domain name for E40.MIT.EDU, then the administrator of the MIT.EDU realm can
+authorize the creation of a realm with that name.
+
+This is acceptable because the organization to which the parent is assigned
+is presumably the organization authorized to assign names to its children in
+the X.500 and domain name systems as well. If the parent assigns a realm
+name without also registering it in the domain name or X.500 hierarchy, it
+is the parent's responsibility to make sure that there will not in the
+future exists a name identical to the realm name of the child unless it is
+assigned to the same entity as the realm name.
+
+7.2. Principal Names
+
+As was the case for realm names, conventions are needed to ensure that all
+agree on what information is implied by a principal name. The name-type
+field that is part of the principal name indicates the kind of information
+implied by the name. The name-type should be treated as a hint. Ignoring the
+name type, no two names can be the same (i.e. at least one of the
+components, or the realm, must be different). The following name types are
+defined:
+
+ name-type value meaning
+
+ NT-UNKNOWN 0 Name type not known
+ NT-PRINCIPAL 1 General principal name (e.g. username, or DCE principal)
+ NT-SRV-INST 2 Service and other unique instance (krbtgt)
+ NT-SRV-HST 3 Service with host name as instance (telnet, rcommands)
+ NT-SRV-XHST 4 Service with slash-separated host name components
+ NT-UID 5 Unique ID
+ NT-X500-PRINCIPAL 6 Encoded X.509 Distingished name [RFC 1779]
+
+When a name implies no information other than its uniqueness at a particular
+time the name type PRINCIPAL should be used. The principal name type should
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+be used for users, and it might also be used for a unique server. If the
+name is a unique machine generated ID that is guaranteed never to be
+reassigned then the name type of UID should be used (note that it is
+generally a bad idea to reassign names of any type since stale entries might
+remain in access control lists).
+
+If the first component of a name identifies a service and the remaining
+components identify an instance of the service in a server specified manner,
+then the name type of SRV-INST should be used. An example of this name type
+is the Kerberos ticket-granting service whose name has a first component of
+krbtgt and a second component identifying the realm for which the ticket is
+valid.
+
+If instance is a single component following the service name and the
+instance identifies the host on which the server is running, then the name
+type SRV-HST should be used. This type is typically used for Internet
+services such as telnet and the Berkeley R commands. If the separate
+components of the host name appear as successive components following the
+name of the service, then the name type SRV-XHST should be used. This type
+might be used to identify servers on hosts with X.500 names where the slash
+(/) might otherwise be ambiguous.
+
+A name type of NT-X500-PRINCIPAL should be used when a name from an X.509
+certificiate is translated into a Kerberos name. The encoding of the X.509
+name as a Kerberos principal shall conform to the encoding rules specified
+in RFC 1779.
+
+A name type of UNKNOWN should be used when the form of the name is not
+known. When comparing names, a name of type UNKNOWN will match principals
+authenticated with names of any type. A principal authenticated with a name
+of type UNKNOWN, however, will only match other names of type UNKNOWN.
+
+Names of any type with an initial component of 'krbtgt' are reserved for the
+Kerberos ticket granting service. See section 8.2.3 for the form of such
+names.
+
+7.2.1. Name of server principals
+
+The principal identifier for a server on a host will generally be composed
+of two parts: (1) the realm of the KDC with which the server is registered,
+and (2) a two-component name of type NT-SRV-HST if the host name is an
+Internet domain name or a multi-component name of type NT-SRV-XHST if the
+name of the host is of a form such as X.500 that allows slash (/)
+separators. The first component of the two- or multi-component name will
+identify the service and the latter components will identify the host. Where
+the name of the host is not case sensitive (for example, with Internet
+domain names) the name of the host must be lower case. If specified by the
+application protocol for services such as telnet and the Berkeley R commands
+which run with system privileges, the first component may be the string
+'host' instead of a service specific identifier. When a host has an official
+name and one or more aliases, the official name of the host must be used
+when constructing the name of the server principal.
+
+8. Constants and other defined values
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+8.1. Host address types
+
+All negative values for the host address type are reserved for local use.
+All non-negative values are reserved for officially assigned type fields and
+interpretations.
+
+The values of the types for the following addresses are chosen to match the
+defined address family constants in the Berkeley Standard Distributions of
+Unix. They can be found in with symbolic names AF_xxx (where xxx is an
+abbreviation of the address family name).
+
+Internet (IPv4) Addresses
+
+Internet (IPv4) addresses are 32-bit (4-octet) quantities, encoded in MSB
+order. The type of IPv4 addresses is two (2).
+
+Internet (IPv6) Addresses
+
+IPv6 addresses are 128-bit (16-octet) quantities, encoded in MSB order. The
+type of IPv6 addresses is twenty-four (24). [RFC1883] [RFC1884]. The
+following addresses (see [RFC1884]) MUST not appear in any Kerberos packet:
+
+ * the Unspecified Address
+ * the Loopback Address
+ * Link-Local addresses
+
+IPv4-mapped IPv6 addresses MUST be represented as addresses of type 2.
+
+CHAOSnet addresses
+
+CHAOSnet addresses are 16-bit (2-octet) quantities, encoded in MSB order.
+The type of CHAOSnet addresses is five (5).
+
+ISO addresses
+
+ISO addresses are variable-length. The type of ISO addresses is seven (7).
+
+Xerox Network Services (XNS) addresses
+
+XNS addresses are 48-bit (6-octet) quantities, encoded in MSB order. The
+type of XNS addresses is six (6).
+
+AppleTalk Datagram Delivery Protocol (DDP) addresses
+
+AppleTalk DDP addresses consist of an 8-bit node number and a 16-bit network
+number. The first octet of the address is the node number; the remaining two
+octets encode the network number in MSB order. The type of AppleTalk DDP
+addresses is sixteen (16).
+
+DECnet Phase IV addresses
+
+DECnet Phase IV addresses are 16-bit addresses, encoded in LSB order. The
+type of DECnet Phase IV addresses is twelve (12).
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+8.2. KDC messages
+
+8.2.1. UDP/IP transport
+
+When contacting a Kerberos server (KDC) for a KRB_KDC_REQ request using UDP
+IP transport, the client shall send a UDP datagram containing only an
+encoding of the request to port 88 (decimal) at the KDC's IP address; the
+KDC will respond with a reply datagram containing only an encoding of the
+reply message (either a KRB_ERROR or a KRB_KDC_REP) to the sending port at
+the sender's IP address. Kerberos servers supporting IP transport must
+accept UDP requests on port 88 (decimal). The response to a request made
+through UDP/IP transport must also use UDP/IP transport.
+
+8.2.2. TCP/IP transport
+
+Kerberos servers (KDC's) must accept TCP requests on port 88 (decimal). When
+the KRB_KDC_REQ message is sent to the KDC over a TCP stream, a new
+connection will be established for each authentication exchange (request and
+response). The KRB_KDC_REP or KRB_ERROR message will be returned to the
+client on the same TCP stream that was established for the request. The
+connection will be broken after the reply has been received (or upon
+time-out). Care must be taken in managing TCP/IP connections with the KDC to
+prevent denial of service attacks based on the number of TCP/IP connections
+with the KDC that remain open. If multiple exchanges with the KDC are needed
+for certain forms of preauthentication, multiple TCP connections will be
+required. The response to a request made through TCP/IP transport must also
+use TCP/IP transport.
+
+The first four octets of the TCP stream used to transmit the request request
+will encode in network byte order the length of the request (KRB_KDC_REQ),
+and the length will be followed by the request itself. The response will
+similarly be preceeded by a 4 octet encoding in network byte order of the
+length of the KRB_KDC_REP or the KRB_ERROR message and will be followed by
+the KRB_KDC_REP or the KRB_ERROR response.
+
+8.2.3. OSI transport
+
+During authentication of an OSI client to an OSI server, the mutual
+authentication of an OSI server to an OSI client, the transfer of
+credentials from an OSI client to an OSI server, or during exchange of
+private or integrity checked messages, Kerberos protocol messages may be
+treated as opaque objects and the type of the authentication mechanism will
+be:
+
+OBJECT IDENTIFIER ::= {iso (1), org(3), dod(6),internet(1), security(5),kerberosv5(2)}
+
+Depending on the situation, the opaque object will be an authentication
+header (KRB_AP_REQ), an authentication reply (KRB_AP_REP), a safe message
+(KRB_SAFE), a private message (KRB_PRIV), or a credentials message
+(KRB_CRED). The opaque data contains an application code as specified in the
+ASN.1 description for each message. The application code may be used by
+Kerberos to determine the message type.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+8.2.3. Name of the TGS
+
+The principal identifier of the ticket-granting service shall be composed of
+three parts: (1) the realm of the KDC issuing the TGS ticket (2) a two-part
+name of type NT-SRV-INST, with the first part "krbtgt" and the second part
+the name of the realm which will accept the ticket-granting ticket. For
+example, a ticket-granting ticket issued by the ATHENA.MIT.EDU realm to be
+used to get tickets from the ATHENA.MIT.EDU KDC has a principal identifier
+of "ATHENA.MIT.EDU" (realm), ("krbtgt", "ATHENA.MIT.EDU") (name). A
+ticket-granting ticket issued by the ATHENA.MIT.EDU realm to be used to get
+tickets from the MIT.EDU realm has a principal identifier of
+"ATHENA.MIT.EDU" (realm), ("krbtgt", "MIT.EDU") (name).
+
+8.3. Protocol constants and associated values
+
+The following tables list constants used in the protocol and defines their
+meanings.
+
+Encryption type etype value block size minimum pad size confounder size
+NULL 0 1 0 0
+des-cbc-crc 1 8 4 8
+des-cbc-md4 2 8 0 8
+des-cbc-md5 3 8 0 8
+ 4
+des3-cbc-md5 5 8 0 8
+ 6
+des3-cbc-sha1 7 8 0 8
+sign-dsa-generate 8 (pkinit)
+encrypt-rsa-priv 9 (pkinit)
+encrypt-rsa-pub 10 (pkinit)
+rsa-pub-md5 11 (pkinit)
+rsa-pub-sha1 12 (pkinit)
+ENCTYPE_PK_CROSS 48 (reserved for pkcross)
+ 0x8003
+
+Checksum type sumtype value checksum size
+CRC32 1 4
+rsa-md4 2 16
+rsa-md4-des 3 24
+des-mac 4 16
+des-mac-k 5 8
+rsa-md4-des-k 6 16
+rsa-md5 7 16
+rsa-md5-des 8 24
+rsa-md5-des3 9 24
+hmac-sha1-des3 10 20 (I had this as 10, is it 12)
+
+padata type padata-type value
+
+PA-TGS-REQ 1
+PA-ENC-TIMESTAMP 2
+PA-PW-SALT 3
+ 4
+PA-ENC-UNIX-TIME 5
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+PA-SANDIA-SECUREID 6
+PA-SESAME 7
+PA-OSF-DCE 8
+PA-CYBERSAFE-SECUREID 9
+PA-AFS3-SALT 10
+PA-ETYPE-INFO 11
+SAM-CHALLENGE 12 (sam/otp)
+SAM-RESPONSE 13 (sam/otp)
+PA-PK-AS-REQ 14 (pkinit)
+PA-PK-AS-REP 15 (pkinit)
+PA-PK-AS-SIGN 16 (pkinit)
+PA-PK-KEY-REQ 17 (pkinit)
+PA-PK-KEY-REP 18 (pkinit)
+PA-USE-SPECIFIED-KVNO 20
+
+authorization data type ad-type value
+AD-KDC-ISSUED 1
+AD-INTENDED-FOR-SERVER 2
+AD-INTENDED-FOR-APPLICATION-CLASS 3
+AD-IF-RELEVANT 4
+AD-OR 5
+AD-MANDATORY-TICKET-EXTENSIONS 6
+AD-IN-TICKET-EXTENSIONS 7
+reserved values 8-63
+OSF-DCE 64
+SESAME 65
+
+Ticket Extension Types
+
+TE-TYPE-NULL 0 Null ticket extension
+TE-TYPE-EXTERNAL-ADATA 1 Integrity protected authorization data
+ 2 TE-TYPE-PKCROSS-KDC (I have reservations)
+TE-TYPE-PKCROSS-CLIENT 3 PKCROSS cross realm key ticket
+TE-TYPE-CYBERSAFE-EXT 4 Assigned to CyberSafe Corp
+ 5 TE-TYPE-DEST-HOST (I have reservations)
+
+alternate authentication type method-type value
+reserved values 0-63
+ATT-CHALLENGE-RESPONSE 64
+
+transited encoding type tr-type value
+DOMAIN-X500-COMPRESS 1
+reserved values all others
+
+Label Value Meaning or MIT code
+
+pvno 5 current Kerberos protocol version number
+
+message types
+
+KRB_AS_REQ 10 Request for initial authentication
+KRB_AS_REP 11 Response to KRB_AS_REQ request
+KRB_TGS_REQ 12 Request for authentication based on TGT
+KRB_TGS_REP 13 Response to KRB_TGS_REQ request
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+KRB_AP_REQ 14 application request to server
+KRB_AP_REP 15 Response to KRB_AP_REQ_MUTUAL
+KRB_SAFE 20 Safe (checksummed) application message
+KRB_PRIV 21 Private (encrypted) application message
+KRB_CRED 22 Private (encrypted) message to forward credentials
+KRB_ERROR 30 Error response
+
+name types
+
+KRB_NT_UNKNOWN 0 Name type not known
+KRB_NT_PRINCIPAL 1 Just the name of the principal as in DCE, or for users
+KRB_NT_SRV_INST 2 Service and other unique instance (krbtgt)
+KRB_NT_SRV_HST 3 Service with host name as instance (telnet, rcommands)
+KRB_NT_SRV_XHST 4 Service with host as remaining components
+KRB_NT_UID 5 Unique ID
+KRB_NT_X500_PRINCIPAL 6 Encoded X.509 Distingished name [RFC 1779]
+
+error codes
+
+KDC_ERR_NONE 0 No error
+KDC_ERR_NAME_EXP 1 Client's entry in database has expired
+KDC_ERR_SERVICE_EXP 2 Server's entry in database has expired
+KDC_ERR_BAD_PVNO 3 Requested protocol version number not
+ supported
+KDC_ERR_C_OLD_MAST_KVNO 4 Client's key encrypted in old master key
+KDC_ERR_S_OLD_MAST_KVNO 5 Server's key encrypted in old master key
+KDC_ERR_C_PRINCIPAL_UNKNOWN 6 Client not found in Kerberos database
+KDC_ERR_S_PRINCIPAL_UNKNOWN 7 Server not found in Kerberos database
+KDC_ERR_PRINCIPAL_NOT_UNIQUE 8 Multiple principal entries in database
+KDC_ERR_NULL_KEY 9 The client or server has a null key
+KDC_ERR_CANNOT_POSTDATE 10 Ticket not eligible for postdating
+KDC_ERR_NEVER_VALID 11 Requested start time is later than end time
+KDC_ERR_POLICY 12 KDC policy rejects request
+KDC_ERR_BADOPTION 13 KDC cannot accommodate requested option
+KDC_ERR_ETYPE_NOSUPP 14 KDC has no support for encryption type
+KDC_ERR_SUMTYPE_NOSUPP 15 KDC has no support for checksum type
+KDC_ERR_PADATA_TYPE_NOSUPP 16 KDC has no support for padata type
+KDC_ERR_TRTYPE_NOSUPP 17 KDC has no support for transited type
+KDC_ERR_CLIENT_REVOKED 18 Clients credentials have been revoked
+KDC_ERR_SERVICE_REVOKED 19 Credentials for server have been revoked
+KDC_ERR_TGT_REVOKED 20 TGT has been revoked
+KDC_ERR_CLIENT_NOTYET 21 Client not yet valid - try again later
+KDC_ERR_SERVICE_NOTYET 22 Server not yet valid - try again later
+KDC_ERR_KEY_EXPIRED 23 Password has expired - change password
+ to reset
+KDC_ERR_PREAUTH_FAILED 24 Pre-authentication information was invalid
+KDC_ERR_PREAUTH_REQUIRED 25 Additional pre-authenticationrequired [40]
+KDC_ERR_SERVER_NOMATCH 26 Requested server and ticket don't match
+KDC_ERR_MUST_USE_USER2USER 27 Server principal valid for user2user only
+KDC_ERR_PATH_NOT_ACCPETED 28 KDC Policy rejects transited path
+KRB_AP_ERR_BAD_INTEGRITY 31 Integrity check on decrypted field failed
+KRB_AP_ERR_TKT_EXPIRED 32 Ticket expired
+KRB_AP_ERR_TKT_NYV 33 Ticket not yet valid
+KRB_AP_ERR_REPEAT 34 Request is a replay
+KRB_AP_ERR_NOT_US 35 The ticket isn't for us
+KRB_AP_ERR_BADMATCH 36 Ticket and authenticator don't match
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+KRB_AP_ERR_SKEW 37 Clock skew too great
+KRB_AP_ERR_BADADDR 38 Incorrect net address
+KRB_AP_ERR_BADVERSION 39 Protocol version mismatch
+KRB_AP_ERR_MSG_TYPE 40 Invalid msg type
+KRB_AP_ERR_MODIFIED 41 Message stream modified
+KRB_AP_ERR_BADORDER 42 Message out of order
+KRB_AP_ERR_BADKEYVER 44 Specified version of key is not available
+KRB_AP_ERR_NOKEY 45 Service key not available
+KRB_AP_ERR_MUT_FAIL 46 Mutual authentication failed
+KRB_AP_ERR_BADDIRECTION 47 Incorrect message direction
+KRB_AP_ERR_METHOD 48 Alternative authentication method required
+KRB_AP_ERR_BADSEQ 49 Incorrect sequence number in message
+KRB_AP_ERR_INAPP_CKSUM 50 Inappropriate type of checksum in message
+KRB_AP_PATH_NOT_ACCEPTED 51 Policy rejects transited path
+KRB_ERR_GENERIC 60 Generic error (description in e-text)
+KRB_ERR_FIELD_TOOLONG 61 Field is too long for this implementation
+KDC_ERROR_CLIENT_NOT_TRUSTED 62 (pkinit)
+KDC_ERROR_KDC_NOT_TRUSTED 63 (pkinit)
+KDC_ERROR_INVALID_SIG 64 (pkinit)
+KDC_ERR_KEY_TOO_WEAK 65 (pkinit)
+KDC_ERR_CERTIFICATE_MISMATCH 66 (pkinit)
+
+9. Interoperability requirements
+
+Version 5 of the Kerberos protocol supports a myriad of options. Among these
+are multiple encryption and checksum types, alternative encoding schemes for
+the transited field, optional mechanisms for pre-authentication, the
+handling of tickets with no addresses, options for mutual authentication,
+user to user authentication, support for proxies, forwarding, postdating,
+and renewing tickets, the format of realm names, and the handling of
+authorization data.
+
+In order to ensure the interoperability of realms, it is necessary to define
+a minimal configuration which must be supported by all implementations. This
+minimal configuration is subject to change as technology does. For example,
+if at some later date it is discovered that one of the required encryption
+or checksum algorithms is not secure, it will be replaced.
+
+9.1. Specification 2
+
+This section defines the second specification of these options.
+Implementations which are configured in this way can be said to support
+Kerberos Version 5 Specification 2 (5.1). Specification 1 (depricated) may
+be found in RFC1510.
+
+Transport
+
+TCP/IP and UDP/IP transport must be supported by KDCs claiming conformance
+to specification 2. Kerberos clients claiming conformance to specification 2
+must support UDP/IP transport for messages with the KDC and may support
+TCP/IP transport.
+
+Encryption and checksum methods
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+The following encryption and checksum mechanisms must be supported.
+Implementations may support other mechanisms as well, but the additional
+mechanisms may only be used when communicating with principals known to also
+support them: This list is to be determined.
+
+Encryption: DES-CBC-MD5
+Checksums: CRC-32, DES-MAC, DES-MAC-K, and DES-MD5
+
+Realm Names
+
+All implementations must understand hierarchical realms in both the Internet
+Domain and the X.500 style. When a ticket granting ticket for an unknown
+realm is requested, the KDC must be able to determine the names of the
+intermediate realms between the KDCs realm and the requested realm.
+
+Transited field encoding
+
+DOMAIN-X500-COMPRESS (described in section 3.3.3.2) must be supported.
+Alternative encodings may be supported, but they may be used only when that
+encoding is supported by ALL intermediate realms.
+
+Pre-authentication methods
+
+The TGS-REQ method must be supported. The TGS-REQ method is not used on the
+initial request. The PA-ENC-TIMESTAMP method must be supported by clients
+but whether it is enabled by default may be determined on a realm by realm
+basis. If not used in the initial request and the error
+KDC_ERR_PREAUTH_REQUIRED is returned specifying PA-ENC-TIMESTAMP as an
+acceptable method, the client should retry the initial request using the
+PA-ENC-TIMESTAMP preauthentication method. Servers need not support the
+PA-ENC-TIMESTAMP method, but if not supported the server should ignore the
+presence of PA-ENC-TIMESTAMP pre-authentication in a request.
+
+Mutual authentication
+
+Mutual authentication (via the KRB_AP_REP message) must be supported.
+
+Ticket addresses and flags
+
+All KDC's must pass on tickets that carry no addresses (i.e. if a TGT
+contains no addresses, the KDC will return derivative tickets), but each
+realm may set its own policy for issuing such tickets, and each application
+server will set its own policy with respect to accepting them.
+
+Proxies and forwarded tickets must be supported. Individual realms and
+application servers can set their own policy on when such tickets will be
+accepted.
+
+All implementations must recognize renewable and postdated tickets, but need
+not actually implement them. If these options are not supported, the
+starttime and endtime in the ticket shall specify a ticket's entire useful
+life. When a postdated ticket is decoded by a server, all implementations
+shall make the presence of the postdated flag visible to the calling server.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+User-to-user authentication
+
+Support for user to user authentication (via the ENC-TKT-IN-SKEY KDC option)
+must be provided by implementations, but individual realms may decide as a
+matter of policy to reject such requests on a per-principal or realm-wide
+basis.
+
+Authorization data
+
+Implementations must pass all authorization data subfields from
+ticket-granting tickets to any derivative tickets unless directed to
+suppress a subfield as part of the definition of that registered subfield
+type (it is never incorrect to pass on a subfield, and no registered
+subfield types presently specify suppression at the KDC).
+
+Implementations must make the contents of any authorization data subfields
+available to the server when a ticket is used. Implementations are not
+required to allow clients to specify the contents of the authorization data
+fields.
+
+9.2. Recommended KDC values
+
+Following is a list of recommended values for a KDC implementation, based on
+the list of suggested configuration constants (see section 4.4).
+
+minimum lifetime 5 minutes
+maximum renewable lifetime 1 week
+maximum ticket lifetime 1 day
+empty addresses only when suitable restrictions appear
+ in authorization data
+proxiable, etc. Allowed.
+
+10. REFERENCES
+
+[NT94] B. Clifford Neuman and Theodore Y. Ts'o, "An Authenti-
+ cation Service for Computer Networks," IEEE Communica-
+ tions Magazine, Vol. 32(9), pp. 33-38 (September 1994).
+
+[MNSS87] S. P. Miller, B. C. Neuman, J. I. Schiller, and J. H.
+ Saltzer, Section E.2.1: Kerberos Authentication and
+ Authorization System, M.I.T. Project Athena, Cambridge,
+ Massachusetts (December 21, 1987).
+
+[SNS88] J. G. Steiner, B. C. Neuman, and J. I. Schiller, "Ker-
+ beros: An Authentication Service for Open Network Sys-
+ tems," pp. 191-202 in Usenix Conference Proceedings,
+ Dallas, Texas (February, 1988).
+
+[NS78] Roger M. Needham and Michael D. Schroeder, "Using
+ Encryption for Authentication in Large Networks of Com-
+ puters," Communications of the ACM, Vol. 21(12),
+ pp. 993-999 (December, 1978).
+
+[DS81] Dorothy E. Denning and Giovanni Maria Sacco, "Time-
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ stamps in Key Distribution Protocols," Communications
+ of the ACM, Vol. 24(8), pp. 533-536 (August 1981).
+
+[KNT92] John T. Kohl, B. Clifford Neuman, and Theodore Y. Ts'o,
+ "The Evolution of the Kerberos Authentication Service,"
+ in an IEEE Computer Society Text soon to be published
+ (June 1992).
+
+[Neu93] B. Clifford Neuman, "Proxy-Based Authorization and
+ Accounting for Distributed Systems," in Proceedings of
+ the 13th International Conference on Distributed Com-
+ puting Systems, Pittsburgh, PA (May, 1993).
+
+[DS90] Don Davis and Ralph Swick, "Workstation Services and
+ Kerberos Authentication at Project Athena," Technical
+ Memorandum TM-424, MIT Laboratory for Computer Science
+ (February 1990).
+
+[LGDSR87] P. J. Levine, M. R. Gretzinger, J. M. Diaz, W. E. Som-
+ merfeld, and K. Raeburn, Section E.1: Service Manage-
+ ment System, M.I.T. Project Athena, Cambridge, Mas-
+ sachusetts (1987).
+
+[X509-88] CCITT, Recommendation X.509: The Directory Authentica-
+ tion Framework, December 1988.
+
+[Pat92]. J. Pato, Using Pre-Authentication to Avoid Password
+ Guessing Attacks, Open Software Foundation DCE Request
+ for Comments 26 (December 1992).
+
+[DES77] National Bureau of Standards, U.S. Department of Com-
+ merce, "Data Encryption Standard," Federal Information
+ Processing Standards Publication 46, Washington, DC
+ (1977).
+
+[DESM80] National Bureau of Standards, U.S. Department of Com-
+ merce, "DES Modes of Operation," Federal Information
+ Processing Standards Publication 81, Springfield, VA
+ (December 1980).
+
+[SG92] Stuart G. Stubblebine and Virgil D. Gligor, "On Message
+ Integrity in Cryptographic Protocols," in Proceedings
+ of the IEEE Symposium on Research in Security and
+ Privacy, Oakland, California (May 1992).
+
+[IS3309] International Organization for Standardization, "ISO
+ Information Processing Systems - Data Communication -
+ High-Level Data Link Control Procedure - Frame Struc-
+ ture," IS 3309 (October 1984). 3rd Edition.
+
+[MD4-92] R. Rivest, "The MD4 Message Digest Algorithm," RFC
+ 1320, MIT Laboratory for Computer Science (April
+ 1992).
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+[MD5-92] R. Rivest, "The MD5 Message Digest Algorithm," RFC
+ 1321, MIT Laboratory for Computer Science (April
+ 1992).
+
+[KBC96] H. Krawczyk, M. Bellare, and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication," Working Draft
+ draft-ietf-ipsec-hmac-md5-01.txt, (August 1996).
+
+A. Pseudo-code for protocol processing
+
+This appendix provides pseudo-code describing how the messages are to be
+constructed and interpreted by clients and servers.
+
+A.1. KRB_AS_REQ generation
+
+ request.pvno := protocol version; /* pvno = 5 */
+ request.msg-type := message type; /* type = KRB_AS_REQ */
+
+ if(pa_enc_timestamp_required) then
+ request.padata.padata-type = PA-ENC-TIMESTAMP;
+ get system_time;
+ padata-body.patimestamp,pausec = system_time;
+ encrypt padata-body into request.padata.padata-value
+ using client.key; /* derived from password */
+ endif
+
+ body.kdc-options := users's preferences;
+ body.cname := user's name;
+ body.realm := user's realm;
+ body.sname := service's name; /* usually "krbtgt", "localrealm" */
+ if (body.kdc-options.POSTDATED is set) then
+ body.from := requested starting time;
+ else
+ omit body.from;
+ endif
+ body.till := requested end time;
+ if (body.kdc-options.RENEWABLE is set) then
+ body.rtime := requested final renewal time;
+ endif
+ body.nonce := random_nonce();
+ body.etype := requested etypes;
+ if (user supplied addresses) then
+ body.addresses := user's addresses;
+ else
+ omit body.addresses;
+ endif
+ omit body.enc-authorization-data;
+ request.req-body := body;
+
+ kerberos := lookup(name of local kerberos server (or servers));
+ send(packet,kerberos);
+
+ wait(for response);
+ if (timed_out) then
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ retry or use alternate server;
+ endif
+
+A.2. KRB_AS_REQ verification and KRB_AS_REP generation
+
+ decode message into req;
+
+ client := lookup(req.cname,req.realm);
+ server := lookup(req.sname,req.realm);
+
+ get system_time;
+ kdc_time := system_time.seconds;
+
+ if (!client) then
+ /* no client in Database */
+ error_out(KDC_ERR_C_PRINCIPAL_UNKNOWN);
+ endif
+ if (!server) then
+ /* no server in Database */
+ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
+ endif
+
+ if(client.pa_enc_timestamp_required and
+ pa_enc_timestamp not present) then
+ error_out(KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP));
+ endif
+
+ if(pa_enc_timestamp present) then
+ decrypt req.padata-value into decrypted_enc_timestamp
+ using client.key;
+ using auth_hdr.authenticator.subkey;
+ if (decrypt_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ if(decrypted_enc_timestamp is not within allowable skew) then
+ error_out(KDC_ERR_PREAUTH_FAILED);
+ endif
+ if(decrypted_enc_timestamp and usec is replay)
+ error_out(KDC_ERR_PREAUTH_FAILED);
+ endif
+ add decrypted_enc_timestamp and usec to replay cache;
+ endif
+
+ use_etype := first supported etype in req.etypes;
+
+ if (no support for req.etypes) then
+ error_out(KDC_ERR_ETYPE_NOSUPP);
+ endif
+
+ new_tkt.vno := ticket version; /* = 5 */
+ new_tkt.sname := req.sname;
+ new_tkt.srealm := req.srealm;
+ reset all flags in new_tkt.flags;
+
+ /* It should be noted that local policy may affect the */
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ /* processing of any of these flags. For example, some */
+ /* realms may refuse to issue renewable tickets */
+
+ if (req.kdc-options.FORWARDABLE is set) then
+ set new_tkt.flags.FORWARDABLE;
+ endif
+ if (req.kdc-options.PROXIABLE is set) then
+ set new_tkt.flags.PROXIABLE;
+ endif
+
+ if (req.kdc-options.ALLOW-POSTDATE is set) then
+ set new_tkt.flags.MAY-POSTDATE;
+ endif
+ if ((req.kdc-options.RENEW is set) or
+ (req.kdc-options.VALIDATE is set) or
+ (req.kdc-options.PROXY is set) or
+ (req.kdc-options.FORWARDED is set) or
+ (req.kdc-options.ENC-TKT-IN-SKEY is set)) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+ new_tkt.session := random_session_key();
+ new_tkt.cname := req.cname;
+ new_tkt.crealm := req.crealm;
+ new_tkt.transited := empty_transited_field();
+
+ new_tkt.authtime := kdc_time;
+
+ if (req.kdc-options.POSTDATED is set) then
+ if (against_postdate_policy(req.from)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ set new_tkt.flags.POSTDATED;
+ set new_tkt.flags.INVALID;
+ new_tkt.starttime := req.from;
+ else
+ omit new_tkt.starttime; /* treated as authtime when omitted */
+ endif
+ if (req.till = 0) then
+ till := infinity;
+ else
+ till := req.till;
+ endif
+
+ new_tkt.endtime := min(till,
+ new_tkt.starttime+client.max_life,
+ new_tkt.starttime+server.max_life,
+ new_tkt.starttime+max_life_for_realm);
+
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (new_tkt.endtime < req.till)) then
+ /* we set the RENEWABLE option for later processing */
+ set req.kdc-options.RENEWABLE;
+ req.rtime := req.till;
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ endif
+
+ if (req.rtime = 0) then
+ rtime := infinity;
+ else
+ rtime := req.rtime;
+ endif
+
+ if (req.kdc-options.RENEWABLE is set) then
+ set new_tkt.flags.RENEWABLE;
+ new_tkt.renew-till := min(rtime,
+ new_tkt.starttime+client.max_rlife,
+ new_tkt.starttime+server.max_rlife,
+ new_tkt.starttime+max_rlife_for_realm);
+ else
+ omit new_tkt.renew-till; /* only present if RENEWABLE */
+ endif
+
+ if (req.addresses) then
+ new_tkt.caddr := req.addresses;
+ else
+ omit new_tkt.caddr;
+ endif
+
+ new_tkt.authorization_data := empty_authorization_data();
+
+ encode to-be-encrypted part of ticket into OCTET STRING;
+ new_tkt.enc-part := encrypt OCTET STRING
+ using etype_for_key(server.key), server.key, server.p_kvno;
+
+ /* Start processing the response */
+
+ resp.pvno := 5;
+ resp.msg-type := KRB_AS_REP;
+ resp.cname := req.cname;
+ resp.crealm := req.realm;
+ resp.ticket := new_tkt;
+
+ resp.key := new_tkt.session;
+ resp.last-req := fetch_last_request_info(client);
+ resp.nonce := req.nonce;
+ resp.key-expiration := client.expiration;
+ resp.flags := new_tkt.flags;
+
+ resp.authtime := new_tkt.authtime;
+ resp.starttime := new_tkt.starttime;
+ resp.endtime := new_tkt.endtime;
+
+ if (new_tkt.flags.RENEWABLE) then
+ resp.renew-till := new_tkt.renew-till;
+ endif
+
+ resp.realm := new_tkt.realm;
+ resp.sname := new_tkt.sname;
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+ resp.caddr := new_tkt.caddr;
+
+ encode body of reply into OCTET STRING;
+
+ resp.enc-part := encrypt OCTET STRING
+ using use_etype, client.key, client.p_kvno;
+ send(resp);
+
+A.3. KRB_AS_REP verification
+
+ decode response into resp;
+
+ if (resp.msg-type = KRB_ERROR) then
+ if(error = KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP)) then
+ set pa_enc_timestamp_required;
+ goto KRB_AS_REQ;
+ endif
+ process_error(resp);
+ return;
+ endif
+
+ /* On error, discard the response, and zero the session key */
+ /* from the response immediately */
+
+ key = get_decryption_key(resp.enc-part.kvno, resp.enc-part.etype,
+ resp.padata);
+ unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and key;
+ zero(key);
+
+ if (common_as_rep_tgs_rep_checks fail) then
+ destroy resp.key;
+ return error;
+ endif
+
+ if near(resp.princ_exp) then
+ print(warning message);
+ endif
+ save_for_later(ticket,session,client,server,times,flags);
+
+A.4. KRB_AS_REP and KRB_TGS_REP common checks
+
+ if (decryption_error() or
+ (req.cname != resp.cname) or
+ (req.realm != resp.crealm) or
+ (req.sname != resp.sname) or
+ (req.realm != resp.realm) or
+ (req.nonce != resp.nonce) or
+ (req.addresses != resp.caddr)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ /* make sure no flags are set that shouldn't be, and that all that */
+ /* should be are set */
+ if (!check_flags_for_compatability(req.kdc-options,resp.flags)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ if ((req.from = 0) and
+ (resp.starttime is not within allowable skew)) then
+ destroy resp.key;
+ return KRB_AP_ERR_SKEW;
+ endif
+ if ((req.from != 0) and (req.from != resp.starttime)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+ if ((req.till != 0) and (resp.endtime > req.till)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ if ((req.kdc-options.RENEWABLE is set) and
+ (req.rtime != 0) and (resp.renew-till > req.rtime)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (resp.flags.RENEWABLE) and
+ (req.till != 0) and
+ (resp.renew-till > req.till)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+A.5. KRB_TGS_REQ generation
+
+ /* Note that make_application_request might have to recursivly */
+ /* call this routine to get the appropriate ticket-granting ticket */
+
+ request.pvno := protocol version; /* pvno = 5 */
+ request.msg-type := message type; /* type = KRB_TGS_REQ */
+
+ body.kdc-options := users's preferences;
+ /* If the TGT is not for the realm of the end-server */
+ /* then the sname will be for a TGT for the end-realm */
+ /* and the realm of the requested ticket (body.realm) */
+ /* will be that of the TGS to which the TGT we are */
+ /* sending applies */
+ body.sname := service's name;
+ body.realm := service's realm;
+
+ if (body.kdc-options.POSTDATED is set) then
+ body.from := requested starting time;
+ else
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ omit body.from;
+ endif
+ body.till := requested end time;
+ if (body.kdc-options.RENEWABLE is set) then
+ body.rtime := requested final renewal time;
+ endif
+ body.nonce := random_nonce();
+ body.etype := requested etypes;
+ if (user supplied addresses) then
+ body.addresses := user's addresses;
+ else
+ omit body.addresses;
+ endif
+
+ body.enc-authorization-data := user-supplied data;
+ if (body.kdc-options.ENC-TKT-IN-SKEY) then
+ body.additional-tickets_ticket := second TGT;
+ endif
+
+ request.req-body := body;
+ check := generate_checksum (req.body,checksumtype);
+
+ request.padata[0].padata-type := PA-TGS-REQ;
+ request.padata[0].padata-value := create a KRB_AP_REQ using
+ the TGT and checksum
+
+ /* add in any other padata as required/supplied */
+
+ kerberos := lookup(name of local kerberose server (or servers));
+ send(packet,kerberos);
+
+ wait(for response);
+ if (timed_out) then
+ retry or use alternate server;
+ endif
+
+A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation
+
+ /* note that reading the application request requires first
+ determining the server for which a ticket was issued, and choosing the
+ correct key for decryption. The name of the server appears in the
+ plaintext part of the ticket. */
+
+ if (no KRB_AP_REQ in req.padata) then
+ error_out(KDC_ERR_PADATA_TYPE_NOSUPP);
+ endif
+ verify KRB_AP_REQ in req.padata;
+
+ /* Note that the realm in which the Kerberos server is operating is
+ determined by the instance from the ticket-granting ticket. The realm
+ in the ticket-granting ticket is the realm under which the ticket
+ granting ticket was issued. It is possible for a single Kerberos
+ server to support more than one realm. */
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ auth_hdr := KRB_AP_REQ;
+ tgt := auth_hdr.ticket;
+
+ if (tgt.sname is not a TGT for local realm and is not req.sname) then
+ error_out(KRB_AP_ERR_NOT_US);
+
+ realm := realm_tgt_is_for(tgt);
+
+ decode remainder of request;
+
+ if (auth_hdr.authenticator.cksum is missing) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+
+ if (auth_hdr.authenticator.cksum type is not supported) then
+ error_out(KDC_ERR_SUMTYPE_NOSUPP);
+ endif
+ if (auth_hdr.authenticator.cksum is not both collision-proof and keyed) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+
+ set computed_checksum := checksum(req);
+ if (computed_checksum != auth_hdr.authenticatory.cksum) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ server := lookup(req.sname,realm);
+
+ if (!server) then
+ if (is_foreign_tgt_name(req.sname)) then
+ server := best_intermediate_tgs(req.sname);
+ else
+ /* no server in Database */
+ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
+ endif
+ endif
+
+ session := generate_random_session_key();
+
+ use_etype := first supported etype in req.etypes;
+
+ if (no support for req.etypes) then
+ error_out(KDC_ERR_ETYPE_NOSUPP);
+ endif
+
+ new_tkt.vno := ticket version; /* = 5 */
+ new_tkt.sname := req.sname;
+ new_tkt.srealm := realm;
+ reset all flags in new_tkt.flags;
+
+ /* It should be noted that local policy may affect the */
+ /* processing of any of these flags. For example, some */
+ /* realms may refuse to issue renewable tickets */
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ new_tkt.caddr := tgt.caddr;
+ resp.caddr := NULL; /* We only include this if they change */
+ if (req.kdc-options.FORWARDABLE is set) then
+ if (tgt.flags.FORWARDABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.FORWARDABLE;
+ endif
+ if (req.kdc-options.FORWARDED is set) then
+ if (tgt.flags.FORWARDABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.FORWARDED;
+ new_tkt.caddr := req.addresses;
+ resp.caddr := req.addresses;
+ endif
+ if (tgt.flags.FORWARDED is set) then
+ set new_tkt.flags.FORWARDED;
+ endif
+
+ if (req.kdc-options.PROXIABLE is set) then
+ if (tgt.flags.PROXIABLE is reset)
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.PROXIABLE;
+ endif
+ if (req.kdc-options.PROXY is set) then
+ if (tgt.flags.PROXIABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.PROXY;
+ new_tkt.caddr := req.addresses;
+ resp.caddr := req.addresses;
+ endif
+
+ if (req.kdc-options.ALLOW-POSTDATE is set) then
+ if (tgt.flags.MAY-POSTDATE is reset)
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.MAY-POSTDATE;
+ endif
+ if (req.kdc-options.POSTDATED is set) then
+ if (tgt.flags.MAY-POSTDATE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.POSTDATED;
+ set new_tkt.flags.INVALID;
+ if (against_postdate_policy(req.from)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ new_tkt.starttime := req.from;
+ endif
+
+ if (req.kdc-options.VALIDATE is set) then
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ if (tgt.flags.INVALID is reset) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ if (tgt.starttime > kdc_time) then
+ error_out(KRB_AP_ERR_NYV);
+ endif
+ if (check_hot_list(tgt)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ tkt := tgt;
+ reset new_tkt.flags.INVALID;
+ endif
+
+ if (req.kdc-options.(any flag except ENC-TKT-IN-SKEY, RENEW,
+ and those already processed) is set) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+ new_tkt.authtime := tgt.authtime;
+
+ if (req.kdc-options.RENEW is set) then
+ /* Note that if the endtime has already passed, the ticket would */
+ /* have been rejected in the initial authentication stage, so */
+ /* there is no need to check again here */
+ if (tgt.flags.RENEWABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ if (tgt.renew-till < kdc_time) then
+ error_out(KRB_AP_ERR_TKT_EXPIRED);
+ endif
+ tkt := tgt;
+ new_tkt.starttime := kdc_time;
+ old_life := tgt.endttime - tgt.starttime;
+ new_tkt.endtime := min(tgt.renew-till,
+ new_tkt.starttime + old_life);
+ else
+ new_tkt.starttime := kdc_time;
+ if (req.till = 0) then
+ till := infinity;
+ else
+ till := req.till;
+ endif
+ new_tkt.endtime := min(till,
+ new_tkt.starttime+client.max_life,
+ new_tkt.starttime+server.max_life,
+ new_tkt.starttime+max_life_for_realm,
+ tgt.endtime);
+
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (new_tkt.endtime < req.till) and
+ (tgt.flags.RENEWABLE is set) then
+ /* we set the RENEWABLE option for later processing */
+ set req.kdc-options.RENEWABLE;
+ req.rtime := min(req.till, tgt.renew-till);
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ endif
+ endif
+
+ if (req.rtime = 0) then
+ rtime := infinity;
+ else
+ rtime := req.rtime;
+ endif
+
+ if ((req.kdc-options.RENEWABLE is set) and
+ (tgt.flags.RENEWABLE is set)) then
+ set new_tkt.flags.RENEWABLE;
+ new_tkt.renew-till := min(rtime,
+ new_tkt.starttime+client.max_rlife,
+ new_tkt.starttime+server.max_rlife,
+ new_tkt.starttime+max_rlife_for_realm,
+ tgt.renew-till);
+ else
+ new_tkt.renew-till := OMIT; /* leave the renew-till field out */
+ endif
+ if (req.enc-authorization-data is present) then
+ decrypt req.enc-authorization-data into decrypted_authorization_data
+ using auth_hdr.authenticator.subkey;
+ if (decrypt_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ endif
+ new_tkt.authorization_data := req.auth_hdr.ticket.authorization_data +
+ decrypted_authorization_data;
+
+ new_tkt.key := session;
+ new_tkt.crealm := tgt.crealm;
+ new_tkt.cname := req.auth_hdr.ticket.cname;
+
+ if (realm_tgt_is_for(tgt) := tgt.realm) then
+ /* tgt issued by local realm */
+ new_tkt.transited := tgt.transited;
+ else
+ /* was issued for this realm by some other realm */
+ if (tgt.transited.tr-type not supported) then
+ error_out(KDC_ERR_TRTYPE_NOSUPP);
+ endif
+ new_tkt.transited := compress_transited(tgt.transited + tgt.realm)
+ /* Don't check tranited field if TGT for foreign realm,
+ * or requested not to check */
+ if (is_not_foreign_tgt_name(new_tkt.server)
+ && req.kdc-options.DISABLE-TRANSITED-CHECK not set) then
+ /* Check it, so end-server does not have to
+ * but don't fail, end-server may still accept it */
+ if (check_transited_field(new_tkt.transited) == OK)
+ set new_tkt.flags.TRANSITED-POLICY-CHECKED;
+ endif
+ endif
+ endif
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+ encode encrypted part of new_tkt into OCTET STRING;
+ if (req.kdc-options.ENC-TKT-IN-SKEY is set) then
+ if (server not specified) then
+ server = req.second_ticket.client;
+ endif
+ if ((req.second_ticket is not a TGT) or
+ (req.second_ticket.client != server)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+
+ new_tkt.enc-part := encrypt OCTET STRING using
+ using etype_for_key(second-ticket.key), second-ticket.key;
+ else
+ new_tkt.enc-part := encrypt OCTET STRING
+ using etype_for_key(server.key), server.key, server.p_kvno;
+ endif
+
+ resp.pvno := 5;
+ resp.msg-type := KRB_TGS_REP;
+ resp.crealm := tgt.crealm;
+ resp.cname := tgt.cname;
+ resp.ticket := new_tkt;
+
+ resp.key := session;
+ resp.nonce := req.nonce;
+ resp.last-req := fetch_last_request_info(client);
+ resp.flags := new_tkt.flags;
+
+ resp.authtime := new_tkt.authtime;
+ resp.starttime := new_tkt.starttime;
+ resp.endtime := new_tkt.endtime;
+
+ omit resp.key-expiration;
+
+ resp.sname := new_tkt.sname;
+ resp.realm := new_tkt.realm;
+
+ if (new_tkt.flags.RENEWABLE) then
+ resp.renew-till := new_tkt.renew-till;
+ endif
+
+ encode body of reply into OCTET STRING;
+
+ if (req.padata.authenticator.subkey)
+ resp.enc-part := encrypt OCTET STRING using use_etype,
+ req.padata.authenticator.subkey;
+ else resp.enc-part := encrypt OCTET STRING using use_etype, tgt.key;
+
+ send(resp);
+
+A.7. KRB_TGS_REP verification
+
+ decode response into resp;
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+ if (resp.msg-type = KRB_ERROR) then
+ process_error(resp);
+ return;
+ endif
+
+ /* On error, discard the response, and zero the session key from
+ the response immediately */
+
+ if (req.padata.authenticator.subkey)
+ unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and subkey;
+ else unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and tgt's session key;
+ if (common_as_rep_tgs_rep_checks fail) then
+ destroy resp.key;
+ return error;
+ endif
+
+ check authorization_data as necessary;
+ save_for_later(ticket,session,client,server,times,flags);
+
+A.8. Authenticator generation
+
+ body.authenticator-vno := authenticator vno; /* = 5 */
+ body.cname, body.crealm := client name;
+ if (supplying checksum) then
+ body.cksum := checksum;
+ endif
+ get system_time;
+ body.ctime, body.cusec := system_time;
+ if (selecting sub-session key) then
+ select sub-session key;
+ body.subkey := sub-session key;
+ endif
+ if (using sequence numbers) then
+ select initial sequence number;
+ body.seq-number := initial sequence;
+ endif
+
+A.9. KRB_AP_REQ generation
+
+ obtain ticket and session_key from cache;
+
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_AP_REQ */
+
+ if (desired(MUTUAL_AUTHENTICATION)) then
+ set packet.ap-options.MUTUAL-REQUIRED;
+ else
+ reset packet.ap-options.MUTUAL-REQUIRED;
+ endif
+ if (using session key for ticket) then
+ set packet.ap-options.USE-SESSION-KEY;
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ else
+ reset packet.ap-options.USE-SESSION-KEY;
+ endif
+ packet.ticket := ticket; /* ticket */
+ generate authenticator;
+ encode authenticator into OCTET STRING;
+ encrypt OCTET STRING into packet.authenticator using session_key;
+
+A.10. KRB_AP_REQ verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_AP_REQ) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ if (packet.ticket.tkt_vno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.ap_options.USE-SESSION-KEY is set) then
+ retrieve session key from ticket-granting ticket for
+ packet.ticket.{sname,srealm,enc-part.etype};
+ else
+ retrieve service key for
+ packet.ticket.{sname,srealm,enc-part.etype,enc-part.skvno};
+ endif
+ if (no_key_available) then
+ if (cannot_find_specified_skvno) then
+ error_out(KRB_AP_ERR_BADKEYVER);
+ else
+ error_out(KRB_AP_ERR_NOKEY);
+ endif
+ endif
+ decrypt packet.ticket.enc-part into decr_ticket using retrieved key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ decrypt packet.authenticator into decr_authenticator
+ using decr_ticket.key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if (decr_authenticator.{cname,crealm} !=
+ decr_ticket.{cname,crealm}) then
+ error_out(KRB_AP_ERR_BADMATCH);
+ endif
+ if (decr_ticket.caddr is present) then
+ if (sender_address(packet) is not in decr_ticket.caddr) then
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ elseif (application requires addresses) then
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (not in_clock_skew(decr_authenticator.ctime,
+ decr_authenticator.cusec)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(decr_authenticator.{ctime,cusec,cname,crealm})) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ save_identifier(decr_authenticator.{ctime,cusec,cname,crealm});
+ get system_time;
+ if ((decr_ticket.starttime-system_time > CLOCK_SKEW) or
+ (decr_ticket.flags.INVALID is set)) then
+ /* it hasn't yet become valid */
+ error_out(KRB_AP_ERR_TKT_NYV);
+ endif
+ if (system_time-decr_ticket.endtime > CLOCK_SKEW) then
+ error_out(KRB_AP_ERR_TKT_EXPIRED);
+ endif
+ if (decr_ticket.transited) then
+ /* caller may ignore the TRANSITED-POLICY-CHECKED and do
+ * check anyway */
+ if (decr_ticket.flags.TRANSITED-POLICY-CHECKED not set) then
+ if (check_transited_field(decr_ticket.transited) then
+ error_out(KDC_AP_PATH_NOT_ACCPETED);
+ endif
+ endif
+ endif
+ /* caller must check decr_ticket.flags for any pertinent details */
+ return(OK, decr_ticket, packet.ap_options.MUTUAL-REQUIRED);
+
+A.11. KRB_AP_REP generation
+
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_AP_REP */
+
+ body.ctime := packet.ctime;
+ body.cusec := packet.cusec;
+ if (selecting sub-session key) then
+ select sub-session key;
+ body.subkey := sub-session key;
+ endif
+ if (using sequence numbers) then
+ select initial sequence number;
+ body.seq-number := initial sequence;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part;
+
+A.12. KRB_AP_REP verification
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_AP_REP) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ cleartext := decrypt(packet.enc-part) using ticket's session key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if (cleartext.ctime != authenticator.ctime) then
+ error_out(KRB_AP_ERR_MUT_FAIL);
+ endif
+ if (cleartext.cusec != authenticator.cusec) then
+ error_out(KRB_AP_ERR_MUT_FAIL);
+ endif
+ if (cleartext.subkey is present) then
+ save cleartext.subkey for future use;
+ endif
+ if (cleartext.seq-number is present) then
+ save cleartext.seq-number for future verifications;
+ endif
+ return(AUTHENTICATION_SUCCEEDED);
+
+A.13. KRB_SAFE generation
+
+ collect user data in buffer;
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_SAFE */
+
+ body.user-data := buffer; /* DATA */
+ if (using timestamp) then
+ get system_time;
+ body.timestamp, body.usec := system_time;
+ endif
+ if (using sequence numbers) then
+ body.seq-number := sequence number;
+ endif
+ body.s-address := sender host addresses;
+ if (only one recipient) then
+ body.r-address := recipient host address;
+ endif
+ checksum.cksumtype := checksum type;
+ compute checksum over body;
+ checksum.checksum := checksum value; /* checksum.checksum */
+ packet.cksum := checksum;
+ packet.safe-body := body;
+
+A.14. KRB_SAFE verification
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_SAFE) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ if (packet.checksum.cksumtype is not both collision-proof and keyed) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+ if (safe_priv_common_checks_ok(packet)) then
+ set computed_checksum := checksum(packet.body);
+ if (computed_checksum != packet.checksum) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+ return (packet, PACKET_IS_GENUINE);
+ else
+ return common_checks_error;
+ endif
+
+A.15. KRB_SAFE and KRB_PRIV common checks
+
+ if (packet.s-address != O/S_sender(packet)) then
+ /* O/S report of sender not who claims to have sent it */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if ((packet.r-address is present) and
+ (packet.r-address != local_host_address)) then
+ /* was not sent to proper place */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (((packet.timestamp is present) and
+ (not in_clock_skew(packet.timestamp,packet.usec))) or
+ (packet.timestamp is not present and timestamp expected)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(packet.timestamp,packet.usec,packet.s-address)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+
+ if (((packet.seq-number is present) and
+ ((not in_sequence(packet.seq-number)))) or
+ (packet.seq-number is not present and sequence expected)) then
+ error_out(KRB_AP_ERR_BADORDER);
+ endif
+ if (packet.timestamp not present and packet.seq-number not present)
+ then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ save_identifier(packet.{timestamp,usec,s-address},
+ sender_principal(packet));
+
+ return PACKET_IS_OK;
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+A.16. KRB_PRIV generation
+
+ collect user data in buffer;
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_PRIV */
+
+ packet.enc-part.etype := encryption type;
+
+ body.user-data := buffer;
+ if (using timestamp) then
+ get system_time;
+ body.timestamp, body.usec := system_time;
+ endif
+ if (using sequence numbers) then
+ body.seq-number := sequence number;
+ endif
+ body.s-address := sender host addresses;
+ if (only one recipient) then
+ body.r-address := recipient host address;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part.cipher;
+
+A.17. KRB_PRIV verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_PRIV) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+
+ cleartext := decrypt(packet.enc-part) using negotiated key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+
+ if (safe_priv_common_checks_ok(cleartext)) then
+ return(cleartext.DATA, PACKET_IS_GENUINE_AND_UNMODIFIED);
+ else
+ return common_checks_error;
+ endif
+
+A.18. KRB_CRED generation
+
+ invoke KRB_TGS; /* obtain tickets to be provided to peer */
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_CRED */
+
+ for (tickets[n] in tickets to be forwarded) do
+ packet.tickets[n] = tickets[n].ticket;
+ done
+
+ packet.enc-part.etype := encryption type;
+
+ for (ticket[n] in tickets to be forwarded) do
+ body.ticket-info[n].key = tickets[n].session;
+ body.ticket-info[n].prealm = tickets[n].crealm;
+ body.ticket-info[n].pname = tickets[n].cname;
+ body.ticket-info[n].flags = tickets[n].flags;
+ body.ticket-info[n].authtime = tickets[n].authtime;
+ body.ticket-info[n].starttime = tickets[n].starttime;
+ body.ticket-info[n].endtime = tickets[n].endtime;
+ body.ticket-info[n].renew-till = tickets[n].renew-till;
+ body.ticket-info[n].srealm = tickets[n].srealm;
+ body.ticket-info[n].sname = tickets[n].sname;
+ body.ticket-info[n].caddr = tickets[n].caddr;
+ done
+
+ get system_time;
+ body.timestamp, body.usec := system_time;
+
+ if (using nonce) then
+ body.nonce := nonce;
+ endif
+
+ if (using s-address) then
+ body.s-address := sender host addresses;
+ endif
+ if (limited recipients) then
+ body.r-address := recipient host address;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part.cipher
+ using negotiated encryption key;
+
+A.19. KRB_CRED verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_CRED) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ endif
+
+ cleartext := decrypt(packet.enc-part) using negotiated key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if ((packet.r-address is present or required) and
+ (packet.s-address != O/S_sender(packet)) then
+ /* O/S report of sender not who claims to have sent it */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if ((packet.r-address is present) and
+ (packet.r-address != local_host_address)) then
+ /* was not sent to proper place */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (not in_clock_skew(packet.timestamp,packet.usec)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(packet.timestamp,packet.usec,packet.s-address)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ if (packet.nonce is required or present) and
+ (packet.nonce != expected-nonce) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ for (ticket[n] in tickets that were forwarded) do
+ save_for_later(ticket[n],key[n],principal[n],
+ server[n],times[n],flags[n]);
+ return
+
+A.20. KRB_ERROR generation
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_ERROR */
+
+ get system_time;
+ packet.stime, packet.susec := system_time;
+ packet.realm, packet.sname := server name;
+
+ if (client time available) then
+ packet.ctime, packet.cusec := client_time;
+ endif
+ packet.error-code := error code;
+ if (client name available) then
+ packet.cname, packet.crealm := client name;
+ endif
+ if (error text available) then
+ packet.e-text := error text;
+ endif
+ if (error data available) then
+ packet.e-data := error data;
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+ endif
+
+B. Definition of common authorization data elements
+
+This appendix contains the definitions of common authorization data
+elements. These common authorization data elements are recursivly defined,
+meaning the ad-data for these types will itself contain a sequence of
+authorization data whose interpretation is affected by the encapsulating
+element. Depending on the meaning of the encapsulating element, the
+encapsulated elements may be ignored, might be interpreted as issued
+directly by the KDC, or they might be stored in a separate plaintext part of
+the ticket. The types of the encapsulating elements are specified as part of
+the Kerberos specification ebcause the behavior based on these values should
+be understood across implementations whereas other elements need only be
+understood by the applications which they affect.
+
+In the definitions that follow, the value of the ad-type for the element
+will be specified in the subsection number, and the value of the ad-data
+will be as shown in the ASN.1 structure that follows the subsection heading.
+
+B.1. KDC Issued
+
+AD-KDCIssued SEQUENCE {
+ ad-checksum[0] Checksum,
+ i-realm[1] Realm OPTIONAL,
+ i-sname[2] PrincipalName OPTIONAL,
+ elements[3] AuthorizationData.
+}
+
+ad-checksum
+ A checksum over the elements field using a cryptographic checksum
+ method that is identical to the checksum used to protect the ticket
+ itself (i.e. using the same hash function and the same encryption
+ algorithm used to encrypt the ticket) and using a key derived from the
+ same key used to protect the ticket.
+i-realm, i-sname
+ The name of the issuing principal if different from the KDC itself.
+ This field would be used when the KDC can verify the authenticity of
+ elements signed by the issuing principal and it allows this KDC to
+ notify the application server of the validity of those elements.
+elements
+ A sequence of authorization data elements issued by the KDC.
+
+The KDC-issued ad-data field is intended to provide a means for Kerberos
+principal credentials to embed within themselves privilege attributes and
+other mechanisms for positive authorization, amplifying the priveleges of
+the principal beyond what can be done using a credentials without such an
+a-data element.
+
+This can not be provided without this element because the definition of the
+authorization-data field allows elements to be added at will by the bearer
+of a TGT at the time that they request service tickets and elements may also
+be added to a delegated ticket by inclusion in the authenticator.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+For KDC-issued elements this is prevented because the elements are signed by
+the KDC by including a checksum encrypted using the server's key (the same
+key used to encrypt the ticket - or a key derived from that key). Elements
+encapsulated with in the KDC-issued element will be ignored by the
+application server if this "signature" is not present. Further, elements
+encapsulated within this element from a ticket granting ticket may be
+interpreted by the KDC, and used as a basis according to policy for
+including new signed elements within derivative tickets, but they will not
+be copied to a derivative ticket directly. If they are copied directly to a
+derivative ticket by a KDC that is not aware of this element, the signature
+will not be correct for the application ticket elements, and the field will
+be ignored by the application server.
+
+This element and the elements it encapulates may be safely ignored by
+applications, application servers, and KDCs that do not implement this
+element.
+
+B.2. Intended for server
+
+AD-INTENDED-FOR-SERVER SEQUENCE {
+ intended-server[0] SEQUENCE OF PrincipalName
+ elements[1] AuthorizationData
+}
+
+AD elements encapsulated within the intended-for-server element may be
+ignored if the application server is not in the list of principal names of
+intended servers. Further, a KDC issuing a ticket for an application server
+can remove this element if the application server is not in the list of
+intended servers.
+
+Application servers should check for their principal name in the
+intended-server field of this element. If their principal name is not found,
+this element should be ignored. If found, then the encapsulated elements
+should be evaluated in the same manner as if they were present in the top
+level authorization data field. Applications and application servers that do
+not implement this element should reject tickets that contain authorization
+data elements of this type.
+
+B.3. Intended for application class
+
+AD-INTENDED-FOR-APPLICATION-CLASS SEQUENCE { intended-application-class[0]
+SEQUENCE OF GeneralString elements[1] AuthorizationData } AD elements
+encapsulated within the intended-for-application-class element may be
+ignored if the application server is not in one of the named classes of
+application servers. Examples of application server classes include
+"FILESYSTEM", and other kinds of servers.
+
+This element and the elements it encapulates may be safely ignored by
+applications, application servers, and KDCs that do not implement this
+element.
+
+B.4. If relevant
+
+AD-IF-RELEVANT AuthorizationData
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+AD elements encapsulated within the if-relevant element are intended for
+interpretation only by application servers that understand the particular
+ad-type of the embedded element. Application servers that do not understand
+the type of an element embedded within the if-relevant element may ignore
+the uninterpretable element. This element promotes interoperability across
+implementations which may have local extensions for authorization.
+
+B.5. And-Or
+
+AD-AND-OR SEQUENCE {
+ condition-count[0] INTEGER,
+ elements[1] AuthorizationData
+}
+
+When restrictive AD elements encapsulated within the and-or element are
+encountered, only the number specified in condition-count of the
+encapsulated conditions must be met in order to satisfy this element. This
+element may be used to implement an "or" operation by setting the
+condition-count field to 1, and it may specify an "and" operation by setting
+the condition count to the number of embedded elements. Application servers
+that do not implement this element must reject tickets that contain
+authorization data elements of this type.
+
+B.6. Mandatory ticket extensions
+
+AD-Mandatory-Ticket-Extensions Checksum
+
+An authorization data element of type mandatory-ticket-extensions specifies
+a collision-proof checksum using the same has angorithm used to protect the
+integrity of the ticket itself. This checksum will be calculated over the
+entire extensions field. If there are more than one extension, all will be
+covered by the checksum. This restriction indicates that the ticket should
+not be accepted if the checksum does not match that calculated over the
+ticket extensions. Application servers that do not implement this element
+must reject tickets that contain authorization data elements of this type.
+
+B.7. Authorization Data in ticket extensions
+
+AD-IN-Ticket-Extensions Checksum
+
+An authorization data element of type in-ticket-extensions specifies a
+collision-proof checksum using the same has angorithm used to protect the
+integrity of the ticket itself. This checksum is calculated over a separate
+external AuthorizationData field carried in the ticket extensions.
+Application servers that do not implement this element must reject tickets
+that contain authorization data elements of this type. Application servers
+that do implement this element will search the ticket extensions for
+authorization data fields, calculate the specified checksum over each
+authorization data field and look for one matching the checksum in this
+in-ticket-extensions element. If not found, then the ticket must be
+rejected. If found, the corresponding authorization data elements will be
+interpreted in the same manner as if they were contained in the top level
+authorization data field.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+Note that if multiple external authorization data fields are present in a
+ticket, each will have a corresponding element of type in-ticket-extensions
+in the top level authorization data field, and the external entries will be
+linked to the corresponding element by their checksums.
+
+C. Definition of common ticket extensions
+
+This appendix contains the definitions of common ticket extensions. Support
+for these extensions is optional. However, certain extensions have
+associated authorization data elements that may require rejection of a
+ticket containing an extension by application servers that do not implement
+the particular extension. Other extensions have been defined beyond those
+described in this specification. Such extensions are described elswhere and
+for some of those extensions the reserved number may be found in the list of
+constants.
+
+It is known that older versions of Kerberos did not support this field, and
+that some clients will strip this field from a ticket when they parse and
+then reassemble a ticket as it is passed to the application servers. The
+presence of the extension will not break such clients, but any functionaly
+dependent on the extensions will not work when such tickets are handled by
+old clients. In such situations, some implementation may use alternate
+methods to transmit the information in the extensions field.
+
+C.1. Null ticket extension
+
+TE-NullExtension OctetString -- The empty Octet String
+
+The te-data field in the null ticket extension is an octet string of lenght
+zero. This extension may be included in a ticket granting ticket so that the
+KDC can determine on presentation of the ticket granting ticket whether the
+client software will strip the extensions field.
+
+C.2. External Authorization Data
+
+TE-ExternalAuthorizationData AuthorizationData
+
+The te-data field in the external authorization data ticket extension is
+field of type AuthorizationData containing one or more authorization data
+elements. If present, a corresponding authorization data element will be
+present in the primary authorization data for the ticket and that element
+will contain a checksum of the external authorization data ticket extension.
+----------------------------------------------------------------------------
+[TM] Project Athena, Athena, and Kerberos are trademarks of the
+Massachusetts Institute of Technology (MIT). No commercial use of these
+trademarks may be made without prior written permission of MIT.
+
+[1] Note, however, that many applications use Kerberos' functions only upon
+the initiation of a stream-based network connection. Unless an application
+subsequently provides integrity protection for the data stream, the identity
+verification applies only to the initiation of the connection, and does not
+guarantee that subsequent messages on the connection originate from the same
+principal.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+[2] Secret and private are often used interchangeably in the literature. In
+our usage, it takes two (or more) to share a secret, thus a shared DES key
+is a secret key. Something is only private when no one but its owner knows
+it. Thus, in public key cryptosystems, one has a public and a private key.
+
+[3] Of course, with appropriate permission the client could arrange
+registration of a separately-named prin- cipal in a remote realm, and engage
+in normal exchanges with that realm's services. However, for even small
+numbers of clients this becomes cumbersome, and more automatic methods as
+described here are necessary.
+
+[4] Though it is permissible to request or issue tick- ets with no network
+addresses specified.
+
+[5] The password-changing request must not be honored unless the requester
+can provide the old password (the user's current secret key). Otherwise, it
+would be possible for someone to walk up to an unattended ses- sion and
+change another user's password.
+
+[6] To authenticate a user logging on to a local system, the credentials
+obtained in the AS exchange may first be used in a TGS exchange to obtain
+credentials for a local server. Those credentials must then be verified by a
+local server through successful completion of the Client/Server exchange.
+
+[7] "Random" means that, among other things, it should be impossible to
+guess the next session key based on knowledge of past session keys. This can
+only be achieved in a pseudo-random number generator if it is based on
+cryptographic principles. It is more desirable to use a truly random number
+generator, such as one based on measurements of random physical phenomena.
+
+[8] Tickets contain both an encrypted and unencrypted portion, so cleartext
+here refers to the entire unit, which can be copied from one message and
+replayed in another without any cryptographic skill.
+
+[9] Note that this can make applications based on unreliable transports
+difficult to code correctly. If the transport might deliver duplicated
+messages, either a new authenticator must be generated for each retry, or
+the application server must match requests and replies and replay the first
+reply in response to a detected duplicate.
+
+[10] This is used for user-to-user authentication as described in [8].
+
+[11] Note that the rejection here is restricted to authenticators from the
+same principal to the same server. Other client principals communicating
+with the same server principal should not be have their authenticators
+rejected if the time and microsecond fields happen to match some other
+client's authenticator.
+
+[12] In the Kerberos version 4 protocol, the timestamp in the reply was the
+client's timestamp plus one. This is not necessary in version 5 because
+version 5 messages are formatted in such a way that it is not possible to
+create the reply by judicious message surgery (even in encrypted form)
+without knowledge of the appropriate encryption keys.
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+
+[13] Note that for encrypting the KRB_AP_REP message, the sub-session key is
+not used, even if present in the Authenticator.
+
+[14] Implementations of the protocol may wish to provide routines to choose
+subkeys based on session keys and random numbers and to generate a
+negotiated key to be returned in the KRB_AP_REP message.
+
+[15]This can be accomplished in several ways. It might be known beforehand
+(since the realm is part of the principal identifier), it might be stored in
+a nameserver, or it might be obtained from a configura- tion file. If the
+realm to be used is obtained from a nameserver, there is a danger of being
+spoofed if the nameservice providing the realm name is not authenti- cated.
+This might result in the use of a realm which has been compromised, and
+would result in an attacker's ability to compromise the authentication of
+the application server to the client.
+
+[16] If the client selects a sub-session key, care must be taken to ensure
+the randomness of the selected sub- session key. One approach would be to
+generate a random number and XOR it with the session key from the
+ticket-granting ticket.
+
+[17] This allows easy implementation of user-to-user authentication [8],
+which uses ticket-granting ticket session keys in lieu of secret server keys
+in situa- tions where such secret keys could be easily comprom- ised.
+
+[18] For the purpose of appending, the realm preceding the first listed
+realm is considered to be the null realm ("").
+
+[19] For the purpose of interpreting null subfields, the client's realm is
+considered to precede those in the transited field, and the server's realm
+is considered to follow them.
+
+[20] This means that a client and server running on the same host and
+communicating with one another using the KRB_SAFE messages should not share
+a common replay cache to detect KRB_SAFE replays.
+
+[21] The implementation of the Kerberos server need not combine the database
+and the server on the same machine; it is feasible to store the principal
+database in, say, a network name service, as long as the entries stored
+therein are protected from disclosure to and modification by unauthorized
+parties. However, we recommend against such strategies, as they can make
+system management and threat analysis quite complex.
+
+[22] See the discussion of the padata field in section 5.4.2 for details on
+why this can be useful.
+
+[23] Warning for implementations that unpack and repack data structures
+during the generation and verification of embedded checksums: Because any
+checksums applied to data structures must be checked against the original
+data the length of bit strings must be preserved within a data structure
+between the time that a checksum is generated through transmission to the
+time that the checksum is verified.
+
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+[24] It is NOT recommended that this time value be used to adjust the
+workstation's clock since the workstation cannot reliably determine that
+such a KRB_AS_REP actually came from the proper KDC in a timely manner.
+
+[25] Note, however, that if the time is used as the nonce, one must make
+sure that the workstation time is monotonically increasing. If the time is
+ever reset backwards, there is a small, but finite, probability that a nonce
+will be reused.
+
+[27] An application code in the encrypted part of a message provides an
+additional check that the message was decrypted properly.
+
+[29] An application code in the encrypted part of a message provides an
+additional check that the message was decrypted properly.
+
+[31] An application code in the encrypted part of a message provides an
+additional check that the message was decrypted properly.
+
+[32] If supported by the encryption method in use, an initialization vector
+may be passed to the encryption procedure, in order to achieve proper cipher
+chaining. The initialization vector might come from the last block of the
+ciphertext from the previous KRB_PRIV message, but it is the application's
+choice whether or not to use such an initialization vector. If left out, the
+default initialization vector for the encryption algorithm will be used.
+
+[33] This prevents an attacker who generates an incorrect AS request from
+obtaining verifiable plaintext for use in an off-line password guessing
+attack.
+
+[35] In the above specification, UNTAGGED OCTET STRING(length) is the
+notation for an octet string with its tag and length removed. It is not a
+valid ASN.1 type. The tag bits and length must be removed from the
+confounder since the purpose of the confounder is so that the message starts
+with random data, but the tag and its length are fixed. For other fields,
+the length and tag would be redundant if they were included because they are
+specified by the encryption type. [36] The ordering of the fields in the
+CipherText is important. Additionally, messages encoded in this format must
+include a length as part of the msg-seq field. This allows the recipient to
+verify that the message has not been truncated. Without a length, an
+attacker could use a chosen plaintext attack to generate a message which
+could be truncated, while leaving the checksum intact. Note that if the
+msg-seq is an encoding of an ASN.1 SEQUENCE or OCTET STRING, then the length
+is part of that encoding.
+
+[37] In some cases, it may be necessary to use a different "mix-in" string
+for compatibility reasons; see the discussion of padata in section 5.4.2.
+
+[38] In some cases, it may be necessary to use a different "mix-in" string
+for compatibility reasons; see the discussion of padata in section 5.4.2.
+
+[39] A variant of the key is used to limit the use of a key to a particular
+function, separating the functions of generating a checksum from other
+encryption performed using the session key. The constant F0F0F0F0F0F0F0F0
+was chosen because it maintains key parity. The properties of DES precluded
+
+
+draft-ietf-cat-kerberos-r-01 Expires 21 May 1998
+
+the use of the complement. The same constant is used for similar purpose in
+the Message Integrity Check in the Privacy Enhanced Mail standard.
+
+[40] This error carries additional information in the e- data field. The
+contents of the e-data field for this message is described in section 5.9.1.
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-03.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-03.txt
new file mode 100644
index 000000000000..06d997d48cca
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-03.txt
@@ -0,0 +1,6766 @@
+
+
+
+INTERNET-DRAFT Clifford Neuman
+ John Kohl
+ Theodore Ts'o
+ November 18th, 1998
+
+The Kerberos Network Authentication Service (V5)
+
+STATUS OF THIS MEMO
+
+This document is an Internet-Draft. Internet-Drafts are working documents
+of the Internet Engineering Task Force (IETF), its areas, and its working
+groups. Note that other groups may also distribute working documents as
+Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum of six months and
+may be updated, replaced, or obsoleted by other documents at any time. It
+is inappropriate to use Internet-Drafts as reference material or to cite
+them other than as 'work in progress.'
+
+To learn the current status of any Internet-Draft, please check the
+'1id-abstracts.txt' listing contained in the Internet-Drafts Shadow
+Directories on ftp.ietf.org (US East Coast), nic.nordu.net (Europe),
+ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific Rim).
+
+The distribution of this memo is unlimited. It is filed as
+draft-ietf-cat-kerberos-revisions-03.txt, and expires May 18th, 1999.
+Please send comments to: krb-protocol@MIT.EDU
+
+ABSTRACT
+
+This document provides an overview and specification of Version 5 of the
+Kerberos protocol, and updates RFC1510 to clarify aspects of the protocol
+and its intended use that require more detailed or clearer explanation than
+was provided in RFC1510. This document is intended to provide a detailed
+description of the protocol, suitable for implementation, together with
+descriptions of the appropriate use of protocol messages and fields within
+those messages.
+
+This document is not intended to describe Kerberos to the end user, system
+administrator, or application developer. Higher level papers describing
+Version 5 of the Kerberos system [NT94] and documenting version 4 [SNS88],
+are available elsewhere.
+
+OVERVIEW
+
+This INTERNET-DRAFT describes the concepts and model upon which the
+Kerberos network authentication system is based. It also specifies Version
+5 of the Kerberos protocol.
+
+The motivations, goals, assumptions, and rationale behind most design
+decisions are treated cursorily; they are more fully described in a paper
+available in IEEE communications [NT94] and earlier in the Kerberos portion
+of the Athena Technical Plan [MNSS87]. The protocols have been a proposed
+standard and are being considered for advancement for draft standard
+through the IETF standard process. Comments are encouraged on the
+presentation, but only minor refinements to the protocol as implemented or
+extensions that fit within current protocol framework will be considered at
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+this time.
+
+Requests for addition to an electronic mailing list for discussion of
+Kerberos, kerberos@MIT.EDU, may be addressed to kerberos-request@MIT.EDU.
+This mailing list is gatewayed onto the Usenet as the group
+comp.protocols.kerberos. Requests for further information, including
+documents and code availability, may be sent to info-kerberos@MIT.EDU.
+
+BACKGROUND
+
+The Kerberos model is based in part on Needham and Schroeder's trusted
+third-party authentication protocol [NS78] and on modifications suggested
+by Denning and Sacco [DS81]. The original design and implementation of
+Kerberos Versions 1 through 4 was the work of two former Project Athena
+staff members, Steve Miller of Digital Equipment Corporation and Clifford
+Neuman (now at the Information Sciences Institute of the University of
+Southern California), along with Jerome Saltzer, Technical Director of
+Project Athena, and Jeffrey Schiller, MIT Campus Network Manager. Many
+other members of Project Athena have also contributed to the work on
+Kerberos.
+
+Version 5 of the Kerberos protocol (described in this document) has evolved
+from Version 4 based on new requirements and desires for features not
+available in Version 4. The design of Version 5 of the Kerberos protocol
+was led by Clifford Neuman and John Kohl with much input from the
+community. The development of the MIT reference implementation was led at
+MIT by John Kohl and Theodore T'so, with help and contributed code from
+many others. Since RFC1510 was issued, extensions and revisions to the
+protocol have been proposed by many individuals. Some of these proposals
+are reflected in this document. Where such changes involved significant
+effort, the document cites the contribution of the proposer.
+
+Reference implementations of both version 4 and version 5 of Kerberos are
+publicly available and commercial implementations have been developed and
+are widely used. Details on the differences between Kerberos Versions 4 and
+5 can be found in [KNT92].
+
+1. Introduction
+
+Kerberos provides a means of verifying the identities of principals, (e.g.
+a workstation user or a network server) on an open (unprotected) network.
+This is accomplished without relying on assertions by the host operating
+system, without basing trust on host addresses, without requiring physical
+security of all the hosts on the network, and under the assumption that
+packets traveling along the network can be read, modified, and inserted at
+will[1]. Kerberos performs authentication under these conditions as a
+trusted third-party authentication service by using conventional (shared
+secret key [2] cryptography. Kerberos extensions have been proposed and
+implemented that provide for the use of public key cryptography during
+certain phases of the authentication protocol. These extensions provide for
+authentication of users registered with public key certification
+authorities, and allow the system to provide certain benefits of public key
+cryptography in situations where they are needed.
+
+The basic Kerberos authentication process proceeds as follows: A client
+sends a request to the authentication server (AS) requesting 'credentials'
+for a given server. The AS responds with these credentials, encrypted in
+the client's key. The credentials consist of 1) a 'ticket' for the server
+and 2) a temporary encryption key (often called a "session key"). The
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+client transmits the ticket (which contains the client's identity and a
+copy of the session key, all encrypted in the server's key) to the server.
+The session key (now shared by the client and server) is used to
+authenticate the client, and may optionally be used to authenticate the
+server. It may also be used to encrypt further communication between the
+two parties or to exchange a separate sub-session key to be used to encrypt
+further communication.
+
+Implementation of the basic protocol consists of one or more authentication
+servers running on physically secure hosts. The authentication servers
+maintain a database of principals (i.e., users and servers) and their
+secret keys. Code libraries provide encryption and implement the Kerberos
+protocol. In order to add authentication to its transactions, a typical
+network application adds one or two calls to the Kerberos library directly
+or through the Generic Security Services Application Programming Interface,
+GSSAPI, described in separate document. These calls result in the
+transmission of the necessary messages to achieve authentication.
+
+The Kerberos protocol consists of several sub-protocols (or exchanges).
+There are two basic methods by which a client can ask a Kerberos server for
+credentials. In the first approach, the client sends a cleartext request
+for a ticket for the desired server to the AS. The reply is sent encrypted
+in the client's secret key. Usually this request is for a ticket-granting
+ticket (TGT) which can later be used with the ticket-granting server (TGS).
+In the second method, the client sends a request to the TGS. The client
+uses the TGT to authenticate itself to the TGS in the same manner as if it
+were contacting any other application server that requires Kerberos
+authentication. The reply is encrypted in the session key from the TGT.
+Though the protocol specification describes the AS and the TGS as separate
+servers, they are implemented in practice as different protocol entry
+points within a single Kerberos server.
+
+Once obtained, credentials may be used to verify the identity of the
+principals in a transaction, to ensure the integrity of messages exchanged
+between them, or to preserve privacy of the messages. The application is
+free to choose whatever protection may be necessary.
+
+To verify the identities of the principals in a transaction, the client
+transmits the ticket to the application server. Since the ticket is sent
+"in the clear" (parts of it are encrypted, but this encryption doesn't
+thwart replay) and might be intercepted and reused by an attacker,
+additional information is sent to prove that the message originated with
+the principal to whom the ticket was issued. This information (called the
+authenticator) is encrypted in the session key, and includes a timestamp.
+The timestamp proves that the message was recently generated and is not a
+replay. Encrypting the authenticator in the session key proves that it was
+generated by a party possessing the session key. Since no one except the
+requesting principal and the server know the session key (it is never sent
+over the network in the clear) this guarantees the identity of the client.
+
+The integrity of the messages exchanged between principals can also be
+guaranteed using the session key (passed in the ticket and contained in the
+credentials). This approach provides detection of both replay attacks and
+message stream modification attacks. It is accomplished by generating and
+transmitting a collision-proof checksum (elsewhere called a hash or digest
+function) of the client's message, keyed with the session key. Privacy and
+integrity of the messages exchanged between principals can be secured by
+encrypting the data to be passed using the session key contained in the
+ticket or the subsession key found in the authenticator.
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+The authentication exchanges mentioned above require read-only access to
+the Kerberos database. Sometimes, however, the entries in the database must
+be modified, such as when adding new principals or changing a principal's
+key. This is done using a protocol between a client and a third Kerberos
+server, the Kerberos Administration Server (KADM). There is also a protocol
+for maintaining multiple copies of the Kerberos database. Neither of these
+protocols are described in this document.
+
+1.1. Cross-Realm Operation
+
+The Kerberos protocol is designed to operate across organizational
+boundaries. A client in one organization can be authenticated to a server
+in another. Each organization wishing to run a Kerberos server establishes
+its own 'realm'. The name of the realm in which a client is registered is
+part of the client's name, and can be used by the end-service to decide
+whether to honor a request.
+
+By establishing 'inter-realm' keys, the administrators of two realms can
+allow a client authenticated in the local realm to prove its identity to
+servers in other realms[3]. The exchange of inter-realm keys (a separate
+key may be used for each direction) registers the ticket-granting service
+of each realm as a principal in the other realm. A client is then able to
+obtain a ticket-granting ticket for the remote realm's ticket-granting
+service from its local realm. When that ticket-granting ticket is used, the
+remote ticket-granting service uses the inter-realm key (which usually
+differs from its own normal TGS key) to decrypt the ticket-granting ticket,
+and is thus certain that it was issued by the client's own TGS. Tickets
+issued by the remote ticket-granting service will indicate to the
+end-service that the client was authenticated from another realm.
+
+A realm is said to communicate with another realm if the two realms share
+an inter-realm key, or if the local realm shares an inter-realm key with an
+intermediate realm that communicates with the remote realm. An
+authentication path is the sequence of intermediate realms that are
+transited in communicating from one realm to another.
+
+Realms are typically organized hierarchically. Each realm shares a key with
+its parent and a different key with each child. If an inter-realm key is
+not directly shared by two realms, the hierarchical organization allows an
+authentication path to be easily constructed. If a hierarchical
+organization is not used, it may be necessary to consult a database in
+order to construct an authentication path between realms.
+
+Although realms are typically hierarchical, intermediate realms may be
+bypassed to achieve cross-realm authentication through alternate
+authentication paths (these might be established to make communication
+between two realms more efficient). It is important for the end-service to
+know which realms were transited when deciding how much faith to place in
+the authentication process. To facilitate this decision, a field in each
+ticket contains the names of the realms that were involved in
+authenticating the client.
+
+The application server is ultimately responsible for accepting or rejecting
+authentication and should check the transited field. The application server
+may choose to rely on the KDC for the application server's realm to check
+the transited field. The application server's KDC will set the
+TRANSITED-POLICY-CHECKED flag in this case. The KDC's for intermediate
+realms may also check the transited field as they issue
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ticket-granting-tickets for other realms, but they are encouraged not to do
+so. A client may request that the KDC's not check the transited field by
+setting the DISABLE-TRANSITED-CHECK flag. KDC's are encouraged but not
+required to honor this flag.
+
+1.2. Authorization
+
+As an authentication service, Kerberos provides a means of verifying the
+identity of principals on a network. Authentication is usually useful
+primarily as a first step in the process of authorization, determining
+whether a client may use a service, which objects the client is allowed to
+access, and the type of access allowed for each. Kerberos does not, by
+itself, provide authorization. Possession of a client ticket for a service
+provides only for authentication of the client to that service, and in the
+absence of a separate authorization procedure, it should not be considered
+by an application as authorizing the use of that service.
+
+Such separate authorization methods may be implemented as application
+specific access control functions and may be based on files such as the
+application server, or on separately issued authorization credentials such
+as those based on proxies [Neu93] , or on other authorization services.
+
+Applications should not be modified to accept the issuance of a service
+ticket by the Kerberos server (even by an modified Kerberos server) as
+granting authority to use the service, since such applications may become
+vulnerable to the bypass of this authorization check in an environment if
+they interoperate with other KDCs or where other options for application
+authentication (e.g. the PKTAPP proposal) are provided.
+
+1.3. Environmental assumptions
+
+Kerberos imposes a few assumptions on the environment in which it can
+properly function:
+
+ * 'Denial of service' attacks are not solved with Kerberos. There are
+ places in these protocols where an intruder can prevent an application
+ from participating in the proper authentication steps. Detection and
+ solution of such attacks (some of which can appear to be nnot-uncommon
+ 'normal' failure modes for the system) is usually best left to the
+ human administrators and users.
+ * Principals must keep their secret keys secret. If an intruder somehow
+ steals a principal's key, it will be able to masquerade as that
+ principal or impersonate any server to the legitimate principal.
+ * 'Password guessing' attacks are not solved by Kerberos. If a user
+ chooses a poor password, it is possible for an attacker to
+ successfully mount an offline dictionary attack by repeatedly
+ attempting to decrypt, with successive entries from a dictionary,
+ messages obtained which are encrypted under a key derived from the
+ user's password.
+ * Each host on the network must have a clock which is 'loosely
+ synchronized' to the time of the other hosts; this synchronization is
+ used to reduce the bookkeeping needs of application servers when they
+ do replay detection. The degree of "looseness" can be configured on a
+ per-server basis, but is typically on the order of 5 minutes. If the
+ clocks are synchronized over the network, the clock synchronization
+ protocol must itself be secured from network attackers.
+ * Principal identifiers are not recycled on a short-term basis. A
+ typical mode of access control will use access control lists (ACLs) to
+ grant permissions to particular principals. If a stale ACL entry
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ remains for a deleted principal and the principal identifier is
+ reused, the new principal will inherit rights specified in the stale
+ ACL entry. By not re-using principal identifiers, the danger of
+ inadvertent access is removed.
+
+1.4. Glossary of terms
+
+Below is a list of terms used throughout this document.
+
+Authentication
+ Verifying the claimed identity of a principal.
+Authentication header
+ A record containing a Ticket and an Authenticator to be presented to a
+ server as part of the authentication process.
+Authentication path
+ A sequence of intermediate realms transited in the authentication
+ process when communicating from one realm to another.
+Authenticator
+ A record containing information that can be shown to have been
+ recently generated using the session key known only by the client and
+ server.
+Authorization
+ The process of determining whether a client may use a service, which
+ objects the client is allowed to access, and the type of access
+ allowed for each.
+Capability
+ A token that grants the bearer permission to access an object or
+ service. In Kerberos, this might be a ticket whose use is restricted
+ by the contents of the authorization data field, but which lists no
+ network addresses, together with the session key necessary to use the
+ ticket.
+Ciphertext
+ The output of an encryption function. Encryption transforms plaintext
+ into ciphertext.
+Client
+ A process that makes use of a network service on behalf of a user.
+ Note that in some cases a Server may itself be a client of some other
+ server (e.g. a print server may be a client of a file server).
+Credentials
+ A ticket plus the secret session key necessary to successfully use
+ that ticket in an authentication exchange.
+KDC
+ Key Distribution Center, a network service that supplies tickets and
+ temporary session keys; or an instance of that service or the host on
+ which it runs. The KDC services both initial ticket and
+ ticket-granting ticket requests. The initial ticket portion is
+ sometimes referred to as the Authentication Server (or service). The
+ ticket-granting ticket portion is sometimes referred to as the
+ ticket-granting server (or service).
+Kerberos
+ Aside from the 3-headed dog guarding Hades, the name given to Project
+ Athena's authentication service, the protocol used by that service, or
+ the code used to implement the authentication service.
+Plaintext
+ The input to an encryption function or the output of a decryption
+ function. Decryption transforms ciphertext into plaintext.
+Principal
+ A uniquely named client or server instance that participates in a
+ network communication.
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+Principal identifier
+ The name used to uniquely identify each different principal.
+Seal
+ To encipher a record containing several fields in such a way that the
+ fields cannot be individually replaced without either knowledge of the
+ encryption key or leaving evidence of tampering.
+Secret key
+ An encryption key shared by a principal and the KDC, distributed
+ outside the bounds of the system, with a long lifetime. In the case of
+ a human user's principal, the secret key is derived from a password.
+Server
+ A particular Principal which provides a resource to network clients.
+ The server is sometimes refered to as the Application Server.
+Service
+ A resource provided to network clients; often provided by more than
+ one server (for example, remote file service).
+Session key
+ A temporary encryption key used between two principals, with a
+ lifetime limited to the duration of a single login "session".
+Sub-session key
+ A temporary encryption key used between two principals, selected and
+ exchanged by the principals using the session key, and with a lifetime
+ limited to the duration of a single association.
+Ticket
+ A record that helps a client authenticate itself to a server; it
+ contains the client's identity, a session key, a timestamp, and other
+ information, all sealed using the server's secret key. It only serves
+ to authenticate a client when presented along with a fresh
+ Authenticator.
+
+2. Ticket flag uses and requests
+
+Each Kerberos ticket contains a set of flags which are used to indicate
+various attributes of that ticket. Most flags may be requested by a client
+when the ticket is obtained; some are automatically turned on and off by a
+Kerberos server as required. The following sections explain what the
+various flags mean, and gives examples of reasons to use such a flag.
+
+2.1. Initial and pre-authenticated tickets
+
+The INITIAL flag indicates that a ticket was issued using the AS protocol
+and not issued based on a ticket-granting ticket. Application servers that
+want to require the demonstrated knowledge of a client's secret key (e.g. a
+password-changing program) can insist that this flag be set in any tickets
+they accept, and thus be assured that the client's key was recently
+presented to the application client.
+
+The PRE-AUTHENT and HW-AUTHENT flags provide addition information about the
+initial authentication, regardless of whether the current ticket was issued
+directly (in which case INITIAL will also be set) or issued on the basis of
+a ticket-granting ticket (in which case the INITIAL flag is clear, but the
+PRE-AUTHENT and HW-AUTHENT flags are carried forward from the
+ticket-granting ticket).
+
+2.2. Invalid tickets
+
+The INVALID flag indicates that a ticket is invalid. Application servers
+must reject tickets which have this flag set. A postdated ticket will
+usually be issued in this form. Invalid tickets must be validated by the
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+KDC before use, by presenting them to the KDC in a TGS request with the
+VALIDATE option specified. The KDC will only validate tickets after their
+starttime has passed. The validation is required so that postdated tickets
+which have been stolen before their starttime can be rendered permanently
+invalid (through a hot-list mechanism) (see section 3.3.3.1).
+
+2.3. Renewable tickets
+
+Applications may desire to hold tickets which can be valid for long periods
+of time. However, this can expose their credentials to potential theft for
+equally long periods, and those stolen credentials would be valid until the
+expiration time of the ticket(s). Simply using short-lived tickets and
+obtaining new ones periodically would require the client to have long-term
+access to its secret key, an even greater risk. Renewable tickets can be
+used to mitigate the consequences of theft. Renewable tickets have two
+"expiration times": the first is when the current instance of the ticket
+expires, and the second is the latest permissible value for an individual
+expiration time. An application client must periodically (i.e. before it
+expires) present a renewable ticket to the KDC, with the RENEW option set
+in the KDC request. The KDC will issue a new ticket with a new session key
+and a later expiration time. All other fields of the ticket are left
+unmodified by the renewal process. When the latest permissible expiration
+time arrives, the ticket expires permanently. At each renewal, the KDC may
+consult a hot-list to determine if the ticket had been reported stolen
+since its last renewal; it will refuse to renew such stolen tickets, and
+thus the usable lifetime of stolen tickets is reduced.
+
+The RENEWABLE flag in a ticket is normally only interpreted by the
+ticket-granting service (discussed below in section 3.3). It can usually be
+ignored by application servers. However, some particularly careful
+application servers may wish to disallow renewable tickets.
+
+If a renewable ticket is not renewed by its expiration time, the KDC will
+not renew the ticket. The RENEWABLE flag is reset by default, but a client
+may request it be set by setting the RENEWABLE option in the KRB_AS_REQ
+message. If it is set, then the renew-till field in the ticket contains the
+time after which the ticket may not be renewed.
+
+2.4. Postdated tickets
+
+Applications may occasionally need to obtain tickets for use much later,
+e.g. a batch submission system would need tickets to be valid at the time
+the batch job is serviced. However, it is dangerous to hold valid tickets
+in a batch queue, since they will be on-line longer and more prone to
+theft. Postdated tickets provide a way to obtain these tickets from the KDC
+at job submission time, but to leave them "dormant" until they are
+activated and validated by a further request of the KDC. If a ticket theft
+were reported in the interim, the KDC would refuse to validate the ticket,
+and the thief would be foiled.
+
+The MAY-POSTDATE flag in a ticket is normally only interpreted by the
+ticket-granting service. It can be ignored by application servers. This
+flag must be set in a ticket-granting ticket in order to issue a postdated
+ticket based on the presented ticket. It is reset by default; it may be
+requested by a client by setting the ALLOW-POSTDATE option in the
+KRB_AS_REQ message. This flag does not allow a client to obtain a postdated
+ticket-granting ticket; postdated ticket-granting tickets can only by
+obtained by requesting the postdating in the KRB_AS_REQ message. The life
+(endtime-starttime) of a postdated ticket will be the remaining life of the
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ticket-granting ticket at the time of the request, unless the RENEWABLE
+option is also set, in which case it can be the full life
+(endtime-starttime) of the ticket-granting ticket. The KDC may limit how
+far in the future a ticket may be postdated.
+
+The POSTDATED flag indicates that a ticket has been postdated. The
+application server can check the authtime field in the ticket to see when
+the original authentication occurred. Some services may choose to reject
+postdated tickets, or they may only accept them within a certain period
+after the original authentication. When the KDC issues a POSTDATED ticket,
+it will also be marked as INVALID, so that the application client must
+present the ticket to the KDC to be validated before use.
+
+2.5. Proxiable and proxy tickets
+
+At times it may be necessary for a principal to allow a service to perform
+an operation on its behalf. The service must be able to take on the
+identity of the client, but only for a particular purpose. A principal can
+allow a service to take on the principal's identity for a particular
+purpose by granting it a proxy.
+
+The process of granting a proxy using the proxy and proxiable flags is used
+to provide credentials for use with specific services. Though conceptually
+also a proxy, user's wishing to delegate their identity for ANY purpose
+must use the ticket forwarding mechanism described in the next section to
+forward a ticket granting ticket.
+
+The PROXIABLE flag in a ticket is normally only interpreted by the
+ticket-granting service. It can be ignored by application servers. When
+set, this flag tells the ticket-granting server that it is OK to issue a
+new ticket (but not a ticket-granting ticket) with a different network
+address based on this ticket. This flag is set if requested by the client
+on initial authentication. By default, the client will request that it be
+set when requesting a ticket granting ticket, and reset when requesting any
+other ticket.
+
+This flag allows a client to pass a proxy to a server to perform a remote
+request on its behalf, e.g. a print service client can give the print
+server a proxy to access the client's files on a particular file server in
+order to satisfy a print request.
+
+In order to complicate the use of stolen credentials, Kerberos tickets are
+usually valid from only those network addresses specifically included in
+the ticket[4]. When granting a proxy, the client must specify the new
+network address from which the proxy is to be used, or indicate that the
+proxy is to be issued for use from any address.
+
+The PROXY flag is set in a ticket by the TGS when it issues a proxy ticket.
+Application servers may check this flag and at their option they may
+require additional authentication from the agent presenting the proxy in
+order to provide an audit trail.
+
+2.6. Forwardable tickets
+
+Authentication forwarding is an instance of a proxy where the service is
+granted complete use of the client's identity. An example where it might be
+used is when a user logs in to a remote system and wants authentication to
+work from that system as if the login were local.
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+The FORWARDABLE flag in a ticket is normally only interpreted by the
+ticket-granting service. It can be ignored by application servers. The
+FORWARDABLE flag has an interpretation similar to that of the PROXIABLE
+flag, except ticket-granting tickets may also be issued with different
+network addresses. This flag is reset by default, but users may request
+that it be set by setting the FORWARDABLE option in the AS request when
+they request their initial ticket- granting ticket.
+
+This flag allows for authentication forwarding without requiring the user
+to enter a password again. If the flag is not set, then authentication
+forwarding is not permitted, but the same result can still be achieved if
+the user engages in the AS exchange specifying the requested network
+addresses and supplies a password.
+
+The FORWARDED flag is set by the TGS when a client presents a ticket with
+the FORWARDABLE flag set and requests a forwarded ticket by specifying the
+FORWARDED KDC option and supplying a set of addresses for the new ticket.
+It is also set in all tickets issued based on tickets with the FORWARDED
+flag set. Application servers may choose to process FORWARDED tickets
+differently than non-FORWARDED tickets.
+
+2.7. Other KDC options
+
+There are two additional options which may be set in a client's request of
+the KDC. The RENEWABLE-OK option indicates that the client will accept a
+renewable ticket if a ticket with the requested life cannot otherwise be
+provided. If a ticket with the requested life cannot be provided, then the
+KDC may issue a renewable ticket with a renew-till equal to the the
+requested endtime. The value of the renew-till field may still be adjusted
+by site-determined limits or limits imposed by the individual principal or
+server.
+
+The ENC-TKT-IN-SKEY option is honored only by the ticket-granting service.
+It indicates that the ticket to be issued for the end server is to be
+encrypted in the session key from the a additional second ticket-granting
+ticket provided with the request. See section 3.3.3 for specific details.
+
+3. Message Exchanges
+
+The following sections describe the interactions between network clients
+and servers and the messages involved in those exchanges.
+
+3.1. The Authentication Service Exchange
+
+ Summary
+ Message direction Message type Section
+ 1. Client to Kerberos KRB_AS_REQ 5.4.1
+ 2. Kerberos to client KRB_AS_REP or 5.4.2
+ KRB_ERROR 5.9.1
+
+The Authentication Service (AS) Exchange between the client and the
+Kerberos Authentication Server is initiated by a client when it wishes to
+obtain authentication credentials for a given server but currently holds no
+credentials. In its basic form, the client's secret key is used for
+encryption and decryption. This exchange is typically used at the
+initiation of a login session to obtain credentials for a Ticket-Granting
+Server which will subsequently be used to obtain credentials for other
+servers (see section 3.3) without requiring further use of the client's
+secret key. This exchange is also used to request credentials for services
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+which must not be mediated through the Ticket-Granting Service, but rather
+require a principal's secret key, such as the password-changing service[5].
+This exchange does not by itself provide any assurance of the the identity
+of the user[6].
+
+The exchange consists of two messages: KRB_AS_REQ from the client to
+Kerberos, and KRB_AS_REP or KRB_ERROR in reply. The formats for these
+messages are described in sections 5.4.1, 5.4.2, and 5.9.1.
+
+In the request, the client sends (in cleartext) its own identity and the
+identity of the server for which it is requesting credentials. The
+response, KRB_AS_REP, contains a ticket for the client to present to the
+server, and a session key that will be shared by the client and the server.
+The session key and additional information are encrypted in the client's
+secret key. The KRB_AS_REP message contains information which can be used
+to detect replays, and to associate it with the message to which it
+replies. Various errors can occur; these are indicated by an error response
+(KRB_ERROR) instead of the KRB_AS_REP response. The error message is not
+encrypted. The KRB_ERROR message contains information which can be used to
+associate it with the message to which it replies. The lack of encryption
+in the KRB_ERROR message precludes the ability to detect replays,
+fabrications, or modifications of such messages.
+
+Without preautentication, the authentication server does not know whether
+the client is actually the principal named in the request. It simply sends
+a reply without knowing or caring whether they are the same. This is
+acceptable because nobody but the principal whose identity was given in the
+request will be able to use the reply. Its critical information is
+encrypted in that principal's key. The initial request supports an optional
+field that can be used to pass additional information that might be needed
+for the initial exchange. This field may be used for preauthentication as
+described in section [hl<>].
+
+3.1.1. Generation of KRB_AS_REQ message
+
+The client may specify a number of options in the initial request. Among
+these options are whether pre-authentication is to be performed; whether
+the requested ticket is to be renewable, proxiable, or forwardable; whether
+it should be postdated or allow postdating of derivative tickets; and
+whether a renewable ticket will be accepted in lieu of a non-renewable
+ticket if the requested ticket expiration date cannot be satisfied by a
+non-renewable ticket (due to configuration constraints; see section 4). See
+section A.1 for pseudocode.
+
+The client prepares the KRB_AS_REQ message and sends it to the KDC.
+
+3.1.2. Receipt of KRB_AS_REQ message
+
+If all goes well, processing the KRB_AS_REQ message will result in the
+creation of a ticket for the client to present to the server. The format
+for the ticket is described in section 5.3.1. The contents of the ticket
+are determined as follows.
+
+3.1.3. Generation of KRB_AS_REP message
+
+The authentication server looks up the client and server principals named
+in the KRB_AS_REQ in its database, extracting their respective keys. If
+required, the server pre-authenticates the request, and if the
+pre-authentication check fails, an error message with the code
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+KDC_ERR_PREAUTH_FAILED is returned. If the server cannot accommodate the
+requested encryption type, an error message with code KDC_ERR_ETYPE_NOSUPP
+is returned. Otherwise it generates a 'random' session key[7].
+
+If there are multiple encryption keys registered for a client in the
+Kerberos database (or if the key registered supports multiple encryption
+types; e.g. DES-CBC-CRC and DES-CBC-MD5), then the etype field from the AS
+request is used by the KDC to select the encryption method to be used for
+encrypting the response to the client. If there is more than one supported,
+strong encryption type in the etype list, the first valid etype for which
+an encryption key is available is used. The encryption method used to
+respond to a TGS request is taken from the keytype of the session key found
+in the ticket granting ticket.
+
+When the etype field is present in a KDC request, whether an AS or TGS
+request, the KDC will attempt to assign the type of the random session key
+from the list of methods in the etype field. The KDC will select the
+appropriate type using the list of methods provided together with
+information from the Kerberos database indicating acceptable encryption
+methods for the application server. The KDC will not issue tickets with a
+weak session key encryption type.
+
+If the requested start time is absent, indicates a time in the past, or is
+within the window of acceptable clock skew for the KDC and the POSTDATE
+option has not been specified, then the start time of the ticket is set to
+the authentication server's current time. If it indicates a time in the
+future beyond the acceptable clock skew, but the POSTDATED option has not
+been specified then the error KDC_ERR_CANNOT_POSTDATE is returned.
+Otherwise the requested start time is checked against the policy of the
+local realm (the administrator might decide to prohibit certain types or
+ranges of postdated tickets), and if acceptable, the ticket's start time is
+set as requested and the INVALID flag is set in the new ticket. The
+postdated ticket must be validated before use by presenting it to the KDC
+after the start time has been reached.
+
+The expiration time of the ticket will be set to the minimum of the
+following:
+
+ * The expiration time (endtime) requested in the KRB_AS_REQ message.
+ * The ticket's start time plus the maximum allowable lifetime associated
+ with the client principal (the authentication server's database
+ includes a maximum ticket lifetime field in each principal's record;
+ see section 4).
+ * The ticket's start time plus the maximum allowable lifetime associated
+ with the server principal.
+ * The ticket's start time plus the maximum lifetime set by the policy of
+ the local realm.
+
+If the requested expiration time minus the start time (as determined above)
+is less than a site-determined minimum lifetime, an error message with code
+KDC_ERR_NEVER_VALID is returned. If the requested expiration time for the
+ticket exceeds what was determined as above, and if the 'RENEWABLE-OK'
+option was requested, then the 'RENEWABLE' flag is set in the new ticket,
+and the renew-till value is set as if the 'RENEWABLE' option were requested
+(the field and option names are described fully in section 5.4.1).
+
+If the RENEWABLE option has been requested or if the RENEWABLE-OK option
+has been set and a renewable ticket is to be issued, then the renew-till
+field is set to the minimum of:
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+ * Its requested value.
+ * The start time of the ticket plus the minimum of the two maximum
+ renewable lifetimes associated with the principals' database entries.
+ * The start time of the ticket plus the maximum renewable lifetime set
+ by the policy of the local realm.
+
+The flags field of the new ticket will have the following options set if
+they have been requested and if the policy of the local realm allows:
+FORWARDABLE, MAY-POSTDATE, POSTDATED, PROXIABLE, RENEWABLE. If the new
+ticket is post-dated (the start time is in the future), its INVALID flag
+will also be set.
+
+If all of the above succeed, the server formats a KRB_AS_REP message (see
+section 5.4.2), copying the addresses in the request into the caddr of the
+response, placing any required pre-authentication data into the padata of
+the response, and encrypts the ciphertext part in the client's key using
+the requested encryption method, and sends it to the client. See section
+A.2 for pseudocode.
+
+3.1.4. Generation of KRB_ERROR message
+
+Several errors can occur, and the Authentication Server responds by
+returning an error message, KRB_ERROR, to the client, with the error-code
+and e-text fields set to appropriate values. The error message contents and
+details are described in Section 5.9.1.
+
+3.1.5. Receipt of KRB_AS_REP message
+
+If the reply message type is KRB_AS_REP, then the client verifies that the
+cname and crealm fields in the cleartext portion of the reply match what it
+requested. If any padata fields are present, they may be used to derive the
+proper secret key to decrypt the message. The client decrypts the encrypted
+part of the response using its secret key, verifies that the nonce in the
+encrypted part matches the nonce it supplied in its request (to detect
+replays). It also verifies that the sname and srealm in the response match
+those in the request (or are otherwise expected values), and that the host
+address field is also correct. It then stores the ticket, session key,
+start and expiration times, and other information for later use. The
+key-expiration field from the encrypted part of the response may be checked
+to notify the user of impending key expiration (the client program could
+then suggest remedial action, such as a password change). See section A.3
+for pseudocode.
+
+Proper decryption of the KRB_AS_REP message is not sufficient to verify the
+identity of the user; the user and an attacker could cooperate to generate
+a KRB_AS_REP format message which decrypts properly but is not from the
+proper KDC. If the host wishes to verify the identity of the user, it must
+require the user to present application credentials which can be verified
+using a securely-stored secret key for the host. If those credentials can
+be verified, then the identity of the user can be assured.
+
+3.1.6. Receipt of KRB_ERROR message
+
+If the reply message type is KRB_ERROR, then the client interprets it as an
+error and performs whatever application-specific tasks are necessary to
+recover.
+
+3.2. The Client/Server Authentication Exchange
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+ Summary
+Message direction Message type Section
+Client to Application server KRB_AP_REQ 5.5.1
+[optional] Application server to client KRB_AP_REP or 5.5.2
+ KRB_ERROR 5.9.1
+
+The client/server authentication (CS) exchange is used by network
+applications to authenticate the client to the server and vice versa. The
+client must have already acquired credentials for the server using the AS
+or TGS exchange.
+
+3.2.1. The KRB_AP_REQ message
+
+The KRB_AP_REQ contains authentication information which should be part of
+the first message in an authenticated transaction. It contains a ticket, an
+authenticator, and some additional bookkeeping information (see section
+5.5.1 for the exact format). The ticket by itself is insufficient to
+authenticate a client, since tickets are passed across the network in
+cleartext[DS90], so the authenticator is used to prevent invalid replay of
+tickets by proving to the server that the client knows the session key of
+the ticket and thus is entitled to use the ticket. The KRB_AP_REQ message
+is referred to elsewhere as the 'authentication header.'
+
+3.2.2. Generation of a KRB_AP_REQ message
+
+When a client wishes to initiate authentication to a server, it obtains
+(either through a credentials cache, the AS exchange, or the TGS exchange)
+a ticket and session key for the desired service. The client may re-use any
+tickets it holds until they expire. To use a ticket the client constructs a
+new Authenticator from the the system time, its name, and optionally an
+application specific checksum, an initial sequence number to be used in
+KRB_SAFE or KRB_PRIV messages, and/or a session subkey to be used in
+negotiations for a session key unique to this particular session.
+Authenticators may not be re-used and will be rejected if replayed to a
+server[LGDSR87]. If a sequence number is to be included, it should be
+randomly chosen so that even after many messages have been exchanged it is
+not likely to collide with other sequence numbers in use.
+
+The client may indicate a requirement of mutual authentication or the use
+of a session-key based ticket by setting the appropriate flag(s) in the
+ap-options field of the message.
+
+The Authenticator is encrypted in the session key and combined with the
+ticket to form the KRB_AP_REQ message which is then sent to the end server
+along with any additional application-specific information. See section A.9
+for pseudocode.
+
+3.2.3. Receipt of KRB_AP_REQ message
+
+Authentication is based on the server's current time of day (clocks must be
+loosely synchronized), the authenticator, and the ticket. Several errors
+are possible. If an error occurs, the server is expected to reply to the
+client with a KRB_ERROR message. This message may be encapsulated in the
+application protocol if its 'raw' form is not acceptable to the protocol.
+The format of error messages is described in section 5.9.1.
+
+The algorithm for verifying authentication information is as follows. If
+the message type is not KRB_AP_REQ, the server returns the
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+KRB_AP_ERR_MSG_TYPE error. If the key version indicated by the Ticket in
+the KRB_AP_REQ is not one the server can use (e.g., it indicates an old
+key, and the server no longer possesses a copy of the old key), the
+KRB_AP_ERR_BADKEYVER error is returned. If the USE-SESSION-KEY flag is set
+in the ap-options field, it indicates to the server that the ticket is
+encrypted in the session key from the server's ticket-granting ticket
+rather than its secret key[10]. Since it is possible for the server to be
+registered in multiple realms, with different keys in each, the srealm
+field in the unencrypted portion of the ticket in the KRB_AP_REQ is used to
+specify which secret key the server should use to decrypt that ticket. The
+KRB_AP_ERR_NOKEY error code is returned if the server doesn't have the
+proper key to decipher the ticket.
+
+The ticket is decrypted using the version of the server's key specified by
+the ticket. If the decryption routines detect a modification of the ticket
+(each encryption system must provide safeguards to detect modified
+ciphertext; see section 6), the KRB_AP_ERR_BAD_INTEGRITY error is returned
+(chances are good that different keys were used to encrypt and decrypt).
+
+The authenticator is decrypted using the session key extracted from the
+decrypted ticket. If decryption shows it to have been modified, the
+KRB_AP_ERR_BAD_INTEGRITY error is returned. The name and realm of the
+client from the ticket are compared against the same fields in the
+authenticator. If they don't match, the KRB_AP_ERR_BADMATCH error is
+returned (they might not match, for example, if the wrong session key was
+used to encrypt the authenticator). The addresses in the ticket (if any)
+are then searched for an address matching the operating-system reported
+address of the client. If no match is found or the server insists on ticket
+addresses but none are present in the ticket, the KRB_AP_ERR_BADADDR error
+is returned.
+
+If the local (server) time and the client time in the authenticator differ
+by more than the allowable clock skew (e.g., 5 minutes), the
+KRB_AP_ERR_SKEW error is returned. If the server name, along with the
+client name, time and microsecond fields from the Authenticator match any
+recently-seen such tuples, the KRB_AP_ERR_REPEAT error is returned[11]. The
+server must remember any authenticator presented within the allowable clock
+skew, so that a replay attempt is guaranteed to fail. If a server loses
+track of any authenticator presented within the allowable clock skew, it
+must reject all requests until the clock skew interval has passed. This
+assures that any lost or re-played authenticators will fall outside the
+allowable clock skew and can no longer be successfully replayed (If this is
+not done, an attacker could conceivably record the ticket and authenticator
+sent over the network to a server, then disable the client's host, pose as
+the disabled host, and replay the ticket and authenticator to subvert the
+authentication.). If a sequence number is provided in the authenticator,
+the server saves it for later use in processing KRB_SAFE and/or KRB_PRIV
+messages. If a subkey is present, the server either saves it for later use
+or uses it to help generate its own choice for a subkey to be returned in a
+KRB_AP_REP message.
+
+The server computes the age of the ticket: local (server) time minus the
+start time inside the Ticket. If the start time is later than the current
+time by more than the allowable clock skew or if the INVALID flag is set in
+the ticket, the KRB_AP_ERR_TKT_NYV error is returned. Otherwise, if the
+current time is later than end time by more than the allowable clock skew,
+the KRB_AP_ERR_TKT_EXPIRED error is returned.
+
+If all these checks succeed without an error, the server is assured that
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+the client possesses the credentials of the principal named in the ticket
+and thus, the client has been authenticated to the server. See section A.10
+for pseudocode.
+
+Passing these checks provides only authentication of the named principal;
+it does not imply authorization to use the named service. Applications must
+make a separate authorization decisions based upon the authenticated name
+of the user, the requested operation, local acces control information such
+as that contained in a .k5login or .k5users file, and possibly a separate
+distributed authorization service.
+
+3.2.4. Generation of a KRB_AP_REP message
+
+Typically, a client's request will include both the authentication
+information and its initial request in the same message, and the server
+need not explicitly reply to the KRB_AP_REQ. However, if mutual
+authentication (not only authenticating the client to the server, but also
+the server to the client) is being performed, the KRB_AP_REQ message will
+have MUTUAL-REQUIRED set in its ap-options field, and a KRB_AP_REP message
+is required in response. As with the error message, this message may be
+encapsulated in the application protocol if its "raw" form is not
+acceptable to the application's protocol. The timestamp and microsecond
+field used in the reply must be the client's timestamp and microsecond
+field (as provided in the authenticator)[12]. If a sequence number is to be
+included, it should be randomly chosen as described above for the
+authenticator. A subkey may be included if the server desires to negotiate
+a different subkey. The KRB_AP_REP message is encrypted in the session key
+extracted from the ticket. See section A.11 for pseudocode.
+
+3.2.5. Receipt of KRB_AP_REP message
+
+If a KRB_AP_REP message is returned, the client uses the session key from
+the credentials obtained for the server[13] to decrypt the message, and
+verifies that the timestamp and microsecond fields match those in the
+Authenticator it sent to the server. If they match, then the client is
+assured that the server is genuine. The sequence number and subkey (if
+present) are retained for later use. See section A.12 for pseudocode.
+
+3.2.6. Using the encryption key
+
+After the KRB_AP_REQ/KRB_AP_REP exchange has occurred, the client and
+server share an encryption key which can be used by the application. The
+'true session key' to be used for KRB_PRIV, KRB_SAFE, or other
+application-specific uses may be chosen by the application based on the
+subkeys in the KRB_AP_REP message and the authenticator[14]. In some cases,
+the use of this session key will be implicit in the protocol; in others the
+method of use must be chosen from several alternatives. We leave the
+protocol negotiations of how to use the key (e.g. selecting an encryption
+or checksum type) to the application programmer; the Kerberos protocol does
+not constrain the implementation options, but an example of how this might
+be done follows.
+
+One way that an application may choose to negotiate a key to be used for
+subequent integrity and privacy protection is for the client to propose a
+key in the subkey field of the authenticator. The server can then choose a
+key using the proposed key from the client as input, returning the new
+subkey in the subkey field of the application reply. This key could then be
+used for subsequent communication. To make this example more concrete, if
+the encryption method in use required a 56 bit key, and for whatever
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+reason, one of the parties was prevented from using a key with more than 40
+unknown bits, this method would allow the the party which is prevented from
+using more than 40 bits to either propose (if the client) an initial key
+with a known quantity for 16 of those bits, or to mask 16 of the bits (if
+the server) with the known quantity. The application implementor is warned,
+however, that this is only an example, and that an analysis of the
+particular crytosystem to be used, and the reasons for limiting the key
+length, must be made before deciding whether it is acceptable to mask bits
+of the key.
+
+With both the one-way and mutual authentication exchanges, the peers should
+take care not to send sensitive information to each other without proper
+assurances. In particular, applications that require privacy or integrity
+should use the KRB_AP_REP response from the server to client to assure both
+client and server of their peer's identity. If an application protocol
+requires privacy of its messages, it can use the KRB_PRIV message (section
+3.5). The KRB_SAFE message (section 3.4) can be used to assure integrity.
+
+3.3. The Ticket-Granting Service (TGS) Exchange
+
+ Summary
+ Message direction Message type Section
+ 1. Client to Kerberos KRB_TGS_REQ 5.4.1
+ 2. Kerberos to client KRB_TGS_REP or 5.4.2
+ KRB_ERROR 5.9.1
+
+The TGS exchange between a client and the Kerberos Ticket-Granting Server
+is initiated by a client when it wishes to obtain authentication
+credentials for a given server (which might be registered in a remote
+realm), when it wishes to renew or validate an existing ticket, or when it
+wishes to obtain a proxy ticket. In the first case, the client must already
+have acquired a ticket for the Ticket-Granting Service using the AS
+exchange (the ticket-granting ticket is usually obtained when a client
+initially authenticates to the system, such as when a user logs in). The
+message format for the TGS exchange is almost identical to that for the AS
+exchange. The primary difference is that encryption and decryption in the
+TGS exchange does not take place under the client's key. Instead, the
+session key from the ticket-granting ticket or renewable ticket, or
+sub-session key from an Authenticator is used. As is the case for all
+application servers, expired tickets are not accepted by the TGS, so once a
+renewable or ticket-granting ticket expires, the client must use a separate
+exchange to obtain valid tickets.
+
+The TGS exchange consists of two messages: A request (KRB_TGS_REQ) from the
+client to the Kerberos Ticket-Granting Server, and a reply (KRB_TGS_REP or
+KRB_ERROR). The KRB_TGS_REQ message includes information authenticating the
+client plus a request for credentials. The authentication information
+consists of the authentication header (KRB_AP_REQ) which includes the
+client's previously obtained ticket-granting, renewable, or invalid ticket.
+In the ticket-granting ticket and proxy cases, the request may include one
+or more of: a list of network addresses, a collection of typed
+authorization data to be sealed in the ticket for authorization use by the
+application server, or additional tickets (the use of which are described
+later). The TGS reply (KRB_TGS_REP) contains the requested credentials,
+encrypted in the session key from the ticket-granting ticket or renewable
+ticket, or if present, in the sub-session key from the Authenticator (part
+of the authentication header). The KRB_ERROR message contains an error code
+and text explaining what went wrong. The KRB_ERROR message is not
+encrypted. The KRB_TGS_REP message contains information which can be used
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+to detect replays, and to associate it with the message to which it
+replies. The KRB_ERROR message also contains information which can be used
+to associate it with the message to which it replies, but the lack of
+encryption in the KRB_ERROR message precludes the ability to detect replays
+or fabrications of such messages.
+
+3.3.1. Generation of KRB_TGS_REQ message
+
+Before sending a request to the ticket-granting service, the client must
+determine in which realm the application server is registered[15]. If the
+client does not already possess a ticket-granting ticket for the
+appropriate realm, then one must be obtained. This is first attempted by
+requesting a ticket-granting ticket for the destination realm from a
+Kerberos server for which the client does posess a ticket-granting ticket
+(using the KRB_TGS_REQ message recursively). The Kerberos server may return
+a TGT for the desired realm in which case one can proceed. Alternatively,
+the Kerberos server may return a TGT for a realm which is 'closer' to the
+desired realm (further along the standard hierarchical path), in which case
+this step must be repeated with a Kerberos server in the realm specified in
+the returned TGT. If neither are returned, then the request must be retried
+with a Kerberos server for a realm higher in the hierarchy. This request
+will itself require a ticket-granting ticket for the higher realm which
+must be obtained by recursively applying these directions.
+
+Once the client obtains a ticket-granting ticket for the appropriate realm,
+it determines which Kerberos servers serve that realm, and contacts one.
+The list might be obtained through a configuration file or network service
+or it may be generated from the name of the realm; as long as the secret
+keys exchanged by realms are kept secret, only denial of service results
+from using a false Kerberos server.
+
+As in the AS exchange, the client may specify a number of options in the
+KRB_TGS_REQ message. The client prepares the KRB_TGS_REQ message, providing
+an authentication header as an element of the padata field, and including
+the same fields as used in the KRB_AS_REQ message along with several
+optional fields: the enc-authorization-data field for application server
+use and additional tickets required by some options.
+
+In preparing the authentication header, the client can select a sub-session
+key under which the response from the Kerberos server will be
+encrypted[16]. If the sub-session key is not specified, the session key
+from the ticket-granting ticket will be used. If the enc-authorization-data
+is present, it must be encrypted in the sub-session key, if present, from
+the authenticator portion of the authentication header, or if not present,
+using the session key from the ticket-granting ticket.
+
+Once prepared, the message is sent to a Kerberos server for the destination
+realm. See section A.5 for pseudocode.
+
+3.3.2. Receipt of KRB_TGS_REQ message
+
+The KRB_TGS_REQ message is processed in a manner similar to the KRB_AS_REQ
+message, but there are many additional checks to be performed. First, the
+Kerberos server must determine which server the accompanying ticket is for
+and it must select the appropriate key to decrypt it. For a normal
+KRB_TGS_REQ message, it will be for the ticket granting service, and the
+TGS's key will be used. If the TGT was issued by another realm, then the
+appropriate inter-realm key must be used. If the accompanying ticket is not
+a ticket granting ticket for the current realm, but is for an application
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+server in the current realm, the RENEW, VALIDATE, or PROXY options are
+specified in the request, and the server for which a ticket is requested is
+the server named in the accompanying ticket, then the KDC will decrypt the
+ticket in the authentication header using the key of the server for which
+it was issued. If no ticket can be found in the padata field, the
+KDC_ERR_PADATA_TYPE_NOSUPP error is returned.
+
+Once the accompanying ticket has been decrypted, the user-supplied checksum
+in the Authenticator must be verified against the contents of the request,
+and the message rejected if the checksums do not match (with an error code
+of KRB_AP_ERR_MODIFIED) or if the checksum is not keyed or not
+collision-proof (with an error code of KRB_AP_ERR_INAPP_CKSUM). If the
+checksum type is not supported, the KDC_ERR_SUMTYPE_NOSUPP error is
+returned. If the authorization-data are present, they are decrypted using
+the sub-session key from the Authenticator.
+
+If any of the decryptions indicate failed integrity checks, the
+KRB_AP_ERR_BAD_INTEGRITY error is returned.
+
+3.3.3. Generation of KRB_TGS_REP message
+
+The KRB_TGS_REP message shares its format with the KRB_AS_REP
+(KRB_KDC_REP), but with its type field set to KRB_TGS_REP. The detailed
+specification is in section 5.4.2.
+
+The response will include a ticket for the requested server. The Kerberos
+database is queried to retrieve the record for the requested server
+(including the key with which the ticket will be encrypted). If the request
+is for a ticket granting ticket for a remote realm, and if no key is shared
+with the requested realm, then the Kerberos server will select the realm
+"closest" to the requested realm with which it does share a key, and use
+that realm instead. This is the only case where the response from the KDC
+will be for a different server than that requested by the client.
+
+By default, the address field, the client's name and realm, the list of
+transited realms, the time of initial authentication, the expiration time,
+and the authorization data of the newly-issued ticket will be copied from
+the ticket-granting ticket (TGT) or renewable ticket. If the transited
+field needs to be updated, but the transited type is not supported, the
+KDC_ERR_TRTYPE_NOSUPP error is returned.
+
+If the request specifies an endtime, then the endtime of the new ticket is
+set to the minimum of (a) that request, (b) the endtime from the TGT, and
+(c) the starttime of the TGT plus the minimum of the maximum life for the
+application server and the maximum life for the local realm (the maximum
+life for the requesting principal was already applied when the TGT was
+issued). If the new ticket is to be a renewal, then the endtime above is
+replaced by the minimum of (a) the value of the renew_till field of the
+ticket and (b) the starttime for the new ticket plus the life
+(endtime-starttime) of the old ticket.
+
+If the FORWARDED option has been requested, then the resulting ticket will
+contain the addresses specified by the client. This option will only be
+honored if the FORWARDABLE flag is set in the TGT. The PROXY option is
+similar; the resulting ticket will contain the addresses specified by the
+client. It will be honored only if the PROXIABLE flag in the TGT is set.
+The PROXY option will not be honored on requests for additional
+ticket-granting tickets.
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+If the requested start time is absent, indicates a time in the past, or is
+within the window of acceptable clock skew for the KDC and the POSTDATE
+option has not been specified, then the start time of the ticket is set to
+the authentication server's current time. If it indicates a time in the
+future beyond the acceptable clock skew, but the POSTDATED option has not
+been specified or the MAY-POSTDATE flag is not set in the TGT, then the
+error KDC_ERR_CANNOT_POSTDATE is returned. Otherwise, if the
+ticket-granting ticket has the MAY-POSTDATE flag set, then the resulting
+ticket will be postdated and the requested starttime is checked against the
+policy of the local realm. If acceptable, the ticket's start time is set as
+requested, and the INVALID flag is set. The postdated ticket must be
+validated before use by presenting it to the KDC after the starttime has
+been reached. However, in no case may the starttime, endtime, or renew-till
+time of a newly-issued postdated ticket extend beyond the renew-till time
+of the ticket-granting ticket.
+
+If the ENC-TKT-IN-SKEY option has been specified and an additional ticket
+has been included in the request, the KDC will decrypt the additional
+ticket using the key for the server to which the additional ticket was
+issued and verify that it is a ticket-granting ticket. If the name of the
+requested server is missing from the request, the name of the client in the
+additional ticket will be used. Otherwise the name of the requested server
+will be compared to the name of the client in the additional ticket and if
+different, the request will be rejected. If the request succeeds, the
+session key from the additional ticket will be used to encrypt the new
+ticket that is issued instead of using the key of the server for which the
+new ticket will be used[17].
+
+If the name of the server in the ticket that is presented to the KDC as
+part of the authentication header is not that of the ticket-granting server
+itself, the server is registered in the realm of the KDC, and the RENEW
+option is requested, then the KDC will verify that the RENEWABLE flag is
+set in the ticket, that the INVALID flag is not set in the ticket, and that
+the renew_till time is still in the future. If the VALIDATE option is
+rqeuested, the KDC will check that the starttime has passed and the INVALID
+flag is set. If the PROXY option is requested, then the KDC will check that
+the PROXIABLE flag is set in the ticket. If the tests succeed, and the
+ticket passes the hotlist check described in the next paragraph, the KDC
+will issue the appropriate new ticket.
+
+3.3.3.1. Checking for revoked tickets
+
+Whenever a request is made to the ticket-granting server, the presented
+ticket(s) is(are) checked against a hot-list of tickets which have been
+canceled. This hot-list might be implemented by storing a range of issue
+timestamps for 'suspect tickets'; if a presented ticket had an authtime in
+that range, it would be rejected. In this way, a stolen ticket-granting
+ticket or renewable ticket cannot be used to gain additional tickets
+(renewals or otherwise) once the theft has been reported. Any normal ticket
+obtained before it was reported stolen will still be valid (because they
+require no interaction with the KDC), but only until their normal
+expiration time.
+
+The ciphertext part of the response in the KRB_TGS_REP message is encrypted
+in the sub-session key from the Authenticator, if present, or the session
+key key from the ticket-granting ticket. It is not encrypted using the
+client's secret key. Furthermore, the client's key's expiration date and
+the key version number fields are left out since these values are stored
+along with the client's database record, and that record is not needed to
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+satisfy a request based on a ticket-granting ticket. See section A.6 for
+pseudocode.
+
+3.3.3.2. Encoding the transited field
+
+If the identity of the server in the TGT that is presented to the KDC as
+part of the authentication header is that of the ticket-granting service,
+but the TGT was issued from another realm, the KDC will look up the
+inter-realm key shared with that realm and use that key to decrypt the
+ticket. If the ticket is valid, then the KDC will honor the request,
+subject to the constraints outlined above in the section describing the AS
+exchange. The realm part of the client's identity will be taken from the
+ticket-granting ticket. The name of the realm that issued the
+ticket-granting ticket will be added to the transited field of the ticket
+to be issued. This is accomplished by reading the transited field from the
+ticket-granting ticket (which is treated as an unordered set of realm
+names), adding the new realm to the set, then constructing and writing out
+its encoded (shorthand) form (this may involve a rearrangement of the
+existing encoding).
+
+Note that the ticket-granting service does not add the name of its own
+realm. Instead, its responsibility is to add the name of the previous
+realm. This prevents a malicious Kerberos server from intentionally leaving
+out its own name (it could, however, omit other realms' names).
+
+The names of neither the local realm nor the principal's realm are to be
+included in the transited field. They appear elsewhere in the ticket and
+both are known to have taken part in authenticating the principal. Since
+the endpoints are not included, both local and single-hop inter-realm
+authentication result in a transited field that is empty.
+
+Because the name of each realm transited is added to this field, it might
+potentially be very long. To decrease the length of this field, its
+contents are encoded. The initially supported encoding is optimized for the
+normal case of inter-realm communication: a hierarchical arrangement of
+realms using either domain or X.500 style realm names. This encoding
+(called DOMAIN-X500-COMPRESS) is now described.
+
+Realm names in the transited field are separated by a ",". The ",", "\",
+trailing "."s, and leading spaces (" ") are special characters, and if they
+are part of a realm name, they must be quoted in the transited field by
+preced- ing them with a "\".
+
+A realm name ending with a "." is interpreted as being prepended to the
+previous realm. For example, we can encode traversal of EDU, MIT.EDU,
+ATHENA.MIT.EDU, WASHINGTON.EDU, and CS.WASHINGTON.EDU as:
+
+ "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS.".
+
+Note that if ATHENA.MIT.EDU, or CS.WASHINGTON.EDU were end-points, that
+they would not be included in this field, and we would have:
+
+ "EDU,MIT.,WASHINGTON.EDU"
+
+A realm name beginning with a "/" is interpreted as being appended to the
+previous realm[18]. If it is to stand by itself, then it should be preceded
+by a space (" "). For example, we can encode traversal of /COM/HP/APOLLO,
+/COM/HP, /COM, and /COM/DEC as:
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ "/COM,/HP,/APOLLO, /COM/DEC".
+
+Like the example above, if /COM/HP/APOLLO and /COM/DEC are endpoints, they
+they would not be included in this field, and we would have:
+
+ "/COM,/HP"
+
+A null subfield preceding or following a "," indicates that all realms
+between the previous realm and the next realm have been traversed[19].
+Thus, "," means that all realms along the path between the client and the
+server have been traversed. ",EDU, /COM," means that that all realms from
+the client's realm up to EDU (in a domain style hierarchy) have been
+traversed, and that everything from /COM down to the server's realm in an
+X.500 style has also been traversed. This could occur if the EDU realm in
+one hierarchy shares an inter-realm key directly with the /COM realm in
+another hierarchy.
+
+3.3.4. Receipt of KRB_TGS_REP message
+
+When the KRB_TGS_REP is received by the client, it is processed in the same
+manner as the KRB_AS_REP processing described above. The primary difference
+is that the ciphertext part of the response must be decrypted using the
+session key from the ticket-granting ticket rather than the client's secret
+key. See section A.7 for pseudocode.
+
+3.4. The KRB_SAFE Exchange
+
+The KRB_SAFE message may be used by clients requiring the ability to detect
+modifications of messages they exchange. It achieves this by including a
+keyed collision-proof checksum of the user data and some control
+information. The checksum is keyed with an encryption key (usually the last
+key negotiated via subkeys, or the session key if no negotiation has
+occured).
+
+3.4.1. Generation of a KRB_SAFE message
+
+When an application wishes to send a KRB_SAFE message, it collects its data
+and the appropriate control information and computes a checksum over them.
+The checksum algorithm should be a keyed one-way hash function (such as the
+RSA- MD5-DES checksum algorithm specified in section 6.4.5, or the DES
+MAC), generated using the sub-session key if present, or the session key.
+Different algorithms may be selected by changing the checksum type in the
+message. Unkeyed or non-collision-proof checksums are not suitable for this
+use.
+
+The control information for the KRB_SAFE message includes both a timestamp
+and a sequence number. The designer of an application using the KRB_SAFE
+message must choose at least one of the two mechanisms. This choice should
+be based on the needs of the application protocol.
+
+Sequence numbers are useful when all messages sent will be received by
+one's peer. Connection state is presently required to maintain the session
+key, so maintaining the next sequence number should not present an
+additional problem.
+
+If the application protocol is expected to tolerate lost messages without
+them being resent, the use of the timestamp is the appropriate replay
+detection mechanism. Using timestamps is also the appropriate mechanism for
+multi-cast protocols where all of one's peers share a common sub-session
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+key, but some messages will be sent to a subset of one's peers.
+
+After computing the checksum, the client then transmits the information and
+checksum to the recipient in the message format specified in section 5.6.1.
+
+3.4.2. Receipt of KRB_SAFE message
+
+When an application receives a KRB_SAFE message, it verifies it as follows.
+If any error occurs, an error code is reported for use by the application.
+
+The message is first checked by verifying that the protocol version and
+type fields match the current version and KRB_SAFE, respectively. A
+mismatch generates a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error.
+The application verifies that the checksum used is a collision-proof keyed
+checksum, and if it is not, a KRB_AP_ERR_INAPP_CKSUM error is generated.
+The recipient verifies that the operating system's report of the sender's
+address matches the sender's address in the message, and (if a recipient
+address is specified or the recipient requires an address) that one of the
+recipient's addresses appears as the recipient's address in the message. A
+failed match for either case generates a KRB_AP_ERR_BADADDR error. Then the
+timestamp and usec and/or the sequence number fields are checked. If
+timestamp and usec are expected and not present, or they are present but
+not current, the KRB_AP_ERR_SKEW error is generated. If the server name,
+along with the client name, time and microsecond fields from the
+Authenticator match any recently-seen (sent or received[20] ) such tuples,
+the KRB_AP_ERR_REPEAT error is generated. If an incorrect sequence number
+is included, or a sequence number is expected but not present, the
+KRB_AP_ERR_BADORDER error is generated. If neither a time-stamp and usec or
+a sequence number is present, a KRB_AP_ERR_MODIFIED error is generated.
+Finally, the checksum is computed over the data and control information,
+and if it doesn't match the received checksum, a KRB_AP_ERR_MODIFIED error
+is generated.
+
+If all the checks succeed, the application is assured that the message was
+generated by its peer and was not modi- fied in transit.
+
+3.5. The KRB_PRIV Exchange
+
+The KRB_PRIV message may be used by clients requiring confidentiality and
+the ability to detect modifications of exchanged messages. It achieves this
+by encrypting the messages and adding control information.
+
+3.5.1. Generation of a KRB_PRIV message
+
+When an application wishes to send a KRB_PRIV message, it collects its data
+and the appropriate control information (specified in section 5.7.1) and
+encrypts them under an encryption key (usually the last key negotiated via
+subkeys, or the session key if no negotiation has occured). As part of the
+control information, the client must choose to use either a timestamp or a
+sequence number (or both); see the discussion in section 3.4.1 for
+guidelines on which to use. After the user data and control information are
+encrypted, the client transmits the ciphertext and some 'envelope'
+information to the recipient.
+
+3.5.2. Receipt of KRB_PRIV message
+
+When an application receives a KRB_PRIV message, it verifies it as follows.
+If any error occurs, an error code is reported for use by the application.
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+The message is first checked by verifying that the protocol version and
+type fields match the current version and KRB_PRIV, respectively. A
+mismatch generates a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error.
+The application then decrypts the ciphertext and processes the resultant
+plaintext. If decryption shows the data to have been modified, a
+KRB_AP_ERR_BAD_INTEGRITY error is generated. The recipient verifies that
+the operating system's report of the sender's address matches the sender's
+address in the message, and (if a recipient address is specified or the
+recipient requires an address) that one of the recipient's addresses
+appears as the recipient's address in the message. A failed match for
+either case generates a KRB_AP_ERR_BADADDR error. Then the timestamp and
+usec and/or the sequence number fields are checked. If timestamp and usec
+are expected and not present, or they are present but not current, the
+KRB_AP_ERR_SKEW error is generated. If the server name, along with the
+client name, time and microsecond fields from the Authenticator match any
+recently-seen such tuples, the KRB_AP_ERR_REPEAT error is generated. If an
+incorrect sequence number is included, or a sequence number is expected but
+not present, the KRB_AP_ERR_BADORDER error is generated. If neither a
+time-stamp and usec or a sequence number is present, a KRB_AP_ERR_MODIFIED
+error is generated.
+
+If all the checks succeed, the application can assume the message was
+generated by its peer, and was securely transmitted (without intruders able
+to see the unencrypted contents).
+
+3.6. The KRB_CRED Exchange
+
+The KRB_CRED message may be used by clients requiring the ability to send
+Kerberos credentials from one host to another. It achieves this by sending
+the tickets together with encrypted data containing the session keys and
+other information associated with the tickets.
+
+3.6.1. Generation of a KRB_CRED message
+
+When an application wishes to send a KRB_CRED message it first (using the
+KRB_TGS exchange) obtains credentials to be sent to the remote host. It
+then constructs a KRB_CRED message using the ticket or tickets so obtained,
+placing the session key needed to use each ticket in the key field of the
+corresponding KrbCredInfo sequence of the encrypted part of the the
+KRB_CRED message.
+
+Other information associated with each ticket and obtained during the
+KRB_TGS exchange is also placed in the corresponding KrbCredInfo sequence
+in the encrypted part of the KRB_CRED message. The current time and, if
+specifically required by the application the nonce, s-address, and
+r-address fields, are placed in the encrypted part of the KRB_CRED message
+which is then encrypted under an encryption key previosuly exchanged in the
+KRB_AP exchange (usually the last key negotiated via subkeys, or the
+session key if no negotiation has occured).
+
+3.6.2. Receipt of KRB_CRED message
+
+When an application receives a KRB_CRED message, it verifies it. If any
+error occurs, an error code is reported for use by the application. The
+message is verified by checking that the protocol version and type fields
+match the current version and KRB_CRED, respectively. A mismatch generates
+a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error. The application then
+decrypts the ciphertext and processes the resultant plaintext. If
+decryption shows the data to have been modified, a KRB_AP_ERR_BAD_INTEGRITY
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+error is generated.
+
+If present or required, the recipient verifies that the operating system's
+report of the sender's address matches the sender's address in the message,
+and that one of the recipient's addresses appears as the recipient's
+address in the message. A failed match for either case generates a
+KRB_AP_ERR_BADADDR error. The timestamp and usec fields (and the nonce
+field if required) are checked next. If the timestamp and usec are not
+present, or they are present but not current, the KRB_AP_ERR_SKEW error is
+generated.
+
+If all the checks succeed, the application stores each of the new tickets
+in its ticket cache together with the session key and other information in
+the corresponding KrbCredInfo sequence from the encrypted part of the
+KRB_CRED message.
+
+4. The Kerberos Database
+
+The Kerberos server must have access to a database contain- ing the
+principal identifiers and secret keys of principals to be
+authenticated[21].
+
+4.1. Database contents
+
+A database entry should contain at least the following fields:
+
+Field Value
+
+name Principal's identifier
+key Principal's secret key
+p_kvno Principal's key version
+max_life Maximum lifetime for Tickets
+max_renewable_life Maximum total lifetime for renewable Tickets
+
+The name field is an encoding of the principal's identifier. The key field
+contains an encryption key. This key is the principal's secret key. (The
+key can be encrypted before storage under a Kerberos "master key" to
+protect it in case the database is compromised but the master key is not.
+In that case, an extra field must be added to indicate the master key
+version used, see below.) The p_kvno field is the key version number of the
+principal's secret key. The max_life field contains the maximum allowable
+lifetime (endtime - starttime) for any Ticket issued for this principal.
+The max_renewable_life field contains the maximum allowable total lifetime
+for any renewable Ticket issued for this principal. (See section 3.1 for a
+description of how these lifetimes are used in determining the lifetime of
+a given Ticket.)
+
+A server may provide KDC service to several realms, as long as the database
+representation provides a mechanism to distinguish between principal
+records with identifiers which differ only in the realm name.
+
+When an application server's key changes, if the change is routine (i.e.
+not the result of disclosure of the old key), the old key should be
+retained by the server until all tickets that had been issued using that
+key have expired. Because of this, it is possible for several keys to be
+active for a single principal. Ciphertext encrypted in a principal's key is
+always tagged with the version of the key that was used for encryption, to
+help the recipient find the proper key for decryption.
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+When more than one key is active for a particular principal, the principal
+will have more than one record in the Kerberos database. The keys and key
+version numbers will differ between the records (the rest of the fields may
+or may not be the same). Whenever Kerberos issues a ticket, or responds to
+a request for initial authentication, the most recent key (known by the
+Kerberos server) will be used for encryption. This is the key with the
+highest key version number.
+
+4.2. Additional fields
+
+Project Athena's KDC implementation uses additional fields in its database:
+
+Field Value
+
+K_kvno Kerberos' key version
+expiration Expiration date for entry
+attributes Bit field of attributes
+mod_date Timestamp of last modification
+mod_name Modifying principal's identifier
+
+The K_kvno field indicates the key version of the Kerberos master key under
+which the principal's secret key is encrypted.
+
+After an entry's expiration date has passed, the KDC will return an error
+to any client attempting to gain tickets as or for the principal. (A
+database may want to maintain two expiration dates: one for the principal,
+and one for the principal's current key. This allows password aging to work
+independently of the principal's expiration date. However, due to the
+limited space in the responses, the KDC must combine the key expiration and
+principal expiration date into a single value called 'key_exp', which is
+used as a hint to the user to take administrative action.)
+
+The attributes field is a bitfield used to govern the operations involving
+the principal. This field might be useful in conjunction with user
+registration procedures, for site-specific policy implementations (Project
+Athena currently uses it for their user registration process controlled by
+the system-wide database service, Moira [LGDSR87]), to identify whether a
+principal can play the role of a client or server or both, to note whether
+a server is appropriate trusted to recieve credentials delegated by a
+client, or to identify the 'string to key' conversion algorithm used for a
+principal's key[22]. Other bits are used to indicate that certain ticket
+options should not be allowed in tickets encrypted under a principal's key
+(one bit each): Disallow issuing postdated tickets, disallow issuing
+forwardable tickets, disallow issuing tickets based on TGT authentication,
+disallow issuing renewable tickets, disallow issuing proxiable tickets, and
+disallow issuing tickets for which the principal is the server.
+
+The mod_date field contains the time of last modification of the entry, and
+the mod_name field contains the name of the principal which last modified
+the entry.
+
+4.3. Frequently Changing Fields
+
+Some KDC implementations may wish to maintain the last time that a request
+was made by a particular principal. Information that might be maintained
+includes the time of the last request, the time of the last request for a
+ticket-granting ticket, the time of the last use of a ticket-granting
+ticket, or other times. This information can then be returned to the user
+in the last-req field (see section 5.2).
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+Other frequently changing information that can be maintained is the latest
+expiration time for any tickets that have been issued using each key. This
+field would be used to indicate how long old keys must remain valid to
+allow the continued use of outstanding tickets.
+
+4.4. Site Constants
+
+The KDC implementation should have the following configurable constants or
+options, to allow an administrator to make and enforce policy decisions:
+
+ * The minimum supported lifetime (used to determine whether the
+ KDC_ERR_NEVER_VALID error should be returned). This constant should
+ reflect reasonable expectations of round-trip time to the KDC,
+ encryption/decryption time, and processing time by the client and
+ target server, and it should allow for a minimum 'useful' lifetime.
+ * The maximum allowable total (renewable) lifetime of a ticket
+ (renew_till - starttime).
+ * The maximum allowable lifetime of a ticket (endtime - starttime).
+ * Whether to allow the issue of tickets with empty address fields
+ (including the ability to specify that such tickets may only be issued
+ if the request specifies some authorization_data).
+ * Whether proxiable, forwardable, renewable or post-datable tickets are
+ to be issued.
+
+5. Message Specifications
+
+The following sections describe the exact contents and encoding of protocol
+messages and objects. The ASN.1 base definitions are presented in the first
+subsection. The remaining subsections specify the protocol objects (tickets
+and authenticators) and messages. Specification of encryption and checksum
+techniques, and the fields related to them, appear in section 6.
+
+Optional field in ASN.1 sequences
+
+For optional integer value and date fields in ASN.1 sequences where a
+default value has been specified, certain default values will not be
+allowed in the encoding because these values will always be represented
+through defaulting by the absence of the optional field. For example, one
+will not send a microsecond zero value because one must make sure that
+there is only one way to encode this value.
+
+Additional fields in ASN.1 sequences
+
+Implementations receiving Kerberos messages with additional fields present
+in ASN.1 sequences should carry the those fields through unmodified when
+the message is forwarded. Implementation should drop such fields if the
+sequence is reencoded.
+
+5.1. ASN.1 Distinguished Encoding Representation
+
+All uses of ASN.1 in Kerberos shall use the Distinguished Encoding
+Representation of the data elements as described in the X.509
+specification, section 8.7 [X509-88].
+
+5.3. ASN.1 Base Definitions
+
+The following ASN.1 base definitions are used in the rest of this section.
+Note that since the underscore character (_) is not permitted in ASN.1
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+names, the hyphen (-) is used in its place for the purposes of ASN.1 names.
+
+Realm ::= GeneralString
+PrincipalName ::= SEQUENCE {
+ name-type[0] INTEGER,
+ name-string[1] SEQUENCE OF GeneralString
+}
+
+Kerberos realms are encoded as GeneralStrings. Realms shall not contain a
+character with the code 0 (the ASCII NUL). Most realms will usually consist
+of several components separated by periods (.), in the style of Internet
+Domain Names, or separated by slashes (/) in the style of X.500 names.
+Acceptable forms for realm names are specified in section 7. A
+PrincipalName is a typed sequence of components consisting of the following
+sub-fields:
+
+name-type
+ This field specifies the type of name that follows. Pre-defined values
+ for this field are specified in section 7.2. The name-type should be
+ treated as a hint. Ignoring the name type, no two names can be the
+ same (i.e. at least one of the components, or the realm, must be
+ different). This constraint may be eliminated in the future.
+name-string
+ This field encodes a sequence of components that form a name, each
+ component encoded as a GeneralString. Taken together, a PrincipalName
+ and a Realm form a principal identifier. Most PrincipalNames will have
+ only a few components (typically one or two).
+
+KerberosTime ::= GeneralizedTime
+ -- Specifying UTC time zone (Z)
+
+The timestamps used in Kerberos are encoded as GeneralizedTimes. An
+encoding shall specify the UTC time zone (Z) and shall not include any
+fractional portions of the seconds. It further shall not include any
+separators. Example: The only valid format for UTC time 6 minutes, 27
+seconds after 9 pm on 6 November 1985 is 19851106210627Z.
+
+HostAddress ::= SEQUENCE {
+ addr-type[0] INTEGER,
+ address[1] OCTET STRING
+}
+
+HostAddresses ::= SEQUENCE OF HostAddress
+
+The host adddress encodings consists of two fields:
+
+addr-type
+ This field specifies the type of address that follows. Pre-defined
+ values for this field are specified in section 8.1.
+address
+ This field encodes a single address of type addr-type.
+
+The two forms differ slightly. HostAddress contains exactly one address;
+HostAddresses contains a sequence of possibly many addresses.
+
+AuthorizationData ::= SEQUENCE OF SEQUENCE {
+ ad-type[0] INTEGER,
+ ad-data[1] OCTET STRING
+}
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+ad-data
+ This field contains authorization data to be interpreted according to
+ the value of the corresponding ad-type field.
+ad-type
+ This field specifies the format for the ad-data subfield. All negative
+ values are reserved for local use. Non-negative values are reserved
+ for registered use.
+
+Each sequence of type and data is refered to as an authorization element.
+Elements may be application specific, however, there is a common set of
+recursive elements that should be understood by all implementations. These
+elements contain other elements embedded within them, and the
+interpretation of the encapsulating element determines which of the
+embedded elements must be interpreted, and which may be ignored.
+Definitions for these common elements may be found in Appendix B.
+
+TicketExtensions ::= SEQUENCE OF SEQUENCE {
+ te-type[0] INTEGER,
+ te-data[1] OCTET STRING
+}
+
+
+
+te-data
+ This field contains opaque data that must be caried with the ticket to
+ support extensions to the Kerberos protocol including but not limited
+ to some forms of inter-realm key exchange and plaintext authorization
+ data. See appendix C for some common uses of this field.
+te-type
+ This field specifies the format for the te-data subfield. All negative
+ values are reserved for local use. Non-negative values are reserved
+ for registered use.
+
+APOptions ::= BIT STRING
+ -- reserved(0),
+ -- use-session-key(1),
+ -- mutual-required(2)
+
+TicketFlags ::= BIT STRING
+ -- reserved(0),
+ -- forwardable(1),
+ -- forwarded(2),
+ -- proxiable(3),
+ -- proxy(4),
+ -- may-postdate(5),
+ -- postdated(6),
+ -- invalid(7),
+ -- renewable(8),
+ -- initial(9),
+ -- pre-authent(10),
+ -- hw-authent(11),
+ -- transited-policy-checked(12),
+ -- ok-as-delegate(13)
+
+KDCOptions ::= BIT STRING
+ -- reserved(0),
+ -- forwardable(1),
+ -- forwarded(2),
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ -- proxiable(3),
+ -- proxy(4),
+ -- allow-postdate(5),
+ -- postdated(6),
+ -- unused7(7),
+ -- renewable(8),
+ -- unused9(9),
+ -- unused10(10),
+ -- unused11(11),
+ -- unused12(12),
+ -- unused13(13),
+ -- disable-transited-check(26),
+ -- renewable-ok(27),
+ -- enc-tkt-in-skey(28),
+ -- renew(30),
+ -- validate(31)
+
+ASN.1 Bit strings have a length and a value. When used in Kerberos for the
+APOptions, TicketFlags, and KDCOptions, the length of the bit string on
+generated values should be the smallest number of bits needed to include
+the highest order bit that is set (1), but in no case less than 32 bits.
+The ASN.1 representation of the bit strings uses unnamed bits, with the
+meaning of the individual bits defined by the comments in the specification
+above. Implementations should accept values of bit strings of any length
+and treat the value of flags corresponding to bits beyond the end of the
+bit string as if the bit were reset (0). Comparison of bit strings of
+different length should treat the smaller string as if it were padded with
+zeros beyond the high order bits to the length of the longer string[23].
+
+LastReq ::= SEQUENCE OF SEQUENCE {
+ lr-type[0] INTEGER,
+ lr-value[1] KerberosTime
+}
+
+lr-type
+ This field indicates how the following lr-value field is to be
+ interpreted. Negative values indicate that the information pertains
+ only to the responding server. Non-negative values pertain to all
+ servers for the realm. If the lr-type field is zero (0), then no
+ information is conveyed by the lr-value subfield. If the absolute
+ value of the lr-type field is one (1), then the lr-value subfield is
+ the time of last initial request for a TGT. If it is two (2), then the
+ lr-value subfield is the time of last initial request. If it is three
+ (3), then the lr-value subfield is the time of issue for the newest
+ ticket-granting ticket used. If it is four (4), then the lr-value
+ subfield is the time of the last renewal. If it is five (5), then the
+ lr-value subfield is the time of last request (of any type). If it is
+ (6), then the lr-value subfield is the time when the password will
+ expire.
+lr-value
+ This field contains the time of the last request. the time must be
+ interpreted according to the contents of the accompanying lr-type
+ subfield.
+
+See section 6 for the definitions of Checksum, ChecksumType, EncryptedData,
+EncryptionKey, EncryptionType, and KeyType.
+
+5.3. Tickets and Authenticators
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+This section describes the format and encryption parameters for tickets and
+authenticators. When a ticket or authenticator is included in a protocol
+message it is treated as an opaque object.
+
+5.3.1. Tickets
+
+A ticket is a record that helps a client authenticate to a service. A
+Ticket contains the following information:
+
+Ticket ::= [APPLICATION 1] SEQUENCE {
+ tkt-vno[0] INTEGER,
+ realm[1] Realm,
+ sname[2] PrincipalName,
+ enc-part[3] EncryptedData,
+ extensions[4] TicketExtensions OPTIONAL
+}
+
+-- Encrypted part of ticket
+EncTicketPart ::= [APPLICATION 3] SEQUENCE {
+ flags[0] TicketFlags,
+ key[1] EncryptionKey,
+ crealm[2] Realm,
+ cname[3] PrincipalName,
+ transited[4] TransitedEncoding,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ caddr[9] HostAddresses OPTIONAL,
+ authorization-data[10] AuthorizationData OPTIONAL
+}
+-- encoded Transited field
+TransitedEncoding ::= SEQUENCE {
+ tr-type[0] INTEGER, -- must be
+registered
+ contents[1] OCTET STRING
+}
+
+The encoding of EncTicketPart is encrypted in the key shared by Kerberos
+and the end server (the server's secret key). See section 6 for the format
+of the ciphertext.
+
+tkt-vno
+ This field specifies the version number for the ticket format. This
+ document describes version number 5.
+realm
+ This field specifies the realm that issued a ticket. It also serves to
+ identify the realm part of the server's principal identifier. Since a
+ Kerberos server can only issue tickets for servers within its realm,
+ the two will always be identical.
+sname
+ This field specifies the name part of the server's identity.
+enc-part
+ This field holds the encrypted encoding of the EncTicketPart sequence.
+extensions
+ This optional field contains a sequence of extentions that may be used
+ to carry information that must be carried with the ticket to support
+ several extensions, including but not limited to plaintext
+ authorization data, tokens for exchanging inter-realm keys, and other
+ information that must be associated with a ticket for use by the
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ application server. See Appendix C for definitions of some common
+ extensions.
+
+ Note that some older versions of Kerberos did not support this field.
+ Because this is an optional field it will not break older clients, but
+ older clients might strip this field from the ticket before sending it
+ to the application server. This limits the usefulness of this ticket
+ field to environments where the ticket will not be parsed and
+ reconstructed by these older Kerberos clients.
+
+ If it is known that the client will strip this field from the ticket,
+ as an interim measure the KDC may append this field to the end of the
+ enc-part of the ticket and append a traler indicating the lenght of
+ the appended extensions field. (this paragraph is open for discussion,
+ including the form of the traler).
+flags
+ This field indicates which of various options were used or requested
+ when the ticket was issued. It is a bit-field, where the selected
+ options are indicated by the bit being set (1), and the unselected
+ options and reserved fields being reset (0). Bit 0 is the most
+ significant bit. The encoding of the bits is specified in section 5.2.
+ The flags are described in more detail above in section 2. The
+ meanings of the flags are:
+
+ Bit(s) Name Description
+
+ 0 RESERVED
+ Reserved for future expansion of this
+ field.
+
+ 1 FORWARDABLE
+ The FORWARDABLE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. When set, this
+ flag tells the ticket-granting server
+ that it is OK to issue a new ticket-
+ granting ticket with a different network
+ address based on the presented ticket.
+
+ 2 FORWARDED
+ When set, this flag indicates that the
+ ticket has either been forwarded or was
+ issued based on authentication involving
+ a forwarded ticket-granting ticket.
+
+ 3 PROXIABLE
+ The PROXIABLE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. The PROXIABLE
+ flag has an interpretation identical to
+ that of the FORWARDABLE flag, except
+ that the PROXIABLE flag tells the
+ ticket-granting server that only non-
+ ticket-granting tickets may be issued
+ with different network addresses.
+
+ 4 PROXY
+ When set, this flag indicates that a
+ ticket is a proxy.
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+ 5 MAY-POSTDATE
+ The MAY-POSTDATE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. This flag tells
+ the ticket-granting server that a post-
+ dated ticket may be issued based on this
+ ticket-granting ticket.
+
+ 6 POSTDATED
+ This flag indicates that this ticket has
+ been postdated. The end-service can
+ check the authtime field to see when the
+ original authentication occurred.
+
+ 7 INVALID
+ This flag indicates that a ticket is
+ invalid, and it must be validated by the
+ KDC before use. Application servers
+ must reject tickets which have this flag
+ set.
+
+ 8 RENEWABLE
+ The RENEWABLE flag is normally only
+ interpreted by the TGS, and can usually
+ be ignored by end servers (some particu-
+ larly careful servers may wish to disal-
+ low renewable tickets). A renewable
+ ticket can be used to obtain a replace-
+ ment ticket that expires at a later
+ date.
+
+ 9 INITIAL
+ This flag indicates that this ticket was
+ issued using the AS protocol, and not
+ issued based on a ticket-granting
+ ticket.
+
+ 10 PRE-AUTHENT
+ This flag indicates that during initial
+ authentication, the client was authenti-
+ cated by the KDC before a ticket was
+ issued. The strength of the pre-
+ authentication method is not indicated,
+ but is acceptable to the KDC.
+
+ 11 HW-AUTHENT
+ This flag indicates that the protocol
+ employed for initial authentication
+ required the use of hardware expected to
+ be possessed solely by the named client.
+ The hardware authentication method is
+ selected by the KDC and the strength of
+ the method is not indicated.
+
+ 12 TRANSITED This flag indicates that the KDC for the
+ POLICY-CHECKED realm has checked the transited field
+ against a realm defined policy for
+ trusted certifiers. If this flag is
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ reset (0), then the application server
+ must check the transited field itself,
+ and if unable to do so it must reject
+ the authentication. If the flag is set
+ (1) then the application server may skip
+ its own validation of the transited
+ field, relying on the validation
+ performed by the KDC. At its option the
+ application server may still apply its
+ own validation based on a separate
+ policy for acceptance.
+
+ 13 OK-AS-DELEGATE This flag indicates that the server (not
+ the client) specified in the ticket has
+ been determined by policy of the realm
+ to be a suitable recipient of
+ delegation. A client can use the
+ presence of this flag to help it make a
+ decision whether to delegate credentials
+ (either grant a proxy or a forwarded
+ ticket granting ticket) to this server.
+ The client is free to ignore the value
+ of this flag. When setting this flag,
+ an administrator should consider the
+ Security and placement of the server on
+ which the service will run, as well as
+ whether the service requires the use of
+ delegated credentials.
+
+ 14 ANONYMOUS
+ This flag indicates that the principal
+ named in the ticket is a generic princi-
+ pal for the realm and does not identify
+ the individual using the ticket. The
+ purpose of the ticket is only to
+ securely distribute a session key, and
+ not to identify the user. Subsequent
+ requests using the same ticket and ses-
+ sion may be considered as originating
+ from the same user, but requests with
+ the same username but a different ticket
+ are likely to originate from different
+ users.
+
+ 15-31 RESERVED
+ Reserved for future use.
+
+key
+ This field exists in the ticket and the KDC response and is used to
+ pass the session key from Kerberos to the application server and the
+ client. The field's encoding is described in section 6.2.
+crealm
+ This field contains the name of the realm in which the client is
+ registered and in which initial authentication took place.
+cname
+ This field contains the name part of the client's principal
+ identifier.
+transited
+ This field lists the names of the Kerberos realms that took part in
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ authenticating the user to whom this ticket was issued. It does not
+ specify the order in which the realms were transited. See section
+ 3.3.3.2 for details on how this field encodes the traversed realms.
+ When the names of CA's are to be embedded inthe transited field (as
+ specified for some extentions to the protocol), the X.500 names of the
+ CA's should be mapped into items in the transited field using the
+ mapping defined by RFC2253.
+authtime
+ This field indicates the time of initial authentication for the named
+ principal. It is the time of issue for the original ticket on which
+ this ticket is based. It is included in the ticket to provide
+ additional information to the end service, and to provide the
+ necessary information for implementation of a `hot list' service at
+ the KDC. An end service that is particularly paranoid could refuse to
+ accept tickets for which the initial authentication occurred "too far"
+ in the past. This field is also returned as part of the response from
+ the KDC. When returned as part of the response to initial
+ authentication (KRB_AS_REP), this is the current time on the Ker-
+ beros server[24].
+starttime
+ This field in the ticket specifies the time after which the ticket is
+ valid. Together with endtime, this field specifies the life of the
+ ticket. If it is absent from the ticket, its value should be treated
+ as that of the authtime field.
+endtime
+ This field contains the time after which the ticket will not be
+ honored (its expiration time). Note that individual services may place
+ their own limits on the life of a ticket and may reject tickets which
+ have not yet expired. As such, this is really an upper bound on the
+ expiration time for the ticket.
+renew-till
+ This field is only present in tickets that have the RENEWABLE flag set
+ in the flags field. It indicates the maximum endtime that may be
+ included in a renewal. It can be thought of as the absolute expiration
+ time for the ticket, including all renewals.
+caddr
+ This field in a ticket contains zero (if omitted) or more (if present)
+ host addresses. These are the addresses from which the ticket can be
+ used. If there are no addresses, the ticket can be used from any
+ location. The decision by the KDC to issue or by the end server to
+ accept zero-address tickets is a policy decision and is left to the
+ Kerberos and end-service administrators; they may refuse to issue or
+ accept such tickets. The suggested and default policy, however, is
+ that such tickets will only be issued or accepted when additional
+ information that can be used to restrict the use of the ticket is
+ included in the authorization_data field. Such a ticket is a
+ capability.
+
+ Network addresses are included in the ticket to make it harder for an
+ attacker to use stolen credentials. Because the session key is not
+ sent over the network in cleartext, credentials can't be stolen simply
+ by listening to the network; an attacker has to gain access to the
+ session key (perhaps through operating system security breaches or a
+ careless user's unattended session) to make use of stolen tickets.
+
+ It is important to note that the network address from which a
+ connection is received cannot be reliably determined. Even if it could
+ be, an attacker who has compromised the client's worksta- tion could
+ use the credentials from there. Including the network addresses only
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ makes it more difficult, not impossible, for an attacker to walk off
+ with stolen credentials and then use them from a "safe" location.
+authorization-data
+ The authorization-data field is used to pass authorization data from
+ the principal on whose behalf a ticket was issued to the application
+ service. If no authorization data is included, this field will be left
+ out. Experience has shown that the name of this field is confusing,
+ and that a better name for this field would be restrictions.
+ Unfortunately, it is not possible to change the name of this field at
+ this time.
+
+ This field contains restrictions on any authority obtained on the
+ basis of authentication using the ticket. It is possible for any
+ principal in posession of credentials to add entries to the
+ authorization data field since these entries further restrict what can
+ be done with the ticket. Such additions can be made by specifying the
+ additional entries when a new ticket is obtained during the TGS
+ exchange, or they may be added during chained delegation using the
+ authorization data field of the authenticator.
+
+ Because entries may be added to this field by the holder of
+ credentials, it is not allowable for the presence of an entry in the
+ authorization data field of a ticket to amplify the priveleges one
+ would obtain from using a ticket.
+
+ The data in this field may be specific to the end service; the field
+ will contain the names of service specific objects, and the rights to
+ those objects. The format for this field is described in section 5.2.
+ Although Kerberos is not concerned with the format of the contents of
+ the sub-fields, it does carry type information (ad-type).
+
+ By using the authorization_data field, a principal is able to issue a
+ proxy that is valid for a specific purpose. For example, a client
+ wishing to print a file can obtain a file server proxy to be passed to
+ the print server. By specifying the name of the file in the
+ authorization_data field, the file server knows that the print server
+ can only use the client's rights when accessing the particular file to
+ be printed.
+
+ A separate service providing authorization or certifying group
+ membership may be built using the authorization-data field. In this
+ case, the entity granting authorization (not the authorized entity),
+ obtains a ticket in its own name (e.g. the ticket is issued in the
+ name of a privelege server), and this entity adds restrictions on its
+ own authority and delegates the restricted authority through a proxy
+ to the client. The client would then present this authorization
+ credential to the application server separately from the
+ authentication exchange.
+
+ Similarly, if one specifies the authorization-data field of a proxy
+ and leaves the host addresses blank, the resulting ticket and session
+ key can be treated as a capability. See [Neu93] for some suggested
+ uses of this field.
+
+ The authorization-data field is optional and does not have to be
+ included in a ticket.
+
+5.3.2. Authenticators
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+An authenticator is a record sent with a ticket to a server to certify the
+client's knowledge of the encryption key in the ticket, to help the server
+detect replays, and to help choose a "true session key" to use with the
+particular session. The encoding is encrypted in the ticket's session key
+shared by the client and the server:
+
+-- Unencrypted authenticator
+Authenticator ::= [APPLICATION 2] SEQUENCE {
+ authenticator-vno[0] INTEGER,
+ crealm[1] Realm,
+ cname[2] PrincipalName,
+ cksum[3] Checksum OPTIONAL,
+ cusec[4] INTEGER,
+ ctime[5] KerberosTime,
+ subkey[6] EncryptionKey OPTIONAL,
+ seq-number[7] INTEGER OPTIONAL,
+ authorization-data[8] AuthorizationData OPTIONAL
+}
+
+
+authenticator-vno
+ This field specifies the version number for the format of the
+ authenticator. This document specifies version 5.
+crealm and cname
+ These fields are the same as those described for the ticket in section
+ 5.3.1.
+cksum
+ This field contains a checksum of the the applica- tion data that
+ accompanies the KRB_AP_REQ.
+cusec
+ This field contains the microsecond part of the client's timestamp.
+ Its value (before encryption) ranges from 0 to 999999. It often
+ appears along with ctime. The two fields are used together to specify
+ a reasonably accurate timestamp.
+ctime
+ This field contains the current time on the client's host.
+subkey
+ This field contains the client's choice for an encryption key which is
+ to be used to protect this specific application session. Unless an
+ application specifies otherwise, if this field is left out the session
+ key from the ticket will be used.
+seq-number
+ This optional field includes the initial sequence number to be used by
+ the KRB_PRIV or KRB_SAFE messages when sequence numbers are used to
+ detect replays (It may also be used by application specific messages).
+ When included in the authenticator this field specifies the initial
+ sequence number for messages from the client to the server. When
+ included in the AP-REP message, the initial sequence number is that
+ for messages from the server to the client. When used in KRB_PRIV or
+ KRB_SAFE messages, it is incremented by one after each message is
+ sent. Sequence numbers fall in the range of 0 through 2^32 - 1 and
+ wrap to zero following the value 2^32 - 1.
+
+ For sequence numbers to adequately support the detection of replays
+ they should be non-repeating, even across connection boundaries. The
+ initial sequence number should be random and uniformly distributed
+ across the full space of possible sequence numbers, so that it cannot
+ be guessed by an attacker and so that it and the successive sequence
+ numbers do not repeat other sequences.
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+authorization-data
+ This field is the same as described for the ticket in section 5.3.1.
+ It is optional and will only appear when additional restrictions are
+ to be placed on the use of a ticket, beyond those carried in the
+ ticket itself.
+
+5.4. Specifications for the AS and TGS exchanges
+
+This section specifies the format of the messages used in the exchange
+between the client and the Kerberos server. The format of possible error
+messages appears in section 5.9.1.
+
+5.4.1. KRB_KDC_REQ definition
+
+The KRB_KDC_REQ message has no type of its own. Instead, its type is one of
+KRB_AS_REQ or KRB_TGS_REQ depending on whether the request is for an
+initial ticket or an additional ticket. In either case, the message is sent
+from the client to the Authentication Server to request credentials for a
+service.
+
+The message fields are:
+
+AS-REQ ::= [APPLICATION 10] KDC-REQ
+TGS-REQ ::= [APPLICATION 12] KDC-REQ
+
+KDC-REQ ::= SEQUENCE {
+ pvno[1] INTEGER,
+ msg-type[2] INTEGER,
+ padata[3] SEQUENCE OF PA-DATA OPTIONAL,
+ req-body[4] KDC-REQ-BODY
+}
+
+PA-DATA ::= SEQUENCE {
+ padata-type[1] INTEGER,
+ padata-value[2] OCTET STRING,
+ -- might be encoded AP-REQ
+}
+
+KDC-REQ-BODY ::= SEQUENCE {
+ kdc-options[0] KDCOptions,
+ cname[1] PrincipalName OPTIONAL,
+ -- Used only in AS-REQ
+ realm[2] Realm, -- Server's realm
+ -- Also client's in AS-REQ
+ sname[3] PrincipalName OPTIONAL,
+ from[4] KerberosTime OPTIONAL,
+ till[5] KerberosTime OPTIONAL,
+ rtime[6] KerberosTime OPTIONAL,
+ nonce[7] INTEGER,
+ etype[8] SEQUENCE OF INTEGER,
+ -- EncryptionType,
+ -- in preference order
+ addresses[9] HostAddresses OPTIONAL,
+ enc-authorization-data[10] EncryptedData OPTIONAL,
+ -- Encrypted AuthorizationData
+ -- encoding
+ additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
+}
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+The fields in this message are:
+
+pvno
+ This field is included in each message, and specifies the protocol
+ version number. This document specifies protocol version 5.
+msg-type
+ This field indicates the type of a protocol message. It will almost
+ always be the same as the application identifier associated with a
+ message. It is included to make the identifier more readily accessible
+ to the application. For the KDC-REQ message, this type will be
+ KRB_AS_REQ or KRB_TGS_REQ.
+padata
+ The padata (pre-authentication data) field contains a sequence of
+ authentication information which may be needed before credentials can
+ be issued or decrypted. In the case of requests for additional tickets
+ (KRB_TGS_REQ), this field will include an element with padata-type of
+ PA-TGS-REQ and data of an authentication header (ticket-granting
+ ticket and authenticator). The checksum in the authenticator (which
+ must be collision-proof) is to be computed over the KDC-REQ-BODY
+ encoding. In most requests for initial authentication (KRB_AS_REQ) and
+ most replies (KDC-REP), the padata field will be left out.
+
+ This field may also contain information needed by certain extensions
+ to the Kerberos protocol. For example, it might be used to initially
+ verify the identity of a client before any response is returned. This
+ is accomplished with a padata field with padata-type equal to
+ PA-ENC-TIMESTAMP and padata-value defined as follows:
+
+ padata-type ::= PA-ENC-TIMESTAMP
+ padata-value ::= EncryptedData -- PA-ENC-TS-ENC
+
+ PA-ENC-TS-ENC ::= SEQUENCE {
+ patimestamp[0] KerberosTime, -- client's time
+ pausec[1] INTEGER OPTIONAL
+ }
+
+ with patimestamp containing the client's time and pausec containing
+ the microseconds which may be omitted if a client will not generate
+ more than one request per second. The ciphertext (padata-value)
+ consists of the PA-ENC-TS-ENC sequence, encrypted using the client's
+ secret key.
+
+ [use-specified-kvno item is here for discussion and may be removed] It
+ may also be used by the client to specify the version of a key that is
+ being used for accompanying preauthentication, and/or which should be
+ used to encrypt the reply from the KDC.
+
+ PA-USE-SPECIFIED-KVNO ::= Integer
+
+ The KDC should only accept and abide by the value of the
+ use-specified-kvno preauthentication data field when the specified key
+ is still valid and until use of a new key is confirmed. This situation
+ is likely to occur primarily during the period during which an updated
+ key is propagating to other KDC's in a realm.
+
+ The padata field can also contain information needed to help the KDC
+ or the client select the key needed for generating or decrypting the
+ response. This form of the padata is useful for supporting the use of
+ certain token cards with Kerberos. The details of such extensions are
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ specified in separate documents. See [Pat92] for additional uses of
+ this field.
+padata-type
+ The padata-type element of the padata field indicates the way that the
+ padata-value element is to be interpreted. Negative values of
+ padata-type are reserved for unregistered use; non-negative values are
+ used for a registered interpretation of the element type.
+req-body
+ This field is a placeholder delimiting the extent of the remaining
+ fields. If a checksum is to be calculated over the request, it is
+ calculated over an encoding of the KDC-REQ-BODY sequence which is
+ enclosed within the req-body field.
+kdc-options
+ This field appears in the KRB_AS_REQ and KRB_TGS_REQ requests to the
+ KDC and indicates the flags that the client wants set on the tickets
+ as well as other information that is to modify the behavior of the
+ KDC. Where appropriate, the name of an option may be the same as the
+ flag that is set by that option. Although in most case, the bit in the
+ options field will be the same as that in the flags field, this is not
+ guaranteed, so it is not acceptable to simply copy the options field
+ to the flags field. There are various checks that must be made before
+ honoring an option anyway.
+
+ The kdc_options field is a bit-field, where the selected options are
+ indicated by the bit being set (1), and the unselected options and
+ reserved fields being reset (0). The encoding of the bits is specified
+ in section 5.2. The options are described in more detail above in
+ section 2. The meanings of the options are:
+
+ Bit(s) Name Description
+ 0 RESERVED
+ Reserved for future expansion of
+this
+ field.
+
+ 1 FORWARDABLE
+ The FORWARDABLE option indicates
+that
+ the ticket to be issued is to have
+its
+ forwardable flag set. It may only
+be
+ set on the initial request, or in a
+sub-
+ sequent request if the
+ticket-granting
+ ticket on which it is based is also
+for-
+ wardable.
+
+ 2 FORWARDED
+ The FORWARDED option is only
+specified
+ in a request to the
+ticket-granting
+ server and will only be honored if
+the
+ ticket-granting ticket in the
+request
+ has its FORWARDABLE bit set.
+This
+ option indicates that this is a
+request
+ for forwarding. The address(es) of
+the
+ host from which the resulting ticket
+is
+ to be valid are included in
+the
+ addresses field of the request.
+
+ 3 PROXIABLE
+ The PROXIABLE option indicates that
+the
+ ticket to be issued is to have its
+prox-
+ iable flag set. It may only be set
+on
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ the initial request, or in a
+subsequent
+ request if the ticket-granting ticket
+on
+ which it is based is also proxiable.
+
+ 4 PROXY
+ The PROXY option indicates that this
+is
+ a request for a proxy. This option
+will
+ only be honored if the
+ticket-granting
+ ticket in the request has its
+PROXIABLE
+ bit set. The address(es) of the
+host
+ from which the resulting ticket is to
+be
+ valid are included in the
+addresses
+ field of the request.
+
+ 5 ALLOW-POSTDATE
+ The ALLOW-POSTDATE option indicates
+that
+ the ticket to be issued is to have
+its
+ MAY-POSTDATE flag set. It may only
+be
+ set on the initial request, or in a
+sub-
+ sequent request if the
+ticket-granting
+ ticket on which it is based also has
+its
+ MAY-POSTDATE flag set.
+
+ 6 POSTDATED
+ The POSTDATED option indicates that
+this
+ is a request for a postdated
+ticket.
+ This option will only be honored if
+the
+ ticket-granting ticket on which
+ it is based has its MAY-POSTDATE
+ flag set.
+ The resulting ticket will also have
+its
+ INVALID flag set, and that flag may
+be
+ reset by a subsequent request to the
+KDC
+ after the starttime in the ticket
+has
+ been reached.
+
+ 7 UNUSED
+ This option is presently unused.
+
+ 8 RENEWABLE
+ The RENEWABLE option indicates that
+the
+ ticket to be issued is to have
+its
+ RENEWABLE flag set. It may only be
+set
+ on the initial request, or when
+the
+ ticket-granting ticket on which
+the
+ request is based is also renewable.
+If
+ this option is requested, then the
+rtime
+ field in the request contains
+the
+ desired absolute expiration time for
+the
+ ticket.
+
+ 9-13 UNUSED
+ These options are presently unused.
+
+ 14 REQUEST-ANONYMOUS
+ The REQUEST-ANONYMOUS option
+indicates
+ that the ticket to be issued is not
+to
+ identify the user to which it
+was
+ issued. Instead, the principal
+identif-
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ ier is to be generic, as specified
+by
+ the policy of the realm (e.g.
+usually
+ anonymous@realm). The purpose of
+the
+ ticket is only to securely distribute
+a
+ session key, and not to identify
+the
+ user. The ANONYMOUS flag on the
+ticket
+ to be returned should be set. If
+the
+ local realms policy does not
+permit
+ anonymous credentials, the request is
+to
+ be rejected.
+
+ 15-25 RESERVED
+ Reserved for future use.
+
+ 26 DISABLE-TRANSITED-CHECK
+ By default the KDC will check the
+ transited field of a ticket-granting-
+ ticket against the policy of the local
+ realm before it will issue derivative
+ tickets based on the ticket granting
+ ticket. If this flag is set in the
+ request, checking of the transited
+field
+ is disabled. Tickets issued without
+the
+ performance of this check will be
+noted
+ by the reset (0) value of the
+ TRANSITED-POLICY-CHECKED flag,
+ indicating to the application server
+ that the tranisted field must be
+checked
+ locally. KDC's are encouraged but not
+ required to honor the
+ DISABLE-TRANSITED-CHECK option.
+
+ 27 RENEWABLE-OK
+ The RENEWABLE-OK option indicates that
+a
+ renewable ticket will be acceptable if
+a
+ ticket with the requested life
+cannot
+ otherwise be provided. If a ticket
+with
+ the requested life cannot be
+provided,
+ then a renewable ticket may be
+issued
+ with a renew-till equal to the
+the
+ requested endtime. The value of
+the
+ renew-till field may still be limited
+by
+ local limits, or limits selected by
+the
+ individual principal or server.
+
+ 28 ENC-TKT-IN-SKEY
+ This option is used only by the
+ticket-
+ granting service. The
+ENC-TKT-IN-SKEY
+ option indicates that the ticket for
+the
+ end server is to be encrypted in
+the
+ session key from the additional
+ticket-
+ granting ticket provided.
+
+ 29 RESERVED
+ Reserved for future use.
+
+ 30 RENEW
+ This option is used only by the
+ticket-
+ granting service. The RENEW
+option
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ indicates that the present request
+is
+ for a renewal. The ticket provided
+is
+ encrypted in the secret key for
+the
+ server on which it is valid.
+This
+ option will only be honored if
+the
+ ticket to be renewed has its
+RENEWABLE
+ flag set and if the time in its
+renew-
+ till field has not passed. The
+ticket
+ to be renewed is passed in the
+padata
+ field as part of the
+authentication
+ header.
+
+ 31 VALIDATE
+ This option is used only by the
+ticket-
+ granting service. The VALIDATE
+option
+ indicates that the request is to
+vali-
+ date a postdated ticket. It will
+only
+ be honored if the ticket presented
+is
+ postdated, presently has its
+INVALID
+ flag set, and would be otherwise
+usable
+ at this time. A ticket cannot be
+vali-
+ dated before its starttime. The
+ticket
+ presented for validation is encrypted
+in
+ the key of the server for which it
+is
+ valid and is passed in the padata
+field
+ as part of the authentication header.
+
+cname and sname
+ These fields are the same as those described for the ticket in section
+ 5.3.1. sname may only be absent when the ENC-TKT-IN-SKEY option is
+ specified. If absent, the name of the server is taken from the name of
+ the client in the ticket passed as additional-tickets.
+enc-authorization-data
+ The enc-authorization-data, if present (and it can only be present in
+ the TGS_REQ form), is an encoding of the desired authorization-data
+ encrypted under the sub-session key if present in the Authenticator,
+ or alternatively from the session key in the ticket-granting ticket,
+ both from the padata field in the KRB_AP_REQ.
+realm
+ This field specifies the realm part of the server's principal
+ identifier. In the AS exchange, this is also the realm part of the
+ client's principal identifier.
+from
+ This field is included in the KRB_AS_REQ and KRB_TGS_REQ ticket
+ requests when the requested ticket is to be postdated. It specifies
+ the desired start time for the requested ticket. If this field is
+ omitted then the KDC should use the current time instead.
+till
+ This field contains the expiration date requested by the client in a
+ ticket request. It is optional and if omitted the requested ticket is
+ to have the maximum endtime permitted according to KDC policy for the
+ parties to the authentication exchange as limited by expiration date
+ of the ticket granting ticket or other preauthentication credentials.
+rtime
+ This field is the requested renew-till time sent from a client to the
+ KDC in a ticket request. It is optional.
+nonce
+ This field is part of the KDC request and response. It it intended to
+ hold a random number generated by the client. If the same number is
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ included in the encrypted response from the KDC, it provides evidence
+ that the response is fresh and has not been replayed by an attacker.
+ Nonces must never be re-used. Ideally, it should be generated
+ randomly, but if the correct time is known, it may suffice[25].
+etype
+ This field specifies the desired encryption algorithm to be used in
+ the response.
+addresses
+ This field is included in the initial request for tickets, and
+ optionally included in requests for additional tickets from the
+ ticket-granting server. It specifies the addresses from which the
+ requested ticket is to be valid. Normally it includes the addresses
+ for the client's host. If a proxy is requested, this field will
+ contain other addresses. The contents of this field are usually copied
+ by the KDC into the caddr field of the resulting ticket.
+additional-tickets
+ Additional tickets may be optionally included in a request to the
+ ticket-granting server. If the ENC-TKT-IN-SKEY option has been
+ specified, then the session key from the additional ticket will be
+ used in place of the server's key to encrypt the new ticket. If more
+ than one option which requires additional tickets has been specified,
+ then the additional tickets are used in the order specified by the
+ ordering of the options bits (see kdc-options, above).
+
+The application code will be either ten (10) or twelve (12) depending on
+whether the request is for an initial ticket (AS-REQ) or for an additional
+ticket (TGS-REQ).
+
+The optional fields (addresses, authorization-data and additional-tickets)
+are only included if necessary to perform the operation specified in the
+kdc-options field.
+
+It should be noted that in KRB_TGS_REQ, the protocol version number appears
+twice and two different message types appear: the KRB_TGS_REQ message
+contains these fields as does the authentication header (KRB_AP_REQ) that
+is passed in the padata field.
+
+5.4.2. KRB_KDC_REP definition
+
+The KRB_KDC_REP message format is used for the reply from the KDC for
+either an initial (AS) request or a subsequent (TGS) request. There is no
+message type for KRB_KDC_REP. Instead, the type will be either KRB_AS_REP
+or KRB_TGS_REP. The key used to encrypt the ciphertext part of the reply
+depends on the message type. For KRB_AS_REP, the ciphertext is encrypted in
+the client's secret key, and the client's key version number is included in
+the key version number for the encrypted data. For KRB_TGS_REP, the
+ciphertext is encrypted in the sub-session key from the Authenticator, or
+if absent, the session key from the ticket-granting ticket used in the
+request. In that case, no version number will be present in the
+EncryptedData sequence.
+
+The KRB_KDC_REP message contains the following fields:
+
+AS-REP ::= [APPLICATION 11] KDC-REP
+TGS-REP ::= [APPLICATION 13] KDC-REP
+
+KDC-REP ::= SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ padata[2] SEQUENCE OF PA-DATA OPTIONAL,
+ crealm[3] Realm,
+ cname[4] PrincipalName,
+ ticket[5] Ticket,
+ enc-part[6] EncryptedData
+}
+
+EncASRepPart ::= [APPLICATION 25[27]] EncKDCRepPart
+EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
+
+EncKDCRepPart ::= SEQUENCE {
+ key[0] EncryptionKey,
+ last-req[1] LastReq,
+ nonce[2] INTEGER,
+ key-expiration[3] KerberosTime OPTIONAL,
+ flags[4] TicketFlags,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ srealm[9] Realm,
+ sname[10] PrincipalName,
+ caddr[11] HostAddresses OPTIONAL
+}
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is either
+ KRB_AS_REP or KRB_TGS_REP.
+padata
+ This field is described in detail in section 5.4.1. One possible use
+ for this field is to encode an alternate "mix-in" string to be used
+ with a string-to-key algorithm (such as is described in section
+ 6.3.2). This ability is useful to ease transitions if a realm name
+ needs to change (e.g. when a company is acquired); in such a case all
+ existing password-derived entries in the KDC database would be flagged
+ as needing a special mix-in string until the next password change.
+crealm, cname, srealm and sname
+ These fields are the same as those described for the ticket in section
+ 5.3.1.
+ticket
+ The newly-issued ticket, from section 5.3.1.
+enc-part
+ This field is a place holder for the ciphertext and related
+ information that forms the encrypted part of a message. The
+ description of the encrypted part of the message follows each
+ appearance of this field. The encrypted part is encoded as described
+ in section 6.1.
+key
+ This field is the same as described for the ticket in section 5.3.1.
+last-req
+ This field is returned by the KDC and specifies the time(s) of the
+ last request by a principal. Depending on what information is
+ available, this might be the last time that a request for a
+ ticket-granting ticket was made, or the last time that a request based
+ on a ticket-granting ticket was successful. It also might cover all
+ servers for a realm, or just the particular server. Some
+ implementations may display this information to the user to aid in
+ discovering unauthorized use of one's identity. It is similar in
+ spirit to the last login time displayed when logging into timesharing
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ systems.
+nonce
+ This field is described above in section 5.4.1.
+key-expiration
+ The key-expiration field is part of the response from the KDC and
+ specifies the time that the client's secret key is due to expire. The
+ expiration might be the result of password aging or an account
+ expiration. This field will usually be left out of the TGS reply since
+ the response to the TGS request is encrypted in a session key and no
+ client information need be retrieved from the KDC database. It is up
+ to the application client (usually the login program) to take
+ appropriate action (such as notifying the user) if the expiration time
+ is imminent.
+flags, authtime, starttime, endtime, renew-till and caddr
+ These fields are duplicates of those found in the encrypted portion of
+ the attached ticket (see section 5.3.1), provided so the client may
+ verify they match the intended request and to assist in proper ticket
+ caching. If the message is of type KRB_TGS_REP, the caddr field will
+ only be filled in if the request was for a proxy or forwarded ticket,
+ or if the user is substituting a subset of the addresses from the
+ ticket granting ticket. If the client-requested addresses are not
+ present or not used, then the addresses contained in the ticket will
+ be the same as those included in the ticket-granting ticket.
+
+5.5. Client/Server (CS) message specifications
+
+This section specifies the format of the messages used for the
+authentication of the client to the application server.
+
+5.5.1. KRB_AP_REQ definition
+
+The KRB_AP_REQ message contains the Kerberos protocol version number, the
+message type KRB_AP_REQ, an options field to indicate any options in use,
+and the ticket and authenticator themselves. The KRB_AP_REQ message is
+often referred to as the 'authentication header'.
+
+AP-REQ ::= [APPLICATION 14] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ap-options[2] APOptions,
+ ticket[3] Ticket,
+ authenticator[4] EncryptedData
+}
+
+APOptions ::= BIT STRING {
+ reserved(0),
+ use-session-key(1),
+ mutual-required(2)
+}
+
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_AP_REQ.
+ap-options
+ This field appears in the application request (KRB_AP_REQ) and affects
+ the way the request is processed. It is a bit-field, where the
+ selected options are indicated by the bit being set (1), and the
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ unselected options and reserved fields being reset (0). The encoding
+ of the bits is specified in section 5.2. The meanings of the options
+ are:
+
+ Bit(s) Name Description
+
+ 0 RESERVED
+ Reserved for future expansion of
+this
+ field.
+
+ 1 USE-SESSION-KEY
+ The USE-SESSION-KEY option
+indicates
+ that the ticket the client is
+presenting
+ to a server is encrypted in the
+session
+ key from the server's
+ticket-granting
+ ticket. When this option is not
+speci-
+ fied, the ticket is encrypted in
+the
+ server's secret key.
+
+ 2 MUTUAL-REQUIRED
+ The MUTUAL-REQUIRED option tells
+the
+ server that the client requires
+mutual
+ authentication, and that it must
+respond
+ with a KRB_AP_REP message.
+
+ 3-31 RESERVED
+ Reserved for future use.
+
+ticket
+ This field is a ticket authenticating the client to the server.
+authenticator
+ This contains the authenticator, which includes the client's choice of
+ a subkey. Its encoding is described in section 5.3.2.
+
+5.5.2. KRB_AP_REP definition
+
+The KRB_AP_REP message contains the Kerberos protocol version number, the
+message type, and an encrypted time- stamp. The message is sent in in
+response to an application request (KRB_AP_REQ) where the mutual
+authentication option has been selected in the ap-options field.
+
+AP-REP ::= [APPLICATION 15] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[2] EncryptedData
+}
+
+EncAPRepPart ::= [APPLICATION 27[29]] SEQUENCE {
+ ctime[0] KerberosTime,
+ cusec[1] INTEGER,
+ subkey[2] EncryptionKey OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL
+}
+
+The encoded EncAPRepPart is encrypted in the shared session key of the
+ticket. The optional subkey field can be used in an application-arranged
+negotiation to choose a per association session key.
+
+pvno and msg-type
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_AP_REP.
+enc-part
+ This field is described above in section 5.4.2.
+ctime
+ This field contains the current time on the client's host.
+cusec
+ This field contains the microsecond part of the client's timestamp.
+subkey
+ This field contains an encryption key which is to be used to protect
+ this specific application session. See section 3.2.6 for specifics on
+ how this field is used to negotiate a key. Unless an application
+ specifies otherwise, if this field is left out, the sub-session key
+ from the authenticator, or if also left out, the session key from the
+ ticket will be used.
+
+5.5.3. Error message reply
+
+If an error occurs while processing the application request, the KRB_ERROR
+message will be sent in response. See section 5.9.1 for the format of the
+error message. The cname and crealm fields may be left out if the server
+cannot determine their appropriate values from the corresponding KRB_AP_REQ
+message. If the authenticator was decipherable, the ctime and cusec fields
+will contain the values from it.
+
+5.6. KRB_SAFE message specification
+
+This section specifies the format of a message that can be used by either
+side (client or server) of an application to send a tamper-proof message to
+its peer. It presumes that a session key has previously been exchanged (for
+example, by using the KRB_AP_REQ/KRB_AP_REP messages).
+
+5.6.1. KRB_SAFE definition
+
+The KRB_SAFE message contains user data along with a collision-proof
+checksum keyed with the last encryption key negotiated via subkeys, or the
+session key if no negotiation has occured. The message fields are:
+
+KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ safe-body[2] KRB-SAFE-BODY,
+ cksum[3] Checksum
+}
+
+KRB-SAFE-BODY ::= SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+}
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_SAFE.
+safe-body
+ This field is a placeholder for the body of the KRB-SAFE message.
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+cksum
+ This field contains the checksum of the application data. Checksum
+ details are described in section 6.4. The checksum is computed over
+ the encoding of the KRB-SAFE sequence. First, the cksum is zeroed and
+ the checksum is computed over the encoding of the KRB-SAFE sequence,
+ then the checksum is set to the result of that computation, and
+ finally the KRB-SAFE sequence is encoded again.
+user-data
+ This field is part of the KRB_SAFE and KRB_PRIV messages and contain
+ the application specific data that is being passed from the sender to
+ the recipient.
+timestamp
+ This field is part of the KRB_SAFE and KRB_PRIV messages. Its contents
+ are the current time as known by the sender of the message. By
+ checking the timestamp, the recipient of the message is able to make
+ sure that it was recently generated, and is not a replay.
+usec
+ This field is part of the KRB_SAFE and KRB_PRIV headers. It contains
+ the microsecond part of the timestamp.
+seq-number
+ This field is described above in section 5.3.2.
+s-address
+ This field specifies the address in use by the sender of the message.
+r-address
+ This field specifies the address in use by the recipient of the
+ message. It may be omitted for some uses (such as broadcast
+ protocols), but the recipient may arbitrarily reject such messages.
+ This field along with s-address can be used to help detect messages
+ which have been incorrectly or maliciously delivered to the wrong
+ recipient.
+
+5.7. KRB_PRIV message specification
+
+This section specifies the format of a message that can be used by either
+side (client or server) of an application to securely and privately send a
+message to its peer. It presumes that a session key has previously been
+exchanged (for example, by using the KRB_AP_REQ/KRB_AP_REP messages).
+
+5.7.1. KRB_PRIV definition
+
+The KRB_PRIV message contains user data encrypted in the Session Key. The
+message fields are:
+
+KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[3] EncryptedData
+}
+
+EncKrbPrivPart ::= [APPLICATION 28[31]] SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL, -- sender's
+addr
+ r-address[5] HostAddress OPTIONAL -- recip's
+addr
+}
+
+pvno and msg-type
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_PRIV.
+enc-part
+ This field holds an encoding of the EncKrbPrivPart sequence encrypted
+ under the session key[32]. This encrypted encoding is used for the
+ enc-part field of the KRB-PRIV message. See section 6 for the format
+ of the ciphertext.
+user-data, timestamp, usec, s-address and r-address
+ These fields are described above in section 5.6.1.
+seq-number
+ This field is described above in section 5.3.2.
+
+5.8. KRB_CRED message specification
+
+This section specifies the format of a message that can be used to send
+Kerberos credentials from one principal to another. It is presented here to
+encourage a common mechanism to be used by applications when forwarding
+tickets or providing proxies to subordinate servers. It presumes that a
+session key has already been exchanged perhaps by using the
+KRB_AP_REQ/KRB_AP_REP messages.
+
+5.8.1. KRB_CRED definition
+
+The KRB_CRED message contains a sequence of tickets to be sent and
+information needed to use the tickets, including the session key from each.
+The information needed to use the tickets is encrypted under an encryption
+key previously exchanged or transferred alongside the KRB_CRED message. The
+message fields are:
+
+KRB-CRED ::= [APPLICATION 22] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER, -- KRB_CRED
+ tickets[2] SEQUENCE OF Ticket,
+ enc-part[3] EncryptedData
+}
+
+EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
+ ticket-info[0] SEQUENCE OF KrbCredInfo,
+ nonce[1] INTEGER OPTIONAL,
+ timestamp[2] KerberosTime OPTIONAL,
+ usec[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+}
+
+KrbCredInfo ::= SEQUENCE {
+ key[0] EncryptionKey,
+ prealm[1] Realm OPTIONAL,
+ pname[2] PrincipalName OPTIONAL,
+ flags[3] TicketFlags OPTIONAL,
+ authtime[4] KerberosTime OPTIONAL,
+ starttime[5] KerberosTime OPTIONAL,
+ endtime[6] KerberosTime OPTIONAL
+ renew-till[7] KerberosTime OPTIONAL,
+ srealm[8] Realm OPTIONAL,
+ sname[9] PrincipalName OPTIONAL,
+ caddr[10] HostAddresses OPTIONAL
+}
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_CRED.
+tickets
+ These are the tickets obtained from the KDC specifically for use by
+ the intended recipient. Successive tickets are paired with the
+ corresponding KrbCredInfo sequence from the enc-part of the KRB-CRED
+ message.
+enc-part
+ This field holds an encoding of the EncKrbCredPart sequence encrypted
+ under the session key shared between the sender and the intended
+ recipient. This encrypted encoding is used for the enc-part field of
+ the KRB-CRED message. See section 6 for the format of the ciphertext.
+nonce
+ If practical, an application may require the inclusion of a nonce
+ generated by the recipient of the message. If the same value is
+ included as the nonce in the message, it provides evidence that the
+ message is fresh and has not been replayed by an attacker. A nonce
+ must never be re-used; it should be generated randomly by the
+ recipient of the message and provided to the sender of the message in
+ an application specific manner.
+timestamp and usec
+ These fields specify the time that the KRB-CRED message was generated.
+ The time is used to provide assurance that the message is fresh.
+s-address and r-address
+ These fields are described above in section 5.6.1. They are used
+ optionally to provide additional assurance of the integrity of the
+ KRB-CRED message.
+key
+ This field exists in the corresponding ticket passed by the KRB-CRED
+ message and is used to pass the session key from the sender to the
+ intended recipient. The field's encoding is described in section 6.2.
+
+The following fields are optional. If present, they can be associated with
+the credentials in the remote ticket file. If left out, then it is assumed
+that the recipient of the credentials already knows their value.
+
+prealm and pname
+ The name and realm of the delegated principal identity.
+flags, authtime, starttime, endtime, renew-till, srealm, sname, and caddr
+ These fields contain the values of the correspond- ing fields from the
+ ticket found in the ticket field. Descriptions of the fields are
+ identical to the descriptions in the KDC-REP message.
+
+5.9. Error message specification
+
+This section specifies the format for the KRB_ERROR message. The fields
+included in the message are intended to return as much information as
+possible about an error. It is not expected that all the information
+required by the fields will be available for all types of errors. If the
+appropriate information is not available when the message is composed, the
+corresponding field will be left out of the message.
+
+Note that since the KRB_ERROR message is not protected by any encryption,
+it is quite possible for an intruder to synthesize or modify such a
+message. In particular, this means that the client should not use any
+fields in this message for security-critical purposes, such as setting a
+system clock or generating a fresh authenticator. The message can be
+useful, however, for advising a user on the reason for some failure.
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+5.9.1. KRB_ERROR definition
+
+The KRB_ERROR message consists of the following fields:
+
+KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ctime[2] KerberosTime OPTIONAL,
+ cusec[3] INTEGER OPTIONAL,
+ stime[4] KerberosTime,
+ susec[5] INTEGER,
+ error-code[6] INTEGER,
+ crealm[7] Realm OPTIONAL,
+ cname[8] PrincipalName OPTIONAL,
+ realm[9] Realm, -- Correct realm
+ sname[10] PrincipalName, -- Correct name
+ e-text[11] GeneralString OPTIONAL,
+ e-data[12] OCTET STRING OPTIONAL,
+ e-cksum[13] Checksum OPTIONAL,
+ e-typed-data[14] SEQUENCE of ETypedData
+OPTIONAL
+}
+
+ETypedData ::= SEQUENCE {
+ e-data-type [1] INTEGER,
+ e-data-value [2] OCTET STRING,
+}
+
+
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_ERROR.
+ctime
+ This field is described above in section 5.4.1.
+cusec
+ This field is described above in section 5.5.2.
+stime
+ This field contains the current time on the server. It is of type
+ KerberosTime.
+susec
+ This field contains the microsecond part of the server's timestamp.
+ Its value ranges from 0 to 999999. It appears along with stime. The
+ two fields are used in conjunction to specify a reasonably accurate
+ timestamp.
+error-code
+ This field contains the error code returned by Kerberos or the server
+ when a request fails. To interpret the value of this field see the
+ list of error codes in section 8. Implementations are encouraged to
+ provide for national language support in the display of error
+ messages.
+crealm, cname, srealm and sname
+ These fields are described above in section 5.3.1.
+e-text
+ This field contains additional text to help explain the error code
+ associated with the failed request (for example, it might include a
+ principal name which was unknown).
+e-data
+ This field contains additional data about the error for use by the
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ application to help it recover from or handle the error. If the
+ errorcode is KDC_ERR_PREAUTH_REQUIRED, then the e-data field will
+ contain an encoding of a sequence of padata fields, each corresponding
+ to an acceptable pre-authentication method and optionally containing
+ data for the method:
+
+ METHOD-DATA ::= SEQUENCE of PA-DATA
+
+ If the error-code is KRB_AP_ERR_METHOD, then the e-data field will
+ contain an encoding of the following sequence:
+
+ METHOD-DATA ::= SEQUENCE {
+ method-type[0] INTEGER,
+ method-data[1] OCTET STRING OPTIONAL
+ }
+
+ method-type will indicate the required alternate method; method-data
+ will contain any required additional information.
+e-cksum
+ This field contains an optional checksum for the KRB-ERROR message.
+ The checksum is calculated over the Kerberos ASN.1 encoding of the
+ KRB-ERROR message with the checksum absent. The checksum is then added
+ to the KRB-ERROR structure and the message is re-encoded. The Checksum
+ should be calculated using the session key from the ticket granting
+ ticket or service ticket, where available. If the error is in response
+ to a TGS or AP request, the checksum should be calculated uing the the
+ session key from the client's ticket. If the error is in response to
+ an AS request, then the checksum should be calulated using the
+ client's secret key ONLY if there has been suitable preauthentication
+ to prove knowledge of the secret key by the client[33]. If a checksum
+ can not be computed because the key to be used is not available, no
+ checksum will be included.
+e-typed-data
+ [This field for discussion, may be deleted from final spec] This field
+ contains optional data that may be used to help the client recover
+ from the indicated error. [This could contain the METHOD-DATA
+ specified since I don't think anyone actually uses it yet. It could
+ also contain the PA-DATA sequence for the preauth required error if we
+ had a clear way to transition to the use of this field from the use of
+ the untype e-data field.] For example, this field may specify the key
+ version of the key used to verify preauthentication:
+
+ e-data-type := 20 -- Key version number
+ e-data-value := Integer -- Key version number used to verify
+preauthentication
+
+6. Encryption and Checksum Specifications
+
+The Kerberos protocols described in this document are designed to use
+stream encryption ciphers, which can be simulated using commonly available
+block encryption ciphers, such as the Data Encryption Standard, [DES77] in
+conjunction with block chaining and checksum methods [DESM80]. Encryption
+is used to prove the identities of the network entities participating in
+message exchanges. The Key Distribution Center for each realm is trusted by
+all principals registered in that realm to store a secret key in
+confidence. Proof of knowledge of this secret key is used to verify the
+authenticity of a principal.
+
+The KDC uses the principal's secret key (in the AS exchange) or a shared
+session key (in the TGS exchange) to encrypt responses to ticket requests;
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+the ability to obtain the secret key or session key implies the knowledge
+of the appropriate keys and the identity of the KDC. The ability of a
+principal to decrypt the KDC response and present a Ticket and a properly
+formed Authenticator (generated with the session key from the KDC response)
+to a service verifies the identity of the principal; likewise the ability
+of the service to extract the session key from the Ticket and prove its
+knowledge thereof in a response verifies the identity of the service.
+
+The Kerberos protocols generally assume that the encryption used is secure
+from cryptanalysis; however, in some cases, the order of fields in the
+encrypted portions of messages are arranged to minimize the effects of
+poorly chosen keys. It is still important to choose good keys. If keys are
+derived from user-typed passwords, those passwords need to be well chosen
+to make brute force attacks more difficult. Poorly chosen keys still make
+easy targets for intruders.
+
+The following sections specify the encryption and checksum mechanisms
+currently defined for Kerberos. The encodings, chaining, and padding
+requirements for each are described. For encryption methods, it is often
+desirable to place random information (often referred to as a confounder)
+at the start of the message. The requirements for a confounder are
+specified with each encryption mechanism.
+
+Some encryption systems use a block-chaining method to improve the the
+security characteristics of the ciphertext. However, these chaining methods
+often don't provide an integrity check upon decryption. Such systems (such
+as DES in CBC mode) must be augmented with a checksum of the plain-text
+which can be verified at decryption and used to detect any tampering or
+damage. Such checksums should be good at detecting burst errors in the
+input. If any damage is detected, the decryption routine is expected to
+return an error indicating the failure of an integrity check. Each
+encryption type is expected to provide and verify an appropriate checksum.
+The specification of each encryption method sets out its checksum
+requirements.
+
+Finally, where a key is to be derived from a user's password, an algorithm
+for converting the password to a key of the appropriate type is included.
+It is desirable for the string to key function to be one-way, and for the
+mapping to be different in different realms. This is important because
+users who are registered in more than one realm will often use the same
+password in each, and it is desirable that an attacker compromising the
+Kerberos server in one realm not obtain or derive the user's key in
+another.
+
+For an discussion of the integrity characteristics of the candidate
+encryption and checksum methods considered for Kerberos, the the reader is
+referred to [SG92].
+
+6.1. Encryption Specifications
+
+The following ASN.1 definition describes all encrypted messages. The
+enc-part field which appears in the unencrypted part of messages in section
+5 is a sequence consisting of an encryption type, an optional key version
+number, and the ciphertext.
+
+EncryptedData ::= SEQUENCE {
+ etype[0] INTEGER, -- EncryptionType
+ kvno[1] INTEGER OPTIONAL,
+ cipher[2] OCTET STRING -- ciphertext
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+}
+
+
+
+etype
+ This field identifies which encryption algorithm was used to encipher
+ the cipher. Detailed specifications for selected encryption types
+ appear later in this section.
+kvno
+ This field contains the version number of the key under which data is
+ encrypted. It is only present in messages encrypted under long lasting
+ keys, such as principals' secret keys.
+cipher
+ This field contains the enciphered text, encoded as an OCTET STRING.
+
+The cipher field is generated by applying the specified encryption
+algorithm to data composed of the message and algorithm-specific inputs.
+Encryption mechanisms defined for use with Kerberos must take sufficient
+measures to guarantee the integrity of the plaintext, and we recommend they
+also take measures to protect against precomputed dictionary attacks. If
+the encryption algorithm is not itself capable of doing so, the protections
+can often be enhanced by adding a checksum and a confounder.
+
+The suggested format for the data to be encrypted includes a confounder, a
+checksum, the encoded plaintext, and any necessary padding. The msg-seq
+field contains the part of the protocol message described in section 5
+which is to be encrypted. The confounder, checksum, and padding are all
+untagged and untyped, and their length is exactly sufficient to hold the
+appropriate item. The type and length is implicit and specified by the
+particular encryption type being used (etype). The format for the data to
+be encrypted is described in the following diagram:
+
+ +-----------+----------+-------------+-----+
+ |confounder | check | msg-seq | pad |
+ +-----------+----------+-------------+-----+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+CipherText ::= ENCRYPTED SEQUENCE {
+ confounder[0] UNTAGGED[35] OCTET STRING(conf_length) OPTIONAL,
+ check[1] UNTAGGED OCTET STRING(checksum_length) OPTIONAL,
+ msg-seq[2] MsgSequence,
+ pad UNTAGGED OCTET STRING(pad_length) OPTIONAL
+}
+
+One generates a random confounder of the appropriate length, placing it in
+confounder; zeroes out check; calculates the appropriate checksum over
+confounder, check, and msg-seq, placing the result in check; adds the
+necessary padding; then encrypts using the specified encryption type and
+the appropriate key.
+
+Unless otherwise specified, a definition of an encryption algorithm that
+specifies a checksum, a length for the confounder field, or an octet
+boundary for padding uses this ciphertext format[36]. Those fields which
+are not specified will be omitted.
+
+In the interest of allowing all implementations using a particular
+encryption type to communicate with all others using that type, the
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+specification of an encryption type defines any checksum that is needed as
+part of the encryption process. If an alternative checksum is to be used, a
+new encryption type must be defined.
+
+Some cryptosystems require additional information beyond the key and the
+data to be encrypted. For example, DES, when used in cipher-block-chaining
+mode, requires an initialization vector. If required, the description for
+each encryption type must specify the source of such additional
+information. 6.2. Encryption Keys
+
+The sequence below shows the encoding of an encryption key:
+
+ EncryptionKey ::= SEQUENCE {
+ keytype[0] INTEGER,
+ keyvalue[1] OCTET STRING
+ }
+
+keytype
+ This field specifies the type of encryption key that follows in the
+ keyvalue field. It will almost always correspond to the encryption
+ algorithm used to generate the EncryptedData, though more than one
+ algorithm may use the same type of key (the mapping is many to one).
+ This might happen, for example, if the encryption algorithm uses an
+ alternate checksum algorithm for an integrity check, or a different
+ chaining mechanism.
+keyvalue
+ This field contains the key itself, encoded as an octet string.
+
+All negative values for the encryption key type are reserved for local use.
+All non-negative values are reserved for officially assigned type fields
+and interpreta- tions.
+
+6.3. Encryption Systems
+
+6.3.1. The NULL Encryption System (null)
+
+If no encryption is in use, the encryption system is said to be the NULL
+encryption system. In the NULL encryption system there is no checksum,
+confounder or padding. The ciphertext is simply the plaintext. The NULL Key
+is used by the null encryption system and is zero octets in length, with
+keytype zero (0).
+
+6.3.2. DES in CBC mode with a CRC-32 checksum (des-cbc-crc)
+
+The des-cbc-crc encryption mode encrypts information under the Data
+Encryption Standard [DES77] using the cipher block chaining mode [DESM80].
+A CRC-32 checksum (described in ISO 3309 [ISO3309]) is applied to the
+confounder and message sequence (msg-seq) and placed in the cksum field.
+DES blocks are 8 bytes. As a result, the data to be encrypted (the
+concatenation of confounder, checksum, and message) must be padded to an 8
+byte boundary before encryption. The details of the encryption of this data
+are identical to those for the des-cbc-md5 encryption mode.
+
+Note that, since the CRC-32 checksum is not collision-proof, an attacker
+could use a probabilistic chosen-plaintext attack to generate a valid
+message even if a confounder is used [SG92]. The use of collision-proof
+checksums is recommended for environments where such attacks represent a
+significant threat. The use of the CRC-32 as the checksum for ticket or
+authenticator is no longer mandated as an interoperability requirement for
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+Kerberos Version 5 Specification 1 (See section 9.1 for specific details).
+
+6.3.3. DES in CBC mode with an MD4 checksum (des-cbc-md4)
+
+The des-cbc-md4 encryption mode encrypts information under the Data
+Encryption Standard [DES77] using the cipher block chaining mode [DESM80].
+An MD4 checksum (described in [MD492]) is applied to the confounder and
+message sequence (msg-seq) and placed in the cksum field. DES blocks are 8
+bytes. As a result, the data to be encrypted (the concatenation of
+confounder, checksum, and message) must be padded to an 8 byte boundary
+before encryption. The details of the encryption of this data are identical
+to those for the des-cbc-md5 encryption mode.
+
+6.3.4. DES in CBC mode with an MD5 checksum (des-cbc-md5)
+
+The des-cbc-md5 encryption mode encrypts information under the Data
+Encryption Standard [DES77] using the cipher block chaining mode [DESM80].
+An MD5 checksum (described in [MD5-92].) is applied to the confounder and
+message sequence (msg-seq) and placed in the cksum field. DES blocks are 8
+bytes. As a result, the data to be encrypted (the concatenation of
+confounder, checksum, and message) must be padded to an 8 byte boundary
+before encryption.
+
+Plaintext and DES ciphtertext are encoded as blocks of 8 octets which are
+concatenated to make the 64-bit inputs for the DES algorithms. The first
+octet supplies the 8 most significant bits (with the octet's MSbit used as
+the DES input block's MSbit, etc.), the second octet the next 8 bits, ...,
+and the eighth octet supplies the 8 least significant bits.
+
+Encryption under DES using cipher block chaining requires an additional
+input in the form of an initialization vector. Unless otherwise specified,
+zero should be used as the initialization vector. Kerberos' use of DES
+requires an 8 octet confounder.
+
+The DES specifications identify some 'weak' and 'semi-weak' keys; those
+keys shall not be used for encrypting messages for use in Kerberos.
+Additionally, because of the way that keys are derived for the encryption
+of checksums, keys shall not be used that yield 'weak' or 'semi-weak' keys
+when eXclusive-ORed with the hexadecimal constant F0F0F0F0F0F0F0F0.
+
+A DES key is 8 octets of data, with keytype one (1). This consists of 56
+bits of key, and 8 parity bits (one per octet). The key is encoded as a
+series of 8 octets written in MSB-first order. The bits within the key are
+also encoded in MSB order. For example, if the encryption key is
+(B1,B2,...,B7,P1,B8,...,B14,P2,B15,...,B49,P7,B50,...,B56,P8) where
+B1,B2,...,B56 are the key bits in MSB order, and P1,P2,...,P8 are the
+parity bits, the first octet of the key would be B1,B2,...,B7,P1 (with B1
+as the MSbit). [See the FIPS 81 introduction for reference.]
+
+String to key transformation
+
+To generate a DES key from a text string (password), a "salt" is
+concatenated to the text string, and then padded with ASCII nulls to an 8
+byte boundary. This "salt" is normally the realm and each component of the
+principal's name appended. However, sometimes different salts are used ---
+for example, when a realm is renamed, or if a user changes her username, or
+for compatibility with Kerberos V4 (whose string-to-key algorithm uses a
+null string for the salt). This string is then fan-folded and
+eXclusive-ORed with itself to form an 8 byte DES key. Before
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+eXclusive-ORing a block, every byte is shifted one bit to the left to leave
+the lowest bit zero. The key is the "corrected" by correcting the parity on
+the key, and if the key matches a 'weak' or 'semi-weak' key as described in
+the DES specification, it is eXclusive-ORed with the constant
+00000000000000F0. This key is then used to generate a DES CBC checksum on
+the initial string (with the salt appended). The result of the CBC checksum
+is the "corrected" as described above to form the result which is return as
+the key. Pseudocode follows:
+
+ name_to_default_salt(realm, name) {
+ s = realm
+ for(each component in name) {
+ s = s + component;
+ }
+ return s;
+ }
+
+ key_correction(key) {
+ fixparity(key);
+ if (is_weak_key_key(key))
+ key = key XOR 0xF0;
+ return(key);
+ }
+
+ string_to_key(string,salt) {
+
+ odd = 1;
+ s = string + salt;
+ tempkey = NULL;
+ pad(s); /* with nulls to 8 byte boundary */
+ for(8byteblock in s) {
+ if(odd == 0) {
+ odd = 1;
+ reverse(8byteblock)
+ }
+ else odd = 0;
+ left shift every byte in 8byteblock one bit;
+ tempkey = tempkey XOR 8byteblock;
+ }
+ tempkey = key_correction(tempkey);
+ key = key_correction(DES-CBC-check(s,tempkey));
+ return(key);
+ }
+
+6.3.5. Triple DES with HMAC-SHA1 Kerberos Encryption Type with Key
+Derivation [Horowitz]
+
+NOTE: This description currently refers to documents, the contents of which
+might be bettered included by value in this spec. The description below was
+provided by Marc Horowitz, and the form in which it will finally appear is
+yet to be determined. This description is included in this version of the
+draft because it does describe the implemenation ready for use with the MIT
+implementation. Note also that the encryption identifier has been left
+unspecified here because the value from Marc Horowitz's spec conflicted
+with some other impmenentations implemented based on perevious versions of
+the specification.
+
+This encryption type is based on the Triple DES cryptosystem, the HMAC-SHA1
+[Krawczyk96] message authentication algorithm, and key derivation for
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+Kerberos V5 [HorowitzB96].
+
+The des3-cbc-hmac-sha1 encryption type has been assigned the value ??. The
+hmac-sha1-des3 checksum type has been assigned the value 12.
+
+Encryption Type des3-cbc-hmac-sha1
+
+EncryptedData using this type must be generated as described in
+[Horowitz96]. The encryption algorithm is Triple DES in Outer-CBC mode. The
+keyed hash algorithm is HMAC-SHA1. Unless otherwise specified, a zero IV
+must be used. If the length of the input data is not a multiple of the
+block size, zero octets must be used to pad the plaintext to the next
+eight-octet boundary. The counfounder must be eight random octets (one
+block).
+
+Checksum Type hmac-sha1-des3
+
+Checksums using this type must be generated as described in [Horowitz96].
+The keyed hash algorithm is HMAC-SHA1.
+
+Common Requirements
+
+The EncryptionKey value is 24 octets long. The 7 most significant bits of
+each octet contain key bits, and the least significant bit is the inverse
+of the xor of the key bits.
+
+For the purposes of key derivation, the block size is 64 bits, and the key
+size is 168 bits. The 168 bits output by key derivation are converted to an
+EncryptionKey value as follows. First, the 168 bits are divided into three
+groups of 56 bits, which are expanded individually into 64 bits as follows:
+
+ 1 2 3 4 5 6 7 p
+ 9 10 11 12 13 14 15 p
+17 18 19 20 21 22 23 p
+25 26 27 28 29 30 31 p
+33 34 35 36 37 38 39 p
+41 42 43 44 45 46 47 p
+49 50 51 52 53 54 55 p
+56 48 40 32 24 16 8 p
+
+The "p" bits are parity bits computed over the data bits. The output of the
+three expansions are concatenated to form the EncryptionKey value.
+
+When the HMAC-SHA1 of a string is computed, the key is used in the
+EncryptedKey form.
+
+Key Derivation
+
+In the Kerberos protocol, cryptographic keys are used in a number of
+places. In order to minimize the effect of compromising a key, it is
+desirable to use a different key for each of these places. Key derivation
+[Horowitz96] can be used to construct different keys for each operation
+from the keys transported on the network. For this to be possible, a small
+change to the specification is necessary.
+
+This section specifies a profile for the use of key derivation [Horowitz96]
+with Kerberos. For each place where a key is used, a ``key usage'' must is
+specified for that purpose. The key, key usage, and encryption/checksum
+type together describe the transformation from plaintext to ciphertext, or
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+plaintext to checksum.
+
+Key Usage Values
+
+This is a complete list of places keys are used in the kerberos protocol,
+with key usage values and RFC 1510 section numbers:
+
+ 1. AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
+ client key (section 5.4.1)
+ 2. AS-REP Ticket and TGS-REP Ticket (includes tgs session key or
+ application session key), encrypted with the service key
+ (section 5.4.2)
+ 3. AS-REP encrypted part (includes tgs session key or application
+ session key), encrypted with the client key (section 5.4.2)
+ 4. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ session key (section 5.4.1)
+ 5. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ authenticator subkey (section 5.4.1)
+ 6. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
+ with the tgs session key (sections 5.3.2, 5.4.1)
+ 7. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes tgs
+ authenticator subkey), encrypted with the tgs session key
+ (section 5.3.2)
+ 8. TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs session key (section 5.4.2)
+ 9. TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs authenticator subkey (section 5.4.2)
+10. AP-REQ Authenticator cksum, keyed with the application session
+ key (section 5.3.2)
+11. AP-REQ Authenticator (includes application authenticator
+ subkey), encrypted with the application session key (section
+ 5.3.2)
+12. AP-REP encrypted part (includes application session subkey),
+ encrypted with the application session key (section 5.5.2)
+13. KRB-PRIV encrypted part, encrypted with a key chosen by the
+ application (section 5.7.1)
+14. KRB-CRED encrypted part, encrypted with a key chosen by the
+ application (section 5.6.1)
+15. KRB-SAVE cksum, keyed with a key chosen by the application
+ (section 5.8.1)
+18. KRB-ERROR checksum (e-cksum in section 5.9.1)
+19. AD-KDCIssued checksum (ad-checksum in appendix B.1)
+20. Checksum for Mandatory Ticket Extensions (appendix B.6)
+21. Checksum in Authorization Data in Ticket Extensions (appendix B.7)
+
+Key usage values between 1024 and 2047 (inclusive) are reserved for
+application use. Applications should use even values for encryption and odd
+values for checksums within this range.
+
+A few of these key usages need a little clarification. A service which
+receives an AP-REQ has no way to know if the enclosed Ticket was part of an
+AS-REP or TGS-REP. Therefore, key usage 2 must always be used for
+generating a Ticket, whether it is in response to an AS- REQ or TGS-REQ.
+
+There might exist other documents which define protocols in terms of the
+RFC1510 encryption types or checksum types. Such documents would not know
+about key usages. In order that these documents continue to be meaningful
+until they are updated, key usages 1024 and 1025 must be used to derive
+keys for encryption and checksums, respectively. New protocols defined in
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+terms of the Kerberos encryption and checksum types should use their own
+key usages. Key usages may be registered with IANA to avoid conflicts. Key
+usages must be unsigned 32 bit integers. Zero is not permitted.
+
+Defining Cryptosystems Using Key Derivation
+
+Kerberos requires that the ciphertext component of EncryptedData be
+tamper-resistant as well as confidential. This implies encryption and
+integrity functions, which must each use their own separate keys. So, for
+each key usage, two keys must be generated, one for encryption (Ke), and
+one for integrity (Ki):
+
+ Ke = DK(protocol key, key usage | 0xAA)
+ Ki = DK(protocol key, key usage | 0x55)
+
+where the protocol key is from the EncryptionKey from the wire protocol,
+and the key usage is represented as a 32 bit integer in network byte order.
+The ciphertest must be generated from the plaintext as follows:
+
+ ciphertext = E(Ke, confounder | plaintext | padding) |
+ H(Ki, confounder | plaintext | padding)
+
+The confounder and padding are specific to the encryption algorithm E.
+
+When generating a checksum only, there is no need for a confounder or
+padding. Again, a new key (Kc) must be used. Checksums must be generated
+from the plaintext as follows:
+
+ Kc = DK(protocol key, key usage | 0x99)
+
+ MAC = H(Kc, plaintext)
+
+Note that each enctype is described by an encryption algorithm E and a
+keyed hash algorithm H, and each checksum type is described by a keyed hash
+algorithm H. HMAC, with an appropriate hash, is recommended for use as H.
+
+Key Derivation from Passwords
+
+The well-known constant for password key derivation must be the byte string
+{0x6b 0x65 0x72 0x62 0x65 0x72 0x6f 0x73}. These values correspond to the
+ASCII encoding for the string "kerberos".
+
+6.4. Checksums
+
+The following is the ASN.1 definition used for a checksum:
+
+ Checksum ::= SEQUENCE {
+ cksumtype[0] INTEGER,
+ checksum[1] OCTET STRING
+ }
+
+cksumtype
+ This field indicates the algorithm used to generate the accompanying
+ checksum.
+checksum
+ This field contains the checksum itself, encoded as an octet string.
+
+Detailed specification of selected checksum types appear later in this
+section. Negative values for the checksum type are reserved for local use.
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+All non-negative values are reserved for officially assigned type fields
+and interpretations.
+
+Checksums used by Kerberos can be classified by two properties: whether
+they are collision-proof, and whether they are keyed. It is infeasible to
+find two plaintexts which generate the same checksum value for a
+collision-proof checksum. A key is required to perturb or initialize the
+algorithm in a keyed checksum. To prevent message-stream modification by an
+active attacker, unkeyed checksums should only be used when the checksum
+and message will be subsequently encrypted (e.g. the checksums defined as
+part of the encryption algorithms covered earlier in this section).
+
+Collision-proof checksums can be made tamper-proof if the checksum value is
+encrypted before inclusion in a message. In such cases, the composition of
+the checksum and the encryption algorithm must be considered a separate
+checksum algorithm (e.g. RSA-MD5 encrypted using DES is a new checksum
+algorithm of type RSA-MD5-DES). For most keyed checksums, as well as for
+the encrypted forms of unkeyed collision-proof checksums, Kerberos prepends
+a confounder before the checksum is calculated.
+
+6.4.1. The CRC-32 Checksum (crc32)
+
+The CRC-32 checksum calculates a checksum based on a cyclic redundancy
+check as described in ISO 3309 [ISO3309]. The resulting checksum is four
+(4) octets in length. The CRC-32 is neither keyed nor collision-proof. The
+use of this checksum is not recommended. An attacker using a probabilistic
+chosen-plaintext attack as described in [SG92] might be able to generate an
+alternative message that satisfies the checksum. The use of collision-proof
+checksums is recommended for environments where such attacks represent a
+significant threat.
+
+6.4.2. The RSA MD4 Checksum (rsa-md4)
+
+The RSA-MD4 checksum calculates a checksum using the RSA MD4 algorithm
+[MD4-92]. The algorithm takes as input an input message of arbitrary length
+and produces as output a 128-bit (16 octet) checksum. RSA-MD4 is believed
+to be collision-proof.
+
+6.4.3. RSA MD4 Cryptographic Checksum Using DES (rsa-md4-des)
+
+The RSA-MD4-DES checksum calculates a keyed collision-proof checksum by
+prepending an 8 octet confounder before the text, applying the RSA MD4
+checksum algorithm, and encrypting the confounder and the checksum using
+DES in cipher-block-chaining (CBC) mode using a variant of the key, where
+the variant is computed by eXclusive-ORing the key with the constant
+F0F0F0F0F0F0F0F0[39]. The initialization vector should be zero. The
+resulting checksum is 24 octets long (8 octets of which are redundant).
+This checksum is tamper-proof and believed to be collision-proof.
+
+The DES specifications identify some weak keys' and 'semi-weak keys'; those
+keys shall not be used for generating RSA-MD4 checksums for use in
+Kerberos.
+
+The format for the checksum is described in the follow- ing diagram:
+
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+| des-cbc(confounder + rsa-md4(confounder+msg),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+rsa-md4-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(16)
+}
+
+6.4.4. The RSA MD5 Checksum (rsa-md5)
+
+The RSA-MD5 checksum calculates a checksum using the RSA MD5 algorithm.
+[MD5-92]. The algorithm takes as input an input message of arbitrary length
+and produces as output a 128-bit (16 octet) checksum. RSA-MD5 is believed
+to be collision-proof.
+
+6.4.5. RSA MD5 Cryptographic Checksum Using DES (rsa-md5-des)
+
+The RSA-MD5-DES checksum calculates a keyed collision-proof checksum by
+prepending an 8 octet confounder before the text, applying the RSA MD5
+checksum algorithm, and encrypting the confounder and the checksum using
+DES in cipher-block-chaining (CBC) mode using a variant of the key, where
+the variant is computed by eXclusive-ORing the key with the hexadecimal
+constant F0F0F0F0F0F0F0F0. The initialization vector should be zero. The
+resulting checksum is 24 octets long (8 octets of which are redundant).
+This checksum is tamper-proof and believed to be collision-proof.
+
+The DES specifications identify some 'weak keys' and 'semi-weak keys';
+those keys shall not be used for encrypting RSA-MD5 checksums for use in
+Kerberos.
+
+The format for the checksum is described in the following diagram:
+
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+| des-cbc(confounder + rsa-md5(confounder+msg),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+rsa-md5-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(16)
+}
+
+6.4.6. DES cipher-block chained checksum (des-mac)
+
+The DES-MAC checksum is computed by prepending an 8 octet confounder to the
+plaintext, performing a DES CBC-mode encryption on the result using the key
+and an initialization vector of zero, taking the last block of the
+ciphertext, prepending the same confounder and encrypting the pair using
+DES in cipher-block-chaining (CBC) mode using a a variant of the key, where
+the variant is computed by eXclusive-ORing the key with the hexadecimal
+constant F0F0F0F0F0F0F0F0. The initialization vector should be zero. The
+resulting checksum is 128 bits (16 octets) long, 64 bits of which are
+redundant. This checksum is tamper-proof and collision-proof.
+
+The format for the checksum is described in the following diagram:
+
++--+--+--+--+--+--+--+--+-----+-----+-----+-----+-----+-----+-----+-----+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+| des-cbc(confounder + des-mac(conf+msg,iv=0,key),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+-----+-----+-----+-----+-----+-----+-----+-----+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+des-mac-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(8)
+}
+
+The DES specifications identify some 'weak' and 'semi-weak' keys; those
+keys shall not be used for generating DES-MAC checksums for use in
+Kerberos, nor shall a key be used whose variant is 'weak' or 'semi-weak'.
+
+6.4.7. RSA MD4 Cryptographic Checksum Using DES alternative (rsa-md4-des-k)
+
+The RSA-MD4-DES-K checksum calculates a keyed collision-proof checksum by
+applying the RSA MD4 checksum algorithm and encrypting the results using
+DES in cipher-block-chaining (CBC) mode using a DES key as both key and
+initialization vector. The resulting checksum is 16 octets long. This
+checksum is tamper-proof and believed to be collision-proof. Note that this
+checksum type is the old method for encoding the RSA-MD4-DES checksum and
+it is no longer recommended.
+
+6.4.8. DES cipher-block chained checksum alternative (des-mac-k)
+
+The DES-MAC-K checksum is computed by performing a DES CBC-mode encryption
+of the plaintext, and using the last block of the ciphertext as the
+checksum value. It is keyed with an encryption key and an initialization
+vector; any uses which do not specify an additional initialization vector
+will use the key as both key and initialization vector. The resulting
+checksum is 64 bits (8 octets) long. This checksum is tamper-proof and
+collision-proof. Note that this checksum type is the old method for
+encoding the DES-MAC checksum and it is no longer recommended. The DES
+specifications identify some 'weak keys' and 'semi-weak keys'; those keys
+shall not be used for generating DES-MAC checksums for use in Kerberos.
+
+7. Naming Constraints
+
+7.1. Realm Names
+
+Although realm names are encoded as GeneralStrings and although a realm can
+technically select any name it chooses, interoperability across realm
+boundaries requires agreement on how realm names are to be assigned, and
+what information they imply.
+
+To enforce these conventions, each realm must conform to the conventions
+itself, and it must require that any realms with which inter-realm keys are
+shared also conform to the conventions and require the same from its
+neighbors.
+
+Kerberos realm names are case sensitive. Realm names that differ only in
+the case of the characters are not equivalent. There are presently four
+styles of realm names: domain, X500, other, and reserved. Examples of each
+style follow:
+
+ domain: ATHENA.MIT.EDU (example)
+ X500: C=US/O=OSF (example)
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ other: NAMETYPE:rest/of.name=without-restrictions (example)
+ reserved: reserved, but will not conflict with above
+
+Domain names must look like domain names: they consist of components
+separated by periods (.) and they contain neither colons (:) nor slashes
+(/). Domain names must be converted to upper case when used as realm names.
+
+X.500 names contain an equal (=) and cannot contain a colon (:) before the
+equal. The realm names for X.500 names will be string representations of
+the names with components separated by slashes. Leading and trailing
+slashes will not be included.
+
+Names that fall into the other category must begin with a prefix that
+contains no equal (=) or period (.) and the prefix must be followed by a
+colon (:) and the rest of the name. All prefixes must be assigned before
+they may be used. Presently none are assigned.
+
+The reserved category includes strings which do not fall into the first
+three categories. All names in this category are reserved. It is unlikely
+that names will be assigned to this category unless there is a very strong
+argument for not using the 'other' category.
+
+These rules guarantee that there will be no conflicts between the various
+name styles. The following additional constraints apply to the assignment
+of realm names in the domain and X.500 categories: the name of a realm for
+the domain or X.500 formats must either be used by the organization owning
+(to whom it was assigned) an Internet domain name or X.500 name, or in the
+case that no such names are registered, authority to use a realm name may
+be derived from the authority of the parent realm. For example, if there is
+no domain name for E40.MIT.EDU, then the administrator of the MIT.EDU realm
+can authorize the creation of a realm with that name.
+
+This is acceptable because the organization to which the parent is assigned
+is presumably the organization authorized to assign names to its children
+in the X.500 and domain name systems as well. If the parent assigns a realm
+name without also registering it in the domain name or X.500 hierarchy, it
+is the parent's responsibility to make sure that there will not in the
+future exists a name identical to the realm name of the child unless it is
+assigned to the same entity as the realm name.
+
+7.2. Principal Names
+
+As was the case for realm names, conventions are needed to ensure that all
+agree on what information is implied by a principal name. The name-type
+field that is part of the principal name indicates the kind of information
+implied by the name. The name-type should be treated as a hint. Ignoring
+the name type, no two names can be the same (i.e. at least one of the
+components, or the realm, must be different). The following name types are
+defined:
+
+ name-type value meaning
+
+ NT-UNKNOWN 0 Name type not known
+ NT-PRINCIPAL 1 General principal name (e.g. username, or DCE
+principal)
+ NT-SRV-INST 2 Service and other unique instance (krbtgt)
+ NT-SRV-HST 3 Service with host name as instance (telnet,
+rcommands)
+ NT-SRV-XHST 4 Service with slash-separated host name components
+ NT-UID 5 Unique ID
+ NT-X500-PRINCIPAL 6 Encoded X.509 Distingished name [RFC 1779]
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+When a name implies no information other than its uniqueness at a
+particular time the name type PRINCIPAL should be used. The principal name
+type should be used for users, and it might also be used for a unique
+server. If the name is a unique machine generated ID that is guaranteed
+never to be reassigned then the name type of UID should be used (note that
+it is generally a bad idea to reassign names of any type since stale
+entries might remain in access control lists).
+
+If the first component of a name identifies a service and the remaining
+components identify an instance of the service in a server specified
+manner, then the name type of SRV-INST should be used. An example of this
+name type is the Kerberos ticket-granting service whose name has a first
+component of krbtgt and a second component identifying the realm for which
+the ticket is valid.
+
+If instance is a single component following the service name and the
+instance identifies the host on which the server is running, then the name
+type SRV-HST should be used. This type is typically used for Internet
+services such as telnet and the Berkeley R commands. If the separate
+components of the host name appear as successive components following the
+name of the service, then the name type SRV-XHST should be used. This type
+might be used to identify servers on hosts with X.500 names where the slash
+(/) might otherwise be ambiguous.
+
+A name type of NT-X500-PRINCIPAL should be used when a name from an X.509
+certificiate is translated into a Kerberos name. The encoding of the X.509
+name as a Kerberos principal shall conform to the encoding rules specified
+in RFC 2253.
+
+A name type of UNKNOWN should be used when the form of the name is not
+known. When comparing names, a name of type UNKNOWN will match principals
+authenticated with names of any type. A principal authenticated with a name
+of type UNKNOWN, however, will only match other names of type UNKNOWN.
+
+Names of any type with an initial component of 'krbtgt' are reserved for
+the Kerberos ticket granting service. See section 8.2.3 for the form of
+such names.
+
+7.2.1. Name of server principals
+
+The principal identifier for a server on a host will generally be composed
+of two parts: (1) the realm of the KDC with which the server is registered,
+and (2) a two-component name of type NT-SRV-HST if the host name is an
+Internet domain name or a multi-component name of type NT-SRV-XHST if the
+name of the host is of a form such as X.500 that allows slash (/)
+separators. The first component of the two- or multi-component name will
+identify the service and the latter components will identify the host.
+Where the name of the host is not case sensitive (for example, with
+Internet domain names) the name of the host must be lower case. If
+specified by the application protocol for services such as telnet and the
+Berkeley R commands which run with system privileges, the first component
+may be the string 'host' instead of a service specific identifier. When a
+host has an official name and one or more aliases, the official name of the
+host must be used when constructing the name of the server principal.
+
+8. Constants and other defined values
+
+8.1. Host address types
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+All negative values for the host address type are reserved for local use.
+All non-negative values are reserved for officially assigned type fields
+and interpretations.
+
+The values of the types for the following addresses are chosen to match the
+defined address family constants in the Berkeley Standard Distributions of
+Unix. They can be found in with symbolic names AF_xxx (where xxx is an
+abbreviation of the address family name).
+
+Internet (IPv4) Addresses
+
+Internet (IPv4) addresses are 32-bit (4-octet) quantities, encoded in MSB
+order. The type of IPv4 addresses is two (2).
+
+Internet (IPv6) Addresses [Westerlund]
+
+IPv6 addresses are 128-bit (16-octet) quantities, encoded in MSB order. The
+type of IPv6 addresses is twenty-four (24). [RFC1883] [RFC1884]. The
+following addresses (see [RFC1884]) MUST not appear in any Kerberos packet:
+
+ * the Unspecified Address
+ * the Loopback Address
+ * Link-Local addresses
+
+IPv4-mapped IPv6 addresses MUST be represented as addresses of type 2.
+
+CHAOSnet addresses
+
+CHAOSnet addresses are 16-bit (2-octet) quantities, encoded in MSB order.
+The type of CHAOSnet addresses is five (5).
+
+ISO addresses
+
+ISO addresses are variable-length. The type of ISO addresses is seven (7).
+
+Xerox Network Services (XNS) addresses
+
+XNS addresses are 48-bit (6-octet) quantities, encoded in MSB order. The
+type of XNS addresses is six (6).
+
+AppleTalk Datagram Delivery Protocol (DDP) addresses
+
+AppleTalk DDP addresses consist of an 8-bit node number and a 16-bit
+network number. The first octet of the address is the node number; the
+remaining two octets encode the network number in MSB order. The type of
+AppleTalk DDP addresses is sixteen (16).
+
+DECnet Phase IV addresses
+
+DECnet Phase IV addresses are 16-bit addresses, encoded in LSB order. The
+type of DECnet Phase IV addresses is twelve (12).
+
+Netbios addresses
+
+Netbios addresses are 16-octet addresses typically composed of 1 to 15
+characters, trailing blank (ascii char 20) filled, with a 16th octet of
+0x0. The type of Netbios addresses is 20 (0x14).
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+8.2. KDC messages
+
+8.2.1. UDP/IP transport
+
+When contacting a Kerberos server (KDC) for a KRB_KDC_REQ request using UDP
+IP transport, the client shall send a UDP datagram containing only an
+encoding of the request to port 88 (decimal) at the KDC's IP address; the
+KDC will respond with a reply datagram containing only an encoding of the
+reply message (either a KRB_ERROR or a KRB_KDC_REP) to the sending port at
+the sender's IP address. Kerberos servers supporting IP transport must
+accept UDP requests on port 88 (decimal). The response to a request made
+through UDP/IP transport must also use UDP/IP transport.
+
+8.2.2. TCP/IP transport [Westerlund,Danielsson]
+
+Kerberos servers (KDC's) should accept TCP requests on port 88 (decimal)
+and clients should support the sending of TCP requests on port 88
+(decimal). When the KRB_KDC_REQ message is sent to the KDC over a TCP
+stream, a new connection will be established for each authentication
+exchange (request and response). The KRB_KDC_REP or KRB_ERROR message will
+be returned to the client on the same TCP stream that was established for
+the request. The response to a request made through TCP/IP transport must
+also use TCP/IP transport. Implementors should note that some extentions to
+the Kerberos protocol will not work if any implementation not supporting
+the TCP transport is involved (client or KDC). Implementors are strongly
+urged to support the TCP transport on both the client and server and are
+advised that the current notation of "should" support will likely change in
+the future to must support. The KDC may close the TCP stream after sending
+a response, but may leave the stream open if it expects a followup - in
+which case it may close the stream at any time if resource constratints or
+other factors make it desirable to do so. Care must be taken in managing
+TCP/IP connections with the KDC to prevent denial of service attacks based
+on the number of TCP/IP connections with the KDC that remain open. If
+multiple exchanges with the KDC are needed for certain forms of
+preauthentication, multiple TCP connections may be required. A client may
+close the stream after receiving response, and should close the stream if
+it does not expect to send followup messages. The client must be prepared
+to have the stream closed by the KDC at anytime, in which case it must
+simply connect again when it is ready to send subsequent messages.
+
+The first four octets of the TCP stream used to transmit the request
+request will encode in network byte order the length of the request
+(KRB_KDC_REQ), and the length will be followed by the request itself. The
+response will similarly be preceeded by a 4 octet encoding in network byte
+order of the length of the KRB_KDC_REP or the KRB_ERROR message and will be
+followed by the KRB_KDC_REP or the KRB_ERROR response. If the sign bit is
+set on integer represented by the first 4 octets, then the next 4 octets
+will be read, extending the length of the field by another 4 octets (less 1
+bit).
+
+8.2.3. OSI transport
+
+During authentication of an OSI client to an OSI server, the mutual
+authentication of an OSI server to an OSI client, the transfer of
+credentials from an OSI client to an OSI server, or during exchange of
+private or integrity checked messages, Kerberos protocol messages may be
+treated as opaque objects and the type of the authentication mechanism will
+be:
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+OBJECT IDENTIFIER ::= {iso (1), org(3), dod(6),internet(1),
+security(5),kerberosv5(2)}
+
+Depending on the situation, the opaque object will be an authentication
+header (KRB_AP_REQ), an authentication reply (KRB_AP_REP), a safe message
+(KRB_SAFE), a private message (KRB_PRIV), or a credentials message
+(KRB_CRED). The opaque data contains an application code as specified in
+the ASN.1 description for each message. The application code may be used by
+Kerberos to determine the message type.
+
+8.2.3. Name of the TGS
+
+The principal identifier of the ticket-granting service shall be composed
+of three parts: (1) the realm of the KDC issuing the TGS ticket (2) a
+two-part name of type NT-SRV-INST, with the first part "krbtgt" and the
+second part the name of the realm which will accept the ticket-granting
+ticket. For example, a ticket-granting ticket issued by the ATHENA.MIT.EDU
+realm to be used to get tickets from the ATHENA.MIT.EDU KDC has a principal
+identifier of "ATHENA.MIT.EDU" (realm), ("krbtgt", "ATHENA.MIT.EDU")
+(name). A ticket-granting ticket issued by the ATHENA.MIT.EDU realm to be
+used to get tickets from the MIT.EDU realm has a principal identifier of
+"ATHENA.MIT.EDU" (realm), ("krbtgt", "MIT.EDU") (name).
+
+8.3. Protocol constants and associated values
+
+The following tables list constants used in the protocol and defines their
+meanings. Ranges are specified in the "specification" section that limit
+the values of constants for which values are defined here. This allows
+implementations to make assumptions about the maximum values that will be
+received for these constants. Implementation receiving values outside the
+range specified in the "specification" section may reject the request, but
+they must recover cleanly.
+
+Encryption type etype value block size minimum pad size confounder
+size
+NULL 0 1 0 0
+des-cbc-crc 1 8 4 8
+des-cbc-md4 2 8 0 8
+des-cbc-md5 3 8 0 8
+ 4
+des3-cbc-md5 5 8 0 8
+ 6
+des3-cbc-sha1 7 8 0 8
+sign-dsa-generate 8 (pkinit)
+encrypt-rsa-priv 9 (pkinit)
+encrypt-rsa-pub 10 (pkinit)
+rsa-pub-md5 11 (pkinit)
+rsa-pub-sha1 12 (pkinit)
+des3kd-cbc-sha1 ?? 8 0 8
+ENCTYPE_PK_CROSS 48 (reserved for pkcross)
+ 0x8003
+
+Checksum type sumtype value checksum size
+CRC32 1 4
+rsa-md4 2 16
+rsa-md4-des 3 24
+des-mac 4 16
+des-mac-k 5 8
+rsa-md4-des-k 6 16
+rsa-md5 7 16
+rsa-md5-des 8 24
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+rsa-md5-des3 9 24
+hmac-sha1-des3 12 20 (I had this as 10, is it
+12)
+
+padata type padata-type value
+
+PA-TGS-REQ 1
+PA-ENC-TIMESTAMP 2
+PA-PW-SALT 3
+ 4
+PA-ENC-UNIX-TIME 5
+PA-SANDIA-SECUREID 6
+PA-SESAME 7
+PA-OSF-DCE 8
+PA-CYBERSAFE-SECUREID 9
+PA-AFS3-SALT 10
+PA-ETYPE-INFO 11
+SAM-CHALLENGE 12 (sam/otp)
+SAM-RESPONSE 13 (sam/otp)
+PA-PK-AS-REQ 14 (pkinit)
+PA-PK-AS-REP 15 (pkinit)
+PA-PK-AS-SIGN 16 (pkinit)
+PA-PK-KEY-REQ 17 (pkinit)
+PA-PK-KEY-REP 18 (pkinit)
+PA-USE-SPECIFIED-KVNO 20
+
+authorization data type ad-type value
+AD-KDC-ISSUED 1
+AD-INTENDED-FOR-SERVER 2
+AD-INTENDED-FOR-APPLICATION-CLASS 3
+AD-IF-RELEVANT 4
+AD-OR 5
+AD-MANDATORY-TICKET-EXTENSIONS 6
+AD-IN-TICKET-EXTENSIONS 7
+reserved values 8-63
+OSF-DCE 64
+SESAME 65
+
+Ticket Extension Types
+
+TE-TYPE-NULL 0 Null ticket extension
+TE-TYPE-EXTERNAL-ADATA 1 Integrity protected authorization data
+ 2 TE-TYPE-PKCROSS-KDC (I have reservations)
+TE-TYPE-PKCROSS-CLIENT 3 PKCROSS cross realm key ticket
+TE-TYPE-CYBERSAFE-EXT 4 Assigned to CyberSafe Corp
+ 5 TE-TYPE-DEST-HOST (I have reservations)
+
+alternate authentication type method-type value
+reserved values 0-63
+ATT-CHALLENGE-RESPONSE 64
+
+transited encoding type tr-type value
+DOMAIN-X500-COMPRESS 1
+reserved values all others
+
+Label Value Meaning or MIT code
+
+pvno 5 current Kerberos protocol version number
+
+message types
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+KRB_AS_REQ 10 Request for initial authentication
+KRB_AS_REP 11 Response to KRB_AS_REQ request
+KRB_TGS_REQ 12 Request for authentication based on TGT
+KRB_TGS_REP 13 Response to KRB_TGS_REQ request
+KRB_AP_REQ 14 application request to server
+KRB_AP_REP 15 Response to KRB_AP_REQ_MUTUAL
+KRB_SAFE 20 Safe (checksummed) application message
+KRB_PRIV 21 Private (encrypted) application message
+KRB_CRED 22 Private (encrypted) message to forward
+credentials
+KRB_ERROR 30 Error response
+
+name types
+
+KRB_NT_UNKNOWN 0 Name type not known
+KRB_NT_PRINCIPAL 1 Just the name of the principal as in DCE, or for
+users
+KRB_NT_SRV_INST 2 Service and other unique instance (krbtgt)
+KRB_NT_SRV_HST 3 Service with host name as instance (telnet,
+rcommands)
+KRB_NT_SRV_XHST 4 Service with host as remaining components
+KRB_NT_UID 5 Unique ID
+KRB_NT_X500_PRINCIPAL 6 Encoded X.509 Distingished name [RFC 2253]
+
+error codes
+
+KDC_ERR_NONE 0 No error
+KDC_ERR_NAME_EXP 1 Client's entry in database has expired
+KDC_ERR_SERVICE_EXP 2 Server's entry in database has expired
+KDC_ERR_BAD_PVNO 3 Requested protocol version number not
+supported
+KDC_ERR_C_OLD_MAST_KVNO 4 Client's key encrypted in old master key
+KDC_ERR_S_OLD_MAST_KVNO 5 Server's key encrypted in old master key
+KDC_ERR_C_PRINCIPAL_UNKNOWN 6 Client not found in Kerberos database
+KDC_ERR_S_PRINCIPAL_UNKNOWN 7 Server not found in Kerberos database
+KDC_ERR_PRINCIPAL_NOT_UNIQUE 8 Multiple principal entries in database
+KDC_ERR_NULL_KEY 9 The client or server has a null key
+KDC_ERR_CANNOT_POSTDATE 10 Ticket not eligible for postdating
+KDC_ERR_NEVER_VALID 11 Requested start time is later than end
+time
+KDC_ERR_POLICY 12 KDC policy rejects request
+KDC_ERR_BADOPTION 13 KDC cannot accommodate requested option
+KDC_ERR_ETYPE_NOSUPP 14 KDC has no support for encryption type
+KDC_ERR_SUMTYPE_NOSUPP 15 KDC has no support for checksum type
+KDC_ERR_PADATA_TYPE_NOSUPP 16 KDC has no support for padata type
+KDC_ERR_TRTYPE_NOSUPP 17 KDC has no support for transited type
+KDC_ERR_CLIENT_REVOKED 18 Clients credentials have been revoked
+KDC_ERR_SERVICE_REVOKED 19 Credentials for server have been revoked
+KDC_ERR_TGT_REVOKED 20 TGT has been revoked
+KDC_ERR_CLIENT_NOTYET 21 Client not yet valid - try again later
+KDC_ERR_SERVICE_NOTYET 22 Server not yet valid - try again later
+KDC_ERR_KEY_EXPIRED 23 Password has expired - change password
+to reset
+KDC_ERR_PREAUTH_FAILED 24 Pre-authentication information was
+invalid
+KDC_ERR_PREAUTH_REQUIRED 25 Additional pre-authenticationrequired
+[40]
+KDC_ERR_SERVER_NOMATCH 26 Requested server and ticket don't match
+KDC_ERR_MUST_USE_USER2USER 27 Server principal valid for user2user
+only
+KDC_ERR_PATH_NOT_ACCPETED 28 KDC Policy rejects transited path
+KRB_AP_ERR_BAD_INTEGRITY 31 Integrity check on decrypted field
+failed
+KRB_AP_ERR_TKT_EXPIRED 32 Ticket expired
+KRB_AP_ERR_TKT_NYV 33 Ticket not yet valid
+KRB_AP_ERR_REPEAT 34 Request is a replay
+KRB_AP_ERR_NOT_US 35 The ticket isn't for us
+KRB_AP_ERR_BADMATCH 36 Ticket and authenticator don't match
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+KRB_AP_ERR_SKEW 37 Clock skew too great
+KRB_AP_ERR_BADADDR 38 Incorrect net address
+KRB_AP_ERR_BADVERSION 39 Protocol version mismatch
+KRB_AP_ERR_MSG_TYPE 40 Invalid msg type
+KRB_AP_ERR_MODIFIED 41 Message stream modified
+KRB_AP_ERR_BADORDER 42 Message out of order
+KRB_AP_ERR_BADKEYVER 44 Specified version of key is not
+available
+KRB_AP_ERR_NOKEY 45 Service key not available
+KRB_AP_ERR_MUT_FAIL 46 Mutual authentication failed
+KRB_AP_ERR_BADDIRECTION 47 Incorrect message direction
+KRB_AP_ERR_METHOD 48 Alternative authentication method
+required
+KRB_AP_ERR_BADSEQ 49 Incorrect sequence number in message
+KRB_AP_ERR_INAPP_CKSUM 50 Inappropriate type of checksum in
+message
+KRB_AP_PATH_NOT_ACCEPTED 51 Policy rejects transited path
+KRB_ERR_RESPONSE_TOO_BIG 52 Response too big for UDP, retry with TCP
+KRB_ERR_GENERIC 60 Generic error (description in e-text)
+KRB_ERR_FIELD_TOOLONG 61 Field is too long for this
+implementation
+KDC_ERROR_CLIENT_NOT_TRUSTED 62 (pkinit)
+KDC_ERROR_KDC_NOT_TRUSTED 63 (pkinit)
+KDC_ERROR_INVALID_SIG 64 (pkinit)
+KDC_ERR_KEY_TOO_WEAK 65 (pkinit)
+KDC_ERR_CERTIFICATE_MISMATCH 66 (pkinit)
+
+9. Interoperability requirements
+
+Version 5 of the Kerberos protocol supports a myriad of options. Among
+these are multiple encryption and checksum types, alternative encoding
+schemes for the transited field, optional mechanisms for
+pre-authentication, the handling of tickets with no addresses, options for
+mutual authentication, user to user authentication, support for proxies,
+forwarding, postdating, and renewing tickets, the format of realm names,
+and the handling of authorization data.
+
+In order to ensure the interoperability of realms, it is necessary to
+define a minimal configuration which must be supported by all
+implementations. This minimal configuration is subject to change as
+technology does. For example, if at some later date it is discovered that
+one of the required encryption or checksum algorithms is not secure, it
+will be replaced.
+
+9.1. Specification 2
+
+This section defines the second specification of these options.
+Implementations which are configured in this way can be said to support
+Kerberos Version 5 Specification 2 (5.1). Specification 1 (depricated) may
+be found in RFC1510.
+
+Transport
+
+TCP/IP and UDP/IP transport must be supported by KDCs claiming conformance
+to specification 2. Kerberos clients claiming conformance to specification
+2 must support UDP/IP transport for messages with the KDC and should
+support TCP/IP transport.
+
+Encryption and checksum methods
+
+The following encryption and checksum mechanisms must be supported.
+Implementations may support other mechanisms as well, but the additional
+mechanisms may only be used when communicating with principals known to
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+also support them: This list is to be determined.
+
+Encryption: DES-CBC-MD5
+Checksums: CRC-32, DES-MAC, DES-MAC-K, and DES-MD5
+
+Realm Names
+
+All implementations must understand hierarchical realms in both the
+Internet Domain and the X.500 style. When a ticket granting ticket for an
+unknown realm is requested, the KDC must be able to determine the names of
+the intermediate realms between the KDCs realm and the requested realm.
+
+Transited field encoding
+
+DOMAIN-X500-COMPRESS (described in section 3.3.3.2) must be supported.
+Alternative encodings may be supported, but they may be used only when that
+encoding is supported by ALL intermediate realms.
+
+Pre-authentication methods
+
+The TGS-REQ method must be supported. The TGS-REQ method is not used on the
+initial request. The PA-ENC-TIMESTAMP method must be supported by clients
+but whether it is enabled by default may be determined on a realm by realm
+basis. If not used in the initial request and the error
+KDC_ERR_PREAUTH_REQUIRED is returned specifying PA-ENC-TIMESTAMP as an
+acceptable method, the client should retry the initial request using the
+PA-ENC-TIMESTAMP preauthentication method. Servers need not support the
+PA-ENC-TIMESTAMP method, but if not supported the server should ignore the
+presence of PA-ENC-TIMESTAMP pre-authentication in a request.
+
+Mutual authentication
+
+Mutual authentication (via the KRB_AP_REP message) must be supported.
+
+Ticket addresses and flags
+
+All KDC's must pass on tickets that carry no addresses (i.e. if a TGT
+contains no addresses, the KDC will return derivative tickets), but each
+realm may set its own policy for issuing such tickets, and each application
+server will set its own policy with respect to accepting them.
+
+Proxies and forwarded tickets must be supported. Individual realms and
+application servers can set their own policy on when such tickets will be
+accepted.
+
+All implementations must recognize renewable and postdated tickets, but
+need not actually implement them. If these options are not supported, the
+starttime and endtime in the ticket shall specify a ticket's entire useful
+life. When a postdated ticket is decoded by a server, all implementations
+shall make the presence of the postdated flag visible to the calling
+server.
+
+User-to-user authentication
+
+Support for user to user authentication (via the ENC-TKT-IN-SKEY KDC
+option) must be provided by implementations, but individual realms may
+decide as a matter of policy to reject such requests on a per-principal or
+realm-wide basis.
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+Authorization data
+
+Implementations must pass all authorization data subfields from
+ticket-granting tickets to any derivative tickets unless directed to
+suppress a subfield as part of the definition of that registered subfield
+type (it is never incorrect to pass on a subfield, and no registered
+subfield types presently specify suppression at the KDC).
+
+Implementations must make the contents of any authorization data subfields
+available to the server when a ticket is used. Implementations are not
+required to allow clients to specify the contents of the authorization data
+fields.
+
+Constant ranges
+
+All protocol constants are constrained to 32 bit (signed) values unless
+further constrained by the protocol definition. This limit is provided to
+allow implementations to make assumptions about the maximum values that
+will be received for these constants. Implementation receiving values
+outside this range may reject the request, but they must recover cleanly.
+
+9.2. Recommended KDC values
+
+Following is a list of recommended values for a KDC implementation, based
+on the list of suggested configuration constants (see section 4.4).
+
+minimum lifetime 5 minutes
+maximum renewable lifetime 1 week
+maximum ticket lifetime 1 day
+empty addresses only when suitable restrictions appear
+ in authorization data
+proxiable, etc. Allowed.
+
+10. REFERENCES
+
+[NT94] B. Clifford Neuman and Theodore Y. Ts'o, "An Authenti-
+ cation Service for Computer Networks," IEEE Communica-
+ tions Magazine, Vol. 32(9), pp. 33-38 (September 1994).
+
+[MNSS87] S. P. Miller, B. C. Neuman, J. I. Schiller, and J. H.
+ Saltzer, Section E.2.1: Kerberos Authentication and
+ Authorization System, M.I.T. Project Athena, Cambridge,
+ Massachusetts (December 21, 1987).
+
+[SNS88] J. G. Steiner, B. C. Neuman, and J. I. Schiller, "Ker-
+ beros: An Authentication Service for Open Network Sys-
+ tems," pp. 191-202 in Usenix Conference Proceedings,
+ Dallas, Texas (February, 1988).
+
+[NS78] Roger M. Needham and Michael D. Schroeder, "Using
+ Encryption for Authentication in Large Networks of Com-
+ puters," Communications of the ACM, Vol. 21(12),
+ pp. 993-999 (December, 1978).
+
+[DS81] Dorothy E. Denning and Giovanni Maria Sacco, "Time-
+ stamps in Key Distribution Protocols," Communications
+ of the ACM, Vol. 24(8), pp. 533-536 (August 1981).
+
+[KNT92] John T. Kohl, B. Clifford Neuman, and Theodore Y. Ts'o,
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ "The Evolution of the Kerberos Authentication Service,"
+ in an IEEE Computer Society Text soon to be published
+ (June 1992).
+
+[Neu93] B. Clifford Neuman, "Proxy-Based Authorization and
+ Accounting for Distributed Systems," in Proceedings of
+ the 13th International Conference on Distributed Com-
+ puting Systems, Pittsburgh, PA (May, 1993).
+
+[DS90] Don Davis and Ralph Swick, "Workstation Services and
+ Kerberos Authentication at Project Athena," Technical
+ Memorandum TM-424, MIT Laboratory for Computer Science
+ (February 1990).
+
+[LGDSR87] P. J. Levine, M. R. Gretzinger, J. M. Diaz, W. E. Som-
+ merfeld, and K. Raeburn, Section E.1: Service Manage-
+ ment System, M.I.T. Project Athena, Cambridge, Mas-
+ sachusetts (1987).
+
+[X509-88] CCITT, Recommendation X.509: The Directory Authentica-
+ tion Framework, December 1988.
+
+[Pat92]. J. Pato, Using Pre-Authentication to Avoid Password
+ Guessing Attacks, Open Software Foundation DCE Request
+ for Comments 26 (December 1992).
+
+[DES77] National Bureau of Standards, U.S. Department of Com-
+ merce, "Data Encryption Standard," Federal Information
+ Processing Standards Publication 46, Washington, DC
+ (1977).
+
+[DESM80] National Bureau of Standards, U.S. Department of Com-
+ merce, "DES Modes of Operation," Federal Information
+ Processing Standards Publication 81, Springfield, VA
+ (December 1980).
+
+[SG92] Stuart G. Stubblebine and Virgil D. Gligor, "On Message
+ Integrity in Cryptographic Protocols," in Proceedings
+ of the IEEE Symposium on Research in Security and
+ Privacy, Oakland, California (May 1992).
+
+[IS3309] International Organization for Standardization, "ISO
+ Information Processing Systems - Data Communication -
+ High-Level Data Link Control Procedure - Frame Struc-
+ ture," IS 3309 (October 1984). 3rd Edition.
+
+[MD4-92] R. Rivest, "The MD4 Message Digest Algorithm," RFC
+ 1320, MIT Laboratory for Computer Science (April
+ 1992).
+
+[MD5-92] R. Rivest, "The MD5 Message Digest Algorithm," RFC
+ 1321, MIT Laboratory for Computer Science (April
+ 1992).
+
+[KBC96] H. Krawczyk, M. Bellare, and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication," Working Draft
+ draft-ietf-ipsec-hmac-md5-01.txt, (August 1996).
+
+[Horowitz96] Horowitz, M., "Key Derivation for Authentication,
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ Integrity, and Privacy", draft-horowitz-key-derivation-02.txt,
+ August 1998.
+
+[HorowitzB96] Horowitz, M., "Key Derivation for Kerberos V5", draft-
+ horowitz-kerb-key-derivation-01.txt, September 1998.
+
+[Krawczyk96] Krawczyk, H., Bellare, and M., Canetti, R., "HMAC:
+ Keyed-Hashing for Message Authentication", draft-ietf-ipsec-hmac-
+ md5-01.txt, August, 1996.
+
+A. Pseudo-code for protocol processing
+
+This appendix provides pseudo-code describing how the messages are to be
+constructed and interpreted by clients and servers.
+
+A.1. KRB_AS_REQ generation
+
+ request.pvno := protocol version; /* pvno = 5 */
+ request.msg-type := message type; /* type = KRB_AS_REQ */
+
+ if(pa_enc_timestamp_required) then
+ request.padata.padata-type = PA-ENC-TIMESTAMP;
+ get system_time;
+ padata-body.patimestamp,pausec = system_time;
+ encrypt padata-body into request.padata.padata-value
+ using client.key; /* derived from password */
+ endif
+
+ body.kdc-options := users's preferences;
+ body.cname := user's name;
+ body.realm := user's realm;
+ body.sname := service's name; /* usually "krbtgt", "localrealm" */
+ if (body.kdc-options.POSTDATED is set) then
+ body.from := requested starting time;
+ else
+ omit body.from;
+ endif
+ body.till := requested end time;
+ if (body.kdc-options.RENEWABLE is set) then
+ body.rtime := requested final renewal time;
+ endif
+ body.nonce := random_nonce();
+ body.etype := requested etypes;
+ if (user supplied addresses) then
+ body.addresses := user's addresses;
+ else
+ omit body.addresses;
+ endif
+ omit body.enc-authorization-data;
+ request.req-body := body;
+
+ kerberos := lookup(name of local kerberos server (or servers));
+ send(packet,kerberos);
+
+ wait(for response);
+ if (timed_out) then
+ retry or use alternate server;
+ endif
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+A.2. KRB_AS_REQ verification and KRB_AS_REP generation
+
+ decode message into req;
+
+ client := lookup(req.cname,req.realm);
+ server := lookup(req.sname,req.realm);
+
+ get system_time;
+ kdc_time := system_time.seconds;
+
+ if (!client) then
+ /* no client in Database */
+ error_out(KDC_ERR_C_PRINCIPAL_UNKNOWN);
+ endif
+ if (!server) then
+ /* no server in Database */
+ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
+ endif
+
+ if(client.pa_enc_timestamp_required and
+ pa_enc_timestamp not present) then
+ error_out(KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP));
+ endif
+
+ if(pa_enc_timestamp present) then
+ decrypt req.padata-value into decrypted_enc_timestamp
+ using client.key;
+ using auth_hdr.authenticator.subkey;
+ if (decrypt_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ if(decrypted_enc_timestamp is not within allowable skew)
+then
+ error_out(KDC_ERR_PREAUTH_FAILED);
+ endif
+ if(decrypted_enc_timestamp and usec is replay)
+ error_out(KDC_ERR_PREAUTH_FAILED);
+ endif
+ add decrypted_enc_timestamp and usec to replay cache;
+ endif
+
+ use_etype := first supported etype in req.etypes;
+
+ if (no support for req.etypes) then
+ error_out(KDC_ERR_ETYPE_NOSUPP);
+ endif
+
+ new_tkt.vno := ticket version; /* = 5 */
+ new_tkt.sname := req.sname;
+ new_tkt.srealm := req.srealm;
+ reset all flags in new_tkt.flags;
+
+ /* It should be noted that local policy may affect the */
+ /* processing of any of these flags. For example, some */
+ /* realms may refuse to issue renewable tickets */
+
+ if (req.kdc-options.FORWARDABLE is set) then
+ set new_tkt.flags.FORWARDABLE;
+ endif
+ if (req.kdc-options.PROXIABLE is set) then
+ set new_tkt.flags.PROXIABLE;
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ endif
+
+ if (req.kdc-options.ALLOW-POSTDATE is set) then
+ set new_tkt.flags.MAY-POSTDATE;
+ endif
+ if ((req.kdc-options.RENEW is set) or
+ (req.kdc-options.VALIDATE is set) or
+ (req.kdc-options.PROXY is set) or
+ (req.kdc-options.FORWARDED is set) or
+ (req.kdc-options.ENC-TKT-IN-SKEY is set)) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+ new_tkt.session := random_session_key();
+ new_tkt.cname := req.cname;
+ new_tkt.crealm := req.crealm;
+ new_tkt.transited := empty_transited_field();
+
+ new_tkt.authtime := kdc_time;
+
+ if (req.kdc-options.POSTDATED is set) then
+ if (against_postdate_policy(req.from)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ set new_tkt.flags.POSTDATED;
+ set new_tkt.flags.INVALID;
+ new_tkt.starttime := req.from;
+ else
+ omit new_tkt.starttime; /* treated as authtime when omitted */
+ endif
+ if (req.till = 0) then
+ till := infinity;
+ else
+ till := req.till;
+ endif
+
+ new_tkt.endtime := min(till,
+ new_tkt.starttime+client.max_life,
+ new_tkt.starttime+server.max_life,
+ new_tkt.starttime+max_life_for_realm);
+
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (new_tkt.endtime < req.till)) then
+ /* we set the RENEWABLE option for later processing */
+ set req.kdc-options.RENEWABLE;
+ req.rtime := req.till;
+ endif
+
+ if (req.rtime = 0) then
+ rtime := infinity;
+ else
+ rtime := req.rtime;
+ endif
+
+ if (req.kdc-options.RENEWABLE is set) then
+ set new_tkt.flags.RENEWABLE;
+ new_tkt.renew-till := min(rtime,
+
+new_tkt.starttime+client.max_rlife,
+
+new_tkt.starttime+server.max_rlife,
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+new_tkt.starttime+max_rlife_for_realm);
+ else
+ omit new_tkt.renew-till; /* only present if RENEWABLE */
+ endif
+
+ if (req.addresses) then
+ new_tkt.caddr := req.addresses;
+ else
+ omit new_tkt.caddr;
+ endif
+
+ new_tkt.authorization_data := empty_authorization_data();
+
+ encode to-be-encrypted part of ticket into OCTET STRING;
+ new_tkt.enc-part := encrypt OCTET STRING
+ using etype_for_key(server.key), server.key, server.p_kvno;
+
+ /* Start processing the response */
+
+ resp.pvno := 5;
+ resp.msg-type := KRB_AS_REP;
+ resp.cname := req.cname;
+ resp.crealm := req.realm;
+ resp.ticket := new_tkt;
+
+ resp.key := new_tkt.session;
+ resp.last-req := fetch_last_request_info(client);
+ resp.nonce := req.nonce;
+ resp.key-expiration := client.expiration;
+ resp.flags := new_tkt.flags;
+
+ resp.authtime := new_tkt.authtime;
+ resp.starttime := new_tkt.starttime;
+ resp.endtime := new_tkt.endtime;
+
+ if (new_tkt.flags.RENEWABLE) then
+ resp.renew-till := new_tkt.renew-till;
+ endif
+
+ resp.realm := new_tkt.realm;
+ resp.sname := new_tkt.sname;
+
+ resp.caddr := new_tkt.caddr;
+
+ encode body of reply into OCTET STRING;
+
+ resp.enc-part := encrypt OCTET STRING
+ using use_etype, client.key, client.p_kvno;
+ send(resp);
+
+A.3. KRB_AS_REP verification
+
+ decode response into resp;
+
+ if (resp.msg-type = KRB_ERROR) then
+ if(error = KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP)) then
+ set pa_enc_timestamp_required;
+ goto KRB_AS_REQ;
+ endif
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ process_error(resp);
+ return;
+ endif
+
+ /* On error, discard the response, and zero the session key */
+ /* from the response immediately */
+
+ key = get_decryption_key(resp.enc-part.kvno, resp.enc-part.etype,
+ resp.padata);
+ unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and key;
+ zero(key);
+
+ if (common_as_rep_tgs_rep_checks fail) then
+ destroy resp.key;
+ return error;
+ endif
+
+ if near(resp.princ_exp) then
+ print(warning message);
+ endif
+ save_for_later(ticket,session,client,server,times,flags);
+
+A.4. KRB_AS_REP and KRB_TGS_REP common checks
+
+ if (decryption_error() or
+ (req.cname != resp.cname) or
+ (req.realm != resp.crealm) or
+ (req.sname != resp.sname) or
+ (req.realm != resp.realm) or
+ (req.nonce != resp.nonce) or
+ (req.addresses != resp.caddr)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ /* make sure no flags are set that shouldn't be, and that all that
+*/
+ /* should be are set
+*/
+ if (!check_flags_for_compatability(req.kdc-options,resp.flags)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ if ((req.from = 0) and
+ (resp.starttime is not within allowable skew)) then
+ destroy resp.key;
+ return KRB_AP_ERR_SKEW;
+ endif
+ if ((req.from != 0) and (req.from != resp.starttime)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+ if ((req.till != 0) and (resp.endtime > req.till)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ if ((req.kdc-options.RENEWABLE is set) and
+ (req.rtime != 0) and (resp.renew-till > req.rtime)) then
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (resp.flags.RENEWABLE) and
+ (req.till != 0) and
+ (resp.renew-till > req.till)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+A.5. KRB_TGS_REQ generation
+
+ /* Note that make_application_request might have to recursivly
+*/
+ /* call this routine to get the appropriate ticket-granting ticket
+*/
+
+ request.pvno := protocol version; /* pvno = 5 */
+ request.msg-type := message type; /* type = KRB_TGS_REQ */
+
+ body.kdc-options := users's preferences;
+ /* If the TGT is not for the realm of the end-server */
+ /* then the sname will be for a TGT for the end-realm */
+ /* and the realm of the requested ticket (body.realm) */
+ /* will be that of the TGS to which the TGT we are */
+ /* sending applies */
+ body.sname := service's name;
+ body.realm := service's realm;
+
+ if (body.kdc-options.POSTDATED is set) then
+ body.from := requested starting time;
+ else
+ omit body.from;
+ endif
+ body.till := requested end time;
+ if (body.kdc-options.RENEWABLE is set) then
+ body.rtime := requested final renewal time;
+ endif
+ body.nonce := random_nonce();
+ body.etype := requested etypes;
+ if (user supplied addresses) then
+ body.addresses := user's addresses;
+ else
+ omit body.addresses;
+ endif
+
+ body.enc-authorization-data := user-supplied data;
+ if (body.kdc-options.ENC-TKT-IN-SKEY) then
+ body.additional-tickets_ticket := second TGT;
+ endif
+
+ request.req-body := body;
+ check := generate_checksum (req.body,checksumtype);
+
+ request.padata[0].padata-type := PA-TGS-REQ;
+ request.padata[0].padata-value := create a KRB_AP_REQ using
+ the TGT and checksum
+
+ /* add in any other padata as required/supplied */
+ kerberos := lookup(name of local kerberose server (or servers));
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ send(packet,kerberos);
+
+ wait(for response);
+ if (timed_out) then
+ retry or use alternate server;
+ endif
+
+A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation
+
+ /* note that reading the application request requires first
+ determining the server for which a ticket was issued, and choosing
+the
+ correct key for decryption. The name of the server appears in the
+ plaintext part of the ticket. */
+
+ if (no KRB_AP_REQ in req.padata) then
+ error_out(KDC_ERR_PADATA_TYPE_NOSUPP);
+ endif
+ verify KRB_AP_REQ in req.padata;
+
+ /* Note that the realm in which the Kerberos server is operating is
+ determined by the instance from the ticket-granting ticket. The
+realm
+ in the ticket-granting ticket is the realm under which the ticket
+ granting ticket was issued. It is possible for a single Kerberos
+ server to support more than one realm. */
+
+ auth_hdr := KRB_AP_REQ;
+ tgt := auth_hdr.ticket;
+
+ if (tgt.sname is not a TGT for local realm and is not req.sname)
+then
+ error_out(KRB_AP_ERR_NOT_US);
+
+ realm := realm_tgt_is_for(tgt);
+
+ decode remainder of request;
+
+ if (auth_hdr.authenticator.cksum is missing) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+
+ if (auth_hdr.authenticator.cksum type is not supported) then
+ error_out(KDC_ERR_SUMTYPE_NOSUPP);
+ endif
+ if (auth_hdr.authenticator.cksum is not both collision-proof and
+keyed) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+
+ set computed_checksum := checksum(req);
+ if (computed_checksum != auth_hdr.authenticatory.cksum) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ server := lookup(req.sname,realm);
+
+ if (!server) then
+ if (is_foreign_tgt_name(req.sname)) then
+ server := best_intermediate_tgs(req.sname);
+ else
+ /* no server in Database */
+ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ endif
+ endif
+
+ session := generate_random_session_key();
+
+ use_etype := first supported etype in req.etypes;
+
+ if (no support for req.etypes) then
+ error_out(KDC_ERR_ETYPE_NOSUPP);
+ endif
+
+ new_tkt.vno := ticket version; /* = 5 */
+ new_tkt.sname := req.sname;
+ new_tkt.srealm := realm;
+ reset all flags in new_tkt.flags;
+
+ /* It should be noted that local policy may affect the */
+ /* processing of any of these flags. For example, some */
+ /* realms may refuse to issue renewable tickets */
+
+ new_tkt.caddr := tgt.caddr;
+ resp.caddr := NULL; /* We only include this if they change */
+ if (req.kdc-options.FORWARDABLE is set) then
+ if (tgt.flags.FORWARDABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.FORWARDABLE;
+ endif
+ if (req.kdc-options.FORWARDED is set) then
+ if (tgt.flags.FORWARDABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.FORWARDED;
+ new_tkt.caddr := req.addresses;
+ resp.caddr := req.addresses;
+ endif
+ if (tgt.flags.FORWARDED is set) then
+ set new_tkt.flags.FORWARDED;
+ endif
+
+ if (req.kdc-options.PROXIABLE is set) then
+ if (tgt.flags.PROXIABLE is reset)
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.PROXIABLE;
+ endif
+ if (req.kdc-options.PROXY is set) then
+ if (tgt.flags.PROXIABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.PROXY;
+ new_tkt.caddr := req.addresses;
+ resp.caddr := req.addresses;
+ endif
+
+ if (req.kdc-options.ALLOW-POSTDATE is set) then
+ if (tgt.flags.MAY-POSTDATE is reset)
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ set new_tkt.flags.MAY-POSTDATE;
+ endif
+ if (req.kdc-options.POSTDATED is set) then
+ if (tgt.flags.MAY-POSTDATE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.POSTDATED;
+ set new_tkt.flags.INVALID;
+ if (against_postdate_policy(req.from)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ new_tkt.starttime := req.from;
+ endif
+
+ if (req.kdc-options.VALIDATE is set) then
+ if (tgt.flags.INVALID is reset) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ if (tgt.starttime > kdc_time) then
+ error_out(KRB_AP_ERR_NYV);
+ endif
+ if (check_hot_list(tgt)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ tkt := tgt;
+ reset new_tkt.flags.INVALID;
+ endif
+
+ if (req.kdc-options.(any flag except ENC-TKT-IN-SKEY, RENEW,
+ and those already processed) is set) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+ new_tkt.authtime := tgt.authtime;
+
+ if (req.kdc-options.RENEW is set) then
+ /* Note that if the endtime has already passed, the ticket would
+*/
+ /* have been rejected in the initial authentication stage, so
+*/
+ /* there is no need to check again here
+*/
+ if (tgt.flags.RENEWABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ if (tgt.renew-till < kdc_time) then
+ error_out(KRB_AP_ERR_TKT_EXPIRED);
+ endif
+ tkt := tgt;
+ new_tkt.starttime := kdc_time;
+ old_life := tgt.endttime - tgt.starttime;
+ new_tkt.endtime := min(tgt.renew-till,
+ new_tkt.starttime + old_life);
+ else
+ new_tkt.starttime := kdc_time;
+ if (req.till = 0) then
+ till := infinity;
+ else
+ till := req.till;
+ endif
+
+ new_tkt.endtime := min(till,
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ new_tkt.starttime+client.max_life,
+ new_tkt.starttime+server.max_life,
+ new_tkt.starttime+max_life_for_realm,
+ tgt.endtime);
+
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (new_tkt.endtime < req.till) and
+ (tgt.flags.RENEWABLE is set) then
+ /* we set the RENEWABLE option for later processing
+*/
+ set req.kdc-options.RENEWABLE;
+ req.rtime := min(req.till, tgt.renew-till);
+ endif
+ endif
+
+ if (req.rtime = 0) then
+ rtime := infinity;
+ else
+ rtime := req.rtime;
+ endif
+
+ if ((req.kdc-options.RENEWABLE is set) and
+ (tgt.flags.RENEWABLE is set)) then
+ set new_tkt.flags.RENEWABLE;
+ new_tkt.renew-till := min(rtime,
+
+new_tkt.starttime+client.max_rlife,
+
+new_tkt.starttime+server.max_rlife,
+
+new_tkt.starttime+max_rlife_for_realm,
+ tgt.renew-till);
+ else
+ new_tkt.renew-till := OMIT; /* leave the renew-till field
+out */
+ endif
+ if (req.enc-authorization-data is present) then
+ decrypt req.enc-authorization-data into
+decrypted_authorization_data
+ using auth_hdr.authenticator.subkey;
+ if (decrypt_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ endif
+ new_tkt.authorization_data := req.auth_hdr.ticket.authorization_data
++
+ decrypted_authorization_data;
+
+ new_tkt.key := session;
+ new_tkt.crealm := tgt.crealm;
+ new_tkt.cname := req.auth_hdr.ticket.cname;
+
+ if (realm_tgt_is_for(tgt) := tgt.realm) then
+ /* tgt issued by local realm */
+ new_tkt.transited := tgt.transited;
+ else
+ /* was issued for this realm by some other realm */
+ if (tgt.transited.tr-type not supported) then
+ error_out(KDC_ERR_TRTYPE_NOSUPP);
+ endif
+ new_tkt.transited := compress_transited(tgt.transited +
+tgt.realm)
+ /* Don't check tranited field if TGT for foreign realm,
+ * or requested not to check */
+ if (is_not_foreign_tgt_name(new_tkt.server)
+ && req.kdc-options.DISABLE-TRANSITED-CHECK not set) then
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ /* Check it, so end-server does not have to
+ * but don't fail, end-server may still accept it */
+ if (check_transited_field(new_tkt.transited) == OK)
+ set new_tkt.flags.TRANSITED-POLICY-CHECKED;
+ endif
+ endif
+ endif
+
+ encode encrypted part of new_tkt into OCTET STRING;
+ if (req.kdc-options.ENC-TKT-IN-SKEY is set) then
+ if (server not specified) then
+ server = req.second_ticket.client;
+ endif
+ if ((req.second_ticket is not a TGT) or
+ (req.second_ticket.client != server)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+
+ new_tkt.enc-part := encrypt OCTET STRING using
+ using etype_for_key(second-ticket.key),
+second-ticket.key;
+ else
+ new_tkt.enc-part := encrypt OCTET STRING
+ using etype_for_key(server.key), server.key,
+server.p_kvno;
+ endif
+
+ resp.pvno := 5;
+ resp.msg-type := KRB_TGS_REP;
+ resp.crealm := tgt.crealm;
+ resp.cname := tgt.cname;
+ resp.ticket := new_tkt;
+
+ resp.key := session;
+ resp.nonce := req.nonce;
+ resp.last-req := fetch_last_request_info(client);
+ resp.flags := new_tkt.flags;
+
+ resp.authtime := new_tkt.authtime;
+ resp.starttime := new_tkt.starttime;
+ resp.endtime := new_tkt.endtime;
+
+ omit resp.key-expiration;
+
+ resp.sname := new_tkt.sname;
+ resp.realm := new_tkt.realm;
+
+ if (new_tkt.flags.RENEWABLE) then
+ resp.renew-till := new_tkt.renew-till;
+ endif
+
+ encode body of reply into OCTET STRING;
+
+ if (req.padata.authenticator.subkey)
+ resp.enc-part := encrypt OCTET STRING using use_etype,
+ req.padata.authenticator.subkey;
+ else resp.enc-part := encrypt OCTET STRING using use_etype, tgt.key;
+
+ send(resp);
+
+A.7. KRB_TGS_REP verification
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+ decode response into resp;
+
+ if (resp.msg-type = KRB_ERROR) then
+ process_error(resp);
+ return;
+ endif
+
+ /* On error, discard the response, and zero the session key from
+ the response immediately */
+
+ if (req.padata.authenticator.subkey)
+ unencrypted part of resp := decode of decrypt of
+resp.enc-part
+ using resp.enc-part.etype and subkey;
+ else unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and tgt's session
+key;
+ if (common_as_rep_tgs_rep_checks fail) then
+ destroy resp.key;
+ return error;
+ endif
+
+ check authorization_data as necessary;
+ save_for_later(ticket,session,client,server,times,flags);
+
+A.8. Authenticator generation
+
+ body.authenticator-vno := authenticator vno; /* = 5 */
+ body.cname, body.crealm := client name;
+ if (supplying checksum) then
+ body.cksum := checksum;
+ endif
+ get system_time;
+ body.ctime, body.cusec := system_time;
+ if (selecting sub-session key) then
+ select sub-session key;
+ body.subkey := sub-session key;
+ endif
+ if (using sequence numbers) then
+ select initial sequence number;
+ body.seq-number := initial sequence;
+ endif
+
+A.9. KRB_AP_REQ generation
+
+ obtain ticket and session_key from cache;
+
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_AP_REQ */
+
+ if (desired(MUTUAL_AUTHENTICATION)) then
+ set packet.ap-options.MUTUAL-REQUIRED;
+ else
+ reset packet.ap-options.MUTUAL-REQUIRED;
+ endif
+ if (using session key for ticket) then
+ set packet.ap-options.USE-SESSION-KEY;
+ else
+ reset packet.ap-options.USE-SESSION-KEY;
+ endif
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+ packet.ticket := ticket; /* ticket */
+ generate authenticator;
+ encode authenticator into OCTET STRING;
+ encrypt OCTET STRING into packet.authenticator using session_key;
+
+A.10. KRB_AP_REQ verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_AP_REQ) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ if (packet.ticket.tkt_vno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.ap_options.USE-SESSION-KEY is set) then
+ retrieve session key from ticket-granting ticket for
+ packet.ticket.{sname,srealm,enc-part.etype};
+ else
+ retrieve service key for
+ packet.ticket.{sname,srealm,enc-part.etype,enc-part.skvno};
+ endif
+ if (no_key_available) then
+ if (cannot_find_specified_skvno) then
+ error_out(KRB_AP_ERR_BADKEYVER);
+ else
+ error_out(KRB_AP_ERR_NOKEY);
+ endif
+ endif
+ decrypt packet.ticket.enc-part into decr_ticket using retrieved key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ decrypt packet.authenticator into decr_authenticator
+ using decr_ticket.key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if (decr_authenticator.{cname,crealm} !=
+ decr_ticket.{cname,crealm}) then
+ error_out(KRB_AP_ERR_BADMATCH);
+ endif
+ if (decr_ticket.caddr is present) then
+ if (sender_address(packet) is not in decr_ticket.caddr) then
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ elseif (application requires addresses) then
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (not in_clock_skew(decr_authenticator.ctime,
+ decr_authenticator.cusec)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(decr_authenticator.{ctime,cusec,cname,crealm})) then
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ save_identifier(decr_authenticator.{ctime,cusec,cname,crealm});
+ get system_time;
+ if ((decr_ticket.starttime-system_time > CLOCK_SKEW) or
+ (decr_ticket.flags.INVALID is set)) then
+ /* it hasn't yet become valid */
+ error_out(KRB_AP_ERR_TKT_NYV);
+ endif
+ if (system_time-decr_ticket.endtime > CLOCK_SKEW) then
+ error_out(KRB_AP_ERR_TKT_EXPIRED);
+ endif
+ if (decr_ticket.transited) then
+ /* caller may ignore the TRANSITED-POLICY-CHECKED and do
+ * check anyway */
+ if (decr_ticket.flags.TRANSITED-POLICY-CHECKED not set) then
+ if (check_transited_field(decr_ticket.transited) then
+ error_out(KDC_AP_PATH_NOT_ACCPETED);
+ endif
+ endif
+ endif
+ /* caller must check decr_ticket.flags for any pertinent details */
+ return(OK, decr_ticket, packet.ap_options.MUTUAL-REQUIRED);
+
+A.11. KRB_AP_REP generation
+
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_AP_REP */
+
+ body.ctime := packet.ctime;
+ body.cusec := packet.cusec;
+ if (selecting sub-session key) then
+ select sub-session key;
+ body.subkey := sub-session key;
+ endif
+ if (using sequence numbers) then
+ select initial sequence number;
+ body.seq-number := initial sequence;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part;
+
+A.12. KRB_AP_REP verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_AP_REP) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ cleartext := decrypt(packet.enc-part) using ticket's session key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ if (cleartext.ctime != authenticator.ctime) then
+ error_out(KRB_AP_ERR_MUT_FAIL);
+ endif
+ if (cleartext.cusec != authenticator.cusec) then
+ error_out(KRB_AP_ERR_MUT_FAIL);
+ endif
+ if (cleartext.subkey is present) then
+ save cleartext.subkey for future use;
+ endif
+ if (cleartext.seq-number is present) then
+ save cleartext.seq-number for future verifications;
+ endif
+ return(AUTHENTICATION_SUCCEEDED);
+
+A.13. KRB_SAFE generation
+
+ collect user data in buffer;
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_SAFE */
+
+ body.user-data := buffer; /* DATA */
+ if (using timestamp) then
+ get system_time;
+ body.timestamp, body.usec := system_time;
+ endif
+ if (using sequence numbers) then
+ body.seq-number := sequence number;
+ endif
+ body.s-address := sender host addresses;
+ if (only one recipient) then
+ body.r-address := recipient host address;
+ endif
+ checksum.cksumtype := checksum type;
+ compute checksum over body;
+ checksum.checksum := checksum value; /* checksum.checksum */
+ packet.cksum := checksum;
+ packet.safe-body := body;
+
+A.14. KRB_SAFE verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_SAFE) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ if (packet.checksum.cksumtype is not both collision-proof and keyed)
+then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+ if (safe_priv_common_checks_ok(packet)) then
+ set computed_checksum := checksum(packet.body);
+ if (computed_checksum != packet.checksum) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+ return (packet, PACKET_IS_GENUINE);
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ else
+ return common_checks_error;
+ endif
+
+A.15. KRB_SAFE and KRB_PRIV common checks
+
+ if (packet.s-address != O/S_sender(packet)) then
+ /* O/S report of sender not who claims to have sent it */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if ((packet.r-address is present) and
+ (packet.r-address != local_host_address)) then
+ /* was not sent to proper place */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (((packet.timestamp is present) and
+ (not in_clock_skew(packet.timestamp,packet.usec))) or
+ (packet.timestamp is not present and timestamp expected)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(packet.timestamp,packet.usec,packet.s-address)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+
+ if (((packet.seq-number is present) and
+ ((not in_sequence(packet.seq-number)))) or
+ (packet.seq-number is not present and sequence expected)) then
+ error_out(KRB_AP_ERR_BADORDER);
+ endif
+ if (packet.timestamp not present and packet.seq-number not present)
+then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ save_identifier(packet.{timestamp,usec,s-address},
+ sender_principal(packet));
+
+ return PACKET_IS_OK;
+
+A.16. KRB_PRIV generation
+
+ collect user data in buffer;
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_PRIV */
+
+ packet.enc-part.etype := encryption type;
+
+ body.user-data := buffer;
+ if (using timestamp) then
+ get system_time;
+ body.timestamp, body.usec := system_time;
+ endif
+ if (using sequence numbers) then
+ body.seq-number := sequence number;
+ endif
+ body.s-address := sender host addresses;
+ if (only one recipient) then
+ body.r-address := recipient host address;
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part.cipher;
+
+A.17. KRB_PRIV verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_PRIV) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+
+ cleartext := decrypt(packet.enc-part) using negotiated key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+
+ if (safe_priv_common_checks_ok(cleartext)) then
+ return(cleartext.DATA, PACKET_IS_GENUINE_AND_UNMODIFIED);
+ else
+ return common_checks_error;
+ endif
+
+A.18. KRB_CRED generation
+
+ invoke KRB_TGS; /* obtain tickets to be provided to peer */
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_CRED */
+
+ for (tickets[n] in tickets to be forwarded) do
+ packet.tickets[n] = tickets[n].ticket;
+ done
+
+ packet.enc-part.etype := encryption type;
+
+ for (ticket[n] in tickets to be forwarded) do
+ body.ticket-info[n].key = tickets[n].session;
+ body.ticket-info[n].prealm = tickets[n].crealm;
+ body.ticket-info[n].pname = tickets[n].cname;
+ body.ticket-info[n].flags = tickets[n].flags;
+ body.ticket-info[n].authtime = tickets[n].authtime;
+ body.ticket-info[n].starttime = tickets[n].starttime;
+ body.ticket-info[n].endtime = tickets[n].endtime;
+ body.ticket-info[n].renew-till = tickets[n].renew-till;
+ body.ticket-info[n].srealm = tickets[n].srealm;
+ body.ticket-info[n].sname = tickets[n].sname;
+ body.ticket-info[n].caddr = tickets[n].caddr;
+ done
+
+ get system_time;
+ body.timestamp, body.usec := system_time;
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+ if (using nonce) then
+ body.nonce := nonce;
+ endif
+
+ if (using s-address) then
+ body.s-address := sender host addresses;
+ endif
+ if (limited recipients) then
+ body.r-address := recipient host address;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part.cipher
+ using negotiated encryption key;
+
+A.19. KRB_CRED verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_CRED) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+
+ cleartext := decrypt(packet.enc-part) using negotiated key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if ((packet.r-address is present or required) and
+ (packet.s-address != O/S_sender(packet)) then
+ /* O/S report of sender not who claims to have sent it */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if ((packet.r-address is present) and
+ (packet.r-address != local_host_address)) then
+ /* was not sent to proper place */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (not in_clock_skew(packet.timestamp,packet.usec)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(packet.timestamp,packet.usec,packet.s-address)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ if (packet.nonce is required or present) and
+ (packet.nonce != expected-nonce) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ for (ticket[n] in tickets that were forwarded) do
+ save_for_later(ticket[n],key[n],principal[n],
+ server[n],times[n],flags[n]);
+ return
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+A.20. KRB_ERROR generation
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_ERROR */
+
+ get system_time;
+ packet.stime, packet.susec := system_time;
+ packet.realm, packet.sname := server name;
+
+ if (client time available) then
+ packet.ctime, packet.cusec := client_time;
+ endif
+ packet.error-code := error code;
+ if (client name available) then
+ packet.cname, packet.crealm := client name;
+ endif
+ if (error text available) then
+ packet.e-text := error text;
+ endif
+ if (error data available) then
+ packet.e-data := error data;
+ endif
+
+B. Definition of common authorization data elements
+
+This appendix contains the definitions of common authorization data
+elements. These common authorization data elements are recursivly defined,
+meaning the ad-data for these types will itself contain a sequence of
+authorization data whose interpretation is affected by the encapsulating
+element. Depending on the meaning of the encapsulating element, the
+encapsulated elements may be ignored, might be interpreted as issued
+directly by the KDC, or they might be stored in a separate plaintext part
+of the ticket. The types of the encapsulating elements are specified as
+part of the Kerberos specification because the behavior based on these
+values should be understood across implementations whereas other elements
+need only be understood by the applications which they affect.
+
+In the definitions that follow, the value of the ad-type for the element
+will be specified in the subsection number, and the value of the ad-data
+will be as shown in the ASN.1 structure that follows the subsection
+heading.
+
+B.1. KDC Issued
+
+AD-KDCIssued SEQUENCE {
+ ad-checksum[0] Checksum,
+ i-realm[1] Realm OPTIONAL,
+ i-sname[2] PrincipalName OPTIONAL,
+ elements[3] AuthorizationData.
+}
+
+ad-checksum
+ A checksum over the elements field using a cryptographic checksum
+ method that is identical to the checksum used to protect the ticket
+ itself (i.e. using the same hash function and the same encryption
+ algorithm used to encrypt the ticket) and using a key derived from the
+ same key used to protect the ticket.
+i-realm, i-sname
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+ The name of the issuing principal if different from the KDC itself.
+ This field would be used when the KDC can verify the authenticity of
+ elements signed by the issuing principal and it allows this KDC to
+ notify the application server of the validity of those elements.
+elements
+ A sequence of authorization data elements issued by the KDC.
+
+The KDC-issued ad-data field is intended to provide a means for Kerberos
+principal credentials to embed within themselves privilege attributes and
+other mechanisms for positive authorization, amplifying the priveleges of
+the principal beyond what can be done using a credentials without such an
+a-data element.
+
+This can not be provided without this element because the definition of the
+authorization-data field allows elements to be added at will by the bearer
+of a TGT at the time that they request service tickets and elements may
+also be added to a delegated ticket by inclusion in the authenticator.
+
+For KDC-issued elements this is prevented because the elements are signed
+by the KDC by including a checksum encrypted using the server's key (the
+same key used to encrypt the ticket - or a key derived from that key).
+Elements encapsulated with in the KDC-issued element will be ignored by the
+application server if this "signature" is not present. Further, elements
+encapsulated within this element from a ticket granting ticket may be
+interpreted by the KDC, and used as a basis according to policy for
+including new signed elements within derivative tickets, but they will not
+be copied to a derivative ticket directly. If they are copied directly to a
+derivative ticket by a KDC that is not aware of this element, the signature
+will not be correct for the application ticket elements, and the field will
+be ignored by the application server.
+
+This element and the elements it encapulates may be safely ignored by
+applications, application servers, and KDCs that do not implement this
+element.
+
+B.2. Intended for server
+
+AD-INTENDED-FOR-SERVER SEQUENCE {
+ intended-server[0] SEQUENCE OF PrincipalName
+ elements[1] AuthorizationData
+}
+
+AD elements encapsulated within the intended-for-server element may be
+ignored if the application server is not in the list of principal names of
+intended servers. Further, a KDC issuing a ticket for an application server
+can remove this element if the application server is not in the list of
+intended servers.
+
+Application servers should check for their principal name in the
+intended-server field of this element. If their principal name is not
+found, this element should be ignored. If found, then the encapsulated
+elements should be evaluated in the same manner as if they were present in
+the top level authorization data field. Applications and application
+servers that do not implement this element should reject tickets that
+contain authorization data elements of this type.
+
+B.3. Intended for application class
+
+AD-INTENDED-FOR-APPLICATION-CLASS SEQUENCE { intended-application-class[0]
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+SEQUENCE OF GeneralString elements[1] AuthorizationData } AD elements
+encapsulated within the intended-for-application-class element may be
+ignored if the application server is not in one of the named classes of
+application servers. Examples of application server classes include
+"FILESYSTEM", and other kinds of servers.
+
+This element and the elements it encapulates may be safely ignored by
+applications, application servers, and KDCs that do not implement this
+element.
+
+B.4. If relevant
+
+AD-IF-RELEVANT AuthorizationData
+
+AD elements encapsulated within the if-relevant element are intended for
+interpretation only by application servers that understand the particular
+ad-type of the embedded element. Application servers that do not understand
+the type of an element embedded within the if-relevant element may ignore
+the uninterpretable element. This element promotes interoperability across
+implementations which may have local extensions for authorization.
+
+B.5. And-Or
+
+AD-AND-OR SEQUENCE {
+ condition-count[0] INTEGER,
+ elements[1] AuthorizationData
+}
+
+When restrictive AD elements encapsulated within the and-or element are
+encountered, only the number specified in condition-count of the
+encapsulated conditions must be met in order to satisfy this element. This
+element may be used to implement an "or" operation by setting the
+condition-count field to 1, and it may specify an "and" operation by
+setting the condition count to the number of embedded elements. Application
+servers that do not implement this element must reject tickets that contain
+authorization data elements of this type.
+
+B.6. Mandatory ticket extensions
+
+AD-Mandatory-Ticket-Extensions Checksum
+
+An authorization data element of type mandatory-ticket-extensions specifies
+a collision-proof checksum using the same hash algorithm used to protect
+the integrity of the ticket itself. This checksum will be calculated over
+an individual extension field. If there are more than one extension,
+multiple Mandatory-Ticket-Extensions authorization data elements may be
+present, each with a checksum for a different extension field. This
+restriction indicates that the ticket should not be accepted if a ticket
+extension is not present in the ticket for which the checksum does not
+match that checksum specified in the authorization data element.
+Application servers that do not implement this element must reject tickets
+that contain authorization data elements of this type.
+
+B.7. Authorization Data in ticket extensions
+
+AD-IN-Ticket-Extensions Checksum
+
+An authorization data element of type in-ticket-extensions specifies a
+collision-proof checksum using the same hash algorithm used to protect the
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+integrity of the ticket itself. This checksum is calculated over a separate
+external AuthorizationData field carried in the ticket extensions.
+Application servers that do not implement this element must reject tickets
+that contain authorization data elements of this type. Application servers
+that do implement this element will search the ticket extensions for
+authorization data fields, calculate the specified checksum over each
+authorization data field and look for one matching the checksum in this
+in-ticket-extensions element. If not found, then the ticket must be
+rejected. If found, the corresponding authorization data elements will be
+interpreted in the same manner as if they were contained in the top level
+authorization data field.
+
+Note that if multiple external authorization data fields are present in a
+ticket, each will have a corresponding element of type in-ticket-extensions
+in the top level authorization data field, and the external entries will be
+linked to the corresponding element by their checksums.
+
+C. Definition of common ticket extensions
+
+This appendix contains the definitions of common ticket extensions. Support
+for these extensions is optional. However, certain extensions have
+associated authorization data elements that may require rejection of a
+ticket containing an extension by application servers that do not implement
+the particular extension. Other extensions have been defined beyond those
+described in this specification. Such extensions are described elswhere and
+for some of those extensions the reserved number may be found in the list
+of constants.
+
+It is known that older versions of Kerberos did not support this field, and
+that some clients will strip this field from a ticket when they parse and
+then reassemble a ticket as it is passed to the application servers. The
+presence of the extension will not break such clients, but any functionaly
+dependent on the extensions will not work when such tickets are handled by
+old clients. In such situations, some implementation may use alternate
+methods to transmit the information in the extensions field.
+
+C.1. Null ticket extension
+
+TE-NullExtension OctetString -- The empty Octet String
+
+The te-data field in the null ticket extension is an octet string of lenght
+zero. This extension may be included in a ticket granting ticket so that
+the KDC can determine on presentation of the ticket granting ticket whether
+the client software will strip the extensions field.
+
+C.2. External Authorization Data
+
+TE-ExternalAuthorizationData AuthorizationData
+
+The te-data field in the external authorization data ticket extension is
+field of type AuthorizationData containing one or more authorization data
+elements. If present, a corresponding authorization data element will be
+present in the primary authorization data for the ticket and that element
+will contain a checksum of the external authorization data ticket
+extension.
+ ------------------------------------------------------------------------
+[TM] Project Athena, Athena, and Kerberos are trademarks of the
+Massachusetts Institute of Technology (MIT). No commercial use of these
+trademarks may be made without prior written permission of MIT.
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+[1] Note, however, that many applications use Kerberos' functions only upon
+the initiation of a stream-based network connection. Unless an application
+subsequently provides integrity protection for the data stream, the
+identity verification applies only to the initiation of the connection, and
+does not guarantee that subsequent messages on the connection originate
+from the same principal.
+
+[2] Secret and private are often used interchangeably in the literature. In
+our usage, it takes two (or more) to share a secret, thus a shared DES key
+is a secret key. Something is only private when no one but its owner knows
+it. Thus, in public key cryptosystems, one has a public and a private key.
+
+[3] Of course, with appropriate permission the client could arrange
+registration of a separately-named prin- cipal in a remote realm, and
+engage in normal exchanges with that realm's services. However, for even
+small numbers of clients this becomes cumbersome, and more automatic
+methods as described here are necessary.
+
+[4] Though it is permissible to request or issue tick- ets with no network
+addresses specified.
+
+[5] The password-changing request must not be honored unless the requester
+can provide the old password (the user's current secret key). Otherwise, it
+would be possible for someone to walk up to an unattended ses- sion and
+change another user's password.
+
+[6] To authenticate a user logging on to a local system, the credentials
+obtained in the AS exchange may first be used in a TGS exchange to obtain
+credentials for a local server. Those credentials must then be verified by
+a local server through successful completion of the Client/Server exchange.
+
+[7] "Random" means that, among other things, it should be impossible to
+guess the next session key based on knowledge of past session keys. This
+can only be achieved in a pseudo-random number generator if it is based on
+cryptographic principles. It is more desirable to use a truly random number
+generator, such as one based on measurements of random physical phenomena.
+
+[8] Tickets contain both an encrypted and unencrypted portion, so cleartext
+here refers to the entire unit, which can be copied from one message and
+replayed in another without any cryptographic skill.
+
+[9] Note that this can make applications based on unreliable transports
+difficult to code correctly. If the transport might deliver duplicated
+messages, either a new authenticator must be generated for each retry, or
+the application server must match requests and replies and replay the first
+reply in response to a detected duplicate.
+
+[10] This is used for user-to-user authentication as described in [8].
+
+[11] Note that the rejection here is restricted to authenticators from the
+same principal to the same server. Other client principals communicating
+with the same server principal should not be have their authenticators
+rejected if the time and microsecond fields happen to match some other
+client's authenticator.
+
+[12] In the Kerberos version 4 protocol, the timestamp in the reply was the
+client's timestamp plus one. This is not necessary in version 5 because
+version 5 messages are formatted in such a way that it is not possible to
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+create the reply by judicious message surgery (even in encrypted form)
+without knowledge of the appropriate encryption keys.
+
+[13] Note that for encrypting the KRB_AP_REP message, the sub-session key
+is not used, even if present in the Authenticator.
+
+[14] Implementations of the protocol may wish to provide routines to choose
+subkeys based on session keys and random numbers and to generate a
+negotiated key to be returned in the KRB_AP_REP message.
+
+[15]This can be accomplished in several ways. It might be known beforehand
+(since the realm is part of the principal identifier), it might be stored
+in a nameserver, or it might be obtained from a configura- tion file. If
+the realm to be used is obtained from a nameserver, there is a danger of
+being spoofed if the nameservice providing the realm name is not authenti-
+cated. This might result in the use of a realm which has been compromised,
+and would result in an attacker's ability to compromise the authentication
+of the application server to the client.
+
+[16] If the client selects a sub-session key, care must be taken to ensure
+the randomness of the selected sub- session key. One approach would be to
+generate a random number and XOR it with the session key from the
+ticket-granting ticket.
+
+[17] This allows easy implementation of user-to-user authentication [8],
+which uses ticket-granting ticket session keys in lieu of secret server
+keys in situa- tions where such secret keys could be easily comprom- ised.
+
+[18] For the purpose of appending, the realm preceding the first listed
+realm is considered to be the null realm ("").
+
+[19] For the purpose of interpreting null subfields, the client's realm is
+considered to precede those in the transited field, and the server's realm
+is considered to follow them.
+
+[20] This means that a client and server running on the same host and
+communicating with one another using the KRB_SAFE messages should not share
+a common replay cache to detect KRB_SAFE replays.
+
+[21] The implementation of the Kerberos server need not combine the
+database and the server on the same machine; it is feasible to store the
+principal database in, say, a network name service, as long as the entries
+stored therein are protected from disclosure to and modification by
+unauthorized parties. However, we recommend against such strategies, as
+they can make system management and threat analysis quite complex.
+
+[22] See the discussion of the padata field in section 5.4.2 for details on
+why this can be useful.
+
+[23] Warning for implementations that unpack and repack data structures
+during the generation and verification of embedded checksums: Because any
+checksums applied to data structures must be checked against the original
+data the length of bit strings must be preserved within a data structure
+between the time that a checksum is generated through transmission to the
+time that the checksum is verified.
+
+[24] It is NOT recommended that this time value be used to adjust the
+workstation's clock since the workstation cannot reliably determine that
+such a KRB_AS_REP actually came from the proper KDC in a timely manner.
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-r-03 November 18 1998
+
+
+
+[25] Note, however, that if the time is used as the nonce, one must make
+sure that the workstation time is monotonically increasing. If the time is
+ever reset backwards, there is a small, but finite, probability that a
+nonce will be reused.
+
+[27] An application code in the encrypted part of a message provides an
+additional check that the message was decrypted properly.
+
+[29] An application code in the encrypted part of a message provides an
+additional check that the message was decrypted properly.
+
+[31] An application code in the encrypted part of a message provides an
+additional check that the message was decrypted properly.
+
+[32] If supported by the encryption method in use, an initialization vector
+may be passed to the encryption procedure, in order to achieve proper
+cipher chaining. The initialization vector might come from the last block
+of the ciphertext from the previous KRB_PRIV message, but it is the
+application's choice whether or not to use such an initialization vector.
+If left out, the default initialization vector for the encryption algorithm
+will be used.
+
+[33] This prevents an attacker who generates an incorrect AS request from
+obtaining verifiable plaintext for use in an off-line password guessing
+attack.
+
+[35] In the above specification, UNTAGGED OCTET STRING(length) is the
+notation for an octet string with its tag and length removed. It is not a
+valid ASN.1 type. The tag bits and length must be removed from the
+confounder since the purpose of the confounder is so that the message
+starts with random data, but the tag and its length are fixed. For other
+fields, the length and tag would be redundant if they were included because
+they are specified by the encryption type. [36] The ordering of the fields
+in the CipherText is important. Additionally, messages encoded in this
+format must include a length as part of the msg-seq field. This allows the
+recipient to verify that the message has not been truncated. Without a
+length, an attacker could use a chosen plaintext attack to generate a
+message which could be truncated, while leaving the checksum intact. Note
+that if the msg-seq is an encoding of an ASN.1 SEQUENCE or OCTET STRING,
+then the length is part of that encoding.
+
+[37] In some cases, it may be necessary to use a different "mix-in" string
+for compatibility reasons; see the discussion of padata in section 5.4.2.
+
+[38] In some cases, it may be necessary to use a different "mix-in" string
+for compatibility reasons; see the discussion of padata in section 5.4.2.
+
+[39] A variant of the key is used to limit the use of a key to a particular
+function, separating the functions of generating a checksum from other
+encryption performed using the session key. The constant F0F0F0F0F0F0F0F0
+was chosen because it maintains key parity. The properties of DES precluded
+the use of the complement. The same constant is used for similar purpose in
+the Message Integrity Check in the Privacy Enhanced Mail standard.
+
+[40] This error carries additional information in the e- data field. The
+contents of the e-data field for this message is described in section
+5.9.1.
+
+
+Neuman, Ts'o, Kohl Expires: 18 May 1999
+
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-04.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-04.txt
new file mode 100644
index 000000000000..16af15dbce9f
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-kerberos-revisions-04.txt
@@ -0,0 +1,6780 @@
+INTERNET-DRAFT Clifford Neuman
+ John Kohl
+ Theodore Ts'o
+ June 25, 1999
+ Expires December 25, 1999
+draft-ietf-cat-kerberos-revisions-04.txt
+
+The Kerberos Network Authentication Service (V5)
+
+STATUS OF THIS MEMO
+
+This document is an Internet-Draft and is in full conformance with all
+provisions of Section 10 of RFC2026. Internet-Drafts are working documents
+of the Internet Engineering Task Force (IETF), its areas, and its working
+groups. Note that other groups may also distribute working documents as
+Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum of six months and
+may be updated, replaced, or obsoleted by other documents at any time. It is
+inappropriate to use Internet- Drafts as reference material or to cite them
+other than as "work in progress."
+
+The list of current Internet-Drafts can be accessed at
+http://www.ietf.org/ietf/1id-abstracts.txt
+
+The list of Internet-Draft Shadow Directories can be accessed at
+http://www.ietf.org/shadow.html. To learn the current status of any
+Internet-Draft, please check the '1id-abstracts.txt' listing contained in
+the Internet-Drafts Shadow Directories.
+
+The distribution of this memo is unlimited. It is filed as
+draft-ietf-cat-kerberos-revisions-04.txt, and expires December 25th, 1999.
+Please send comments to: krb-protocol@MIT.EDU
+
+ABSTRACT
+
+This document provides an overview and specification of Version 5 of the
+Kerberos protocol, and updates RFC1510 to clarify aspects of the protocol
+and its intended use that require more detailed or clearer explanation than
+was provided in RFC1510. This document is intended to provide a detailed
+description of the protocol, suitable for implementation, together with
+descriptions of the appropriate use of protocol messages and fields within
+those messages.
+
+This document is not intended to describe Kerberos to the end user, system
+administrator, or application developer. Higher level papers describing
+Version 5 of the Kerberos system [NT94] and documenting version 4 [SNS88],
+are available elsewhere.
+
+OVERVIEW
+
+This INTERNET-DRAFT describes the concepts and model upon which the Kerberos
+network authentication system is based. It also specifies Version 5 of the
+Kerberos protocol.
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+The motivations, goals, assumptions, and rationale behind most design
+decisions are treated cursorily; they are more fully described in a paper
+available in IEEE communications [NT94] and earlier in the Kerberos portion
+of the Athena Technical Plan [MNSS87]. The protocols have been a proposed
+standard and are being considered for advancement for draft standard through
+the IETF standard process. Comments are encouraged on the presentation, but
+only minor refinements to the protocol as implemented or extensions that fit
+within current protocol framework will be considered at this time.
+
+Requests for addition to an electronic mailing list for discussion of
+Kerberos, kerberos@MIT.EDU, may be addressed to kerberos-request@MIT.EDU.
+This mailing list is gatewayed onto the Usenet as the group
+comp.protocols.kerberos. Requests for further information, including
+documents and code availability, may be sent to info-kerberos@MIT.EDU.
+
+BACKGROUND
+
+The Kerberos model is based in part on Needham and Schroeder's trusted
+third-party authentication protocol [NS78] and on modifications suggested by
+Denning and Sacco [DS81]. The original design and implementation of Kerberos
+Versions 1 through 4 was the work of two former Project Athena staff
+members, Steve Miller of Digital Equipment Corporation and Clifford Neuman
+(now at the Information Sciences Institute of the University of Southern
+California), along with Jerome Saltzer, Technical Director of Project
+Athena, and Jeffrey Schiller, MIT Campus Network Manager. Many other members
+of Project Athena have also contributed to the work on Kerberos.
+
+Version 5 of the Kerberos protocol (described in this document) has evolved
+from Version 4 based on new requirements and desires for features not
+available in Version 4. The design of Version 5 of the Kerberos protocol was
+led by Clifford Neuman and John Kohl with much input from the community. The
+development of the MIT reference implementation was led at MIT by John Kohl
+and Theodore T'so, with help and contributed code from many others. Since
+RFC1510 was issued, extensions and revisions to the protocol have been
+proposed by many individuals. Some of these proposals are reflected in this
+document. Where such changes involved significant effort, the document cites
+the contribution of the proposer.
+
+Reference implementations of both version 4 and version 5 of Kerberos are
+publicly available and commercial implementations have been developed and
+are widely used. Details on the differences between Kerberos Versions 4 and
+5 can be found in [KNT92].
+
+1. Introduction
+
+Kerberos provides a means of verifying the identities of principals, (e.g. a
+workstation user or a network server) on an open (unprotected) network. This
+is accomplished without relying on assertions by the host operating system,
+without basing trust on host addresses, without requiring physical security
+of all the hosts on the network, and under the assumption that packets
+traveling along the network can be read, modified, and inserted at will[1].
+Kerberos performs authentication under these conditions as a trusted
+third-party authentication service by using conventional (shared secret key
+[2] cryptography. Kerberos extensions have been proposed and implemented
+that provide for the use of public key cryptography during certain phases of
+the authentication protocol. These extensions provide for authentication of
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+users registered with public key certification authorities, and allow the
+system to provide certain benefits of public key cryptography in situations
+where they are needed.
+
+The basic Kerberos authentication process proceeds as follows: A client
+sends a request to the authentication server (AS) requesting 'credentials'
+for a given server. The AS responds with these credentials, encrypted in the
+client's key. The credentials consist of 1) a 'ticket' for the server and 2)
+a temporary encryption key (often called a "session key"). The client
+transmits the ticket (which contains the client's identity and a copy of the
+session key, all encrypted in the server's key) to the server. The session
+key (now shared by the client and server) is used to authenticate the
+client, and may optionally be used to authenticate the server. It may also
+be used to encrypt further communication between the two parties or to
+exchange a separate sub-session key to be used to encrypt further
+communication.
+
+Implementation of the basic protocol consists of one or more authentication
+servers running on physically secure hosts. The authentication servers
+maintain a database of principals (i.e., users and servers) and their secret
+keys. Code libraries provide encryption and implement the Kerberos protocol.
+In order to add authentication to its transactions, a typical network
+application adds one or two calls to the Kerberos library directly or
+through the Generic Security Services Application Programming Interface,
+GSSAPI, described in separate document. These calls result in the
+transmission of the necessary messages to achieve authentication.
+
+The Kerberos protocol consists of several sub-protocols (or exchanges).
+There are two basic methods by which a client can ask a Kerberos server for
+credentials. In the first approach, the client sends a cleartext request for
+a ticket for the desired server to the AS. The reply is sent encrypted in
+the client's secret key. Usually this request is for a ticket-granting
+ticket (TGT) which can later be used with the ticket-granting server (TGS).
+In the second method, the client sends a request to the TGS. The client uses
+the TGT to authenticate itself to the TGS in the same manner as if it were
+contacting any other application server that requires Kerberos
+authentication. The reply is encrypted in the session key from the TGT.
+Though the protocol specification describes the AS and the TGS as separate
+servers, they are implemented in practice as different protocol entry points
+within a single Kerberos server.
+
+Once obtained, credentials may be used to verify the identity of the
+principals in a transaction, to ensure the integrity of messages exchanged
+between them, or to preserve privacy of the messages. The application is
+free to choose whatever protection may be necessary.
+
+To verify the identities of the principals in a transaction, the client
+transmits the ticket to the application server. Since the ticket is sent "in
+the clear" (parts of it are encrypted, but this encryption doesn't thwart
+replay) and might be intercepted and reused by an attacker, additional
+information is sent to prove that the message originated with the principal
+to whom the ticket was issued. This information (called the authenticator)
+is encrypted in the session key, and includes a timestamp. The timestamp
+proves that the message was recently generated and is not a replay.
+Encrypting the authenticator in the session key proves that it was generated
+by a party possessing the session key. Since no one except the requesting
+principal and the server know the session key (it is never sent over the
+network in the clear) this guarantees the identity of the client.
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+The integrity of the messages exchanged between principals can also be
+guaranteed using the session key (passed in the ticket and contained in the
+credentials). This approach provides detection of both replay attacks and
+message stream modification attacks. It is accomplished by generating and
+transmitting a collision-proof checksum (elsewhere called a hash or digest
+function) of the client's message, keyed with the session key. Privacy and
+integrity of the messages exchanged between principals can be secured by
+encrypting the data to be passed using the session key contained in the
+ticket or the subsession key found in the authenticator.
+
+The authentication exchanges mentioned above require read-only access to the
+Kerberos database. Sometimes, however, the entries in the database must be
+modified, such as when adding new principals or changing a principal's key.
+This is done using a protocol between a client and a third Kerberos server,
+the Kerberos Administration Server (KADM). There is also a protocol for
+maintaining multiple copies of the Kerberos database. Neither of these
+protocols are described in this document.
+
+1.1. Cross-Realm Operation
+
+The Kerberos protocol is designed to operate across organizational
+boundaries. A client in one organization can be authenticated to a server in
+another. Each organization wishing to run a Kerberos server establishes its
+own 'realm'. The name of the realm in which a client is registered is part
+of the client's name, and can be used by the end-service to decide whether
+to honor a request.
+
+By establishing 'inter-realm' keys, the administrators of two realms can
+allow a client authenticated in the local realm to prove its identity to
+servers in other realms[3]. The exchange of inter-realm keys (a separate key
+may be used for each direction) registers the ticket-granting service of
+each realm as a principal in the other realm. A client is then able to
+obtain a ticket-granting ticket for the remote realm's ticket-granting
+service from its local realm. When that ticket-granting ticket is used, the
+remote ticket-granting service uses the inter-realm key (which usually
+differs from its own normal TGS key) to decrypt the ticket-granting ticket,
+and is thus certain that it was issued by the client's own TGS. Tickets
+issued by the remote ticket-granting service will indicate to the
+end-service that the client was authenticated from another realm.
+
+A realm is said to communicate with another realm if the two realms share an
+inter-realm key, or if the local realm shares an inter-realm key with an
+intermediate realm that communicates with the remote realm. An
+authentication path is the sequence of intermediate realms that are
+transited in communicating from one realm to another.
+
+Realms are typically organized hierarchically. Each realm shares a key with
+its parent and a different key with each child. If an inter-realm key is not
+directly shared by two realms, the hierarchical organization allows an
+authentication path to be easily constructed. If a hierarchical organization
+is not used, it may be necessary to consult a database in order to construct
+an authentication path between realms.
+
+Although realms are typically hierarchical, intermediate realms may be
+bypassed to achieve cross-realm authentication through alternate
+authentication paths (these might be established to make communication
+between two realms more efficient). It is important for the end-service to
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+know which realms were transited when deciding how much faith to place in
+the authentication process. To facilitate this decision, a field in each
+ticket contains the names of the realms that were involved in authenticating
+the client.
+
+The application server is ultimately responsible for accepting or rejecting
+authentication and should check the transited field. The application server
+may choose to rely on the KDC for the application server's realm to check
+the transited field. The application server's KDC will set the
+TRANSITED-POLICY-CHECKED flag in this case. The KDC's for intermediate
+realms may also check the transited field as they issue
+ticket-granting-tickets for other realms, but they are encouraged not to do
+so. A client may request that the KDC's not check the transited field by
+setting the DISABLE-TRANSITED-CHECK flag. KDC's are encouraged but not
+required to honor this flag.
+
+1.2. Authorization
+
+As an authentication service, Kerberos provides a means of verifying the
+identity of principals on a network. Authentication is usually useful
+primarily as a first step in the process of authorization, determining
+whether a client may use a service, which objects the client is allowed to
+access, and the type of access allowed for each. Kerberos does not, by
+itself, provide authorization. Possession of a client ticket for a service
+provides only for authentication of the client to that service, and in the
+absence of a separate authorization procedure, it should not be considered
+by an application as authorizing the use of that service.
+
+Such separate authorization methods may be implemented as application
+specific access control functions and may be based on files such as the
+application server, or on separately issued authorization credentials such
+as those based on proxies [Neu93] , or on other authorization services.
+
+Applications should not be modified to accept the issuance of a service
+ticket by the Kerberos server (even by an modified Kerberos server) as
+granting authority to use the service, since such applications may become
+vulnerable to the bypass of this authorization check in an environment if
+they interoperate with other KDCs or where other options for application
+authentication (e.g. the PKTAPP proposal) are provided.
+
+1.3. Environmental assumptions
+
+Kerberos imposes a few assumptions on the environment in which it can
+properly function:
+
+ * 'Denial of service' attacks are not solved with Kerberos. There are
+ places in these protocols where an intruder can prevent an application
+ from participating in the proper authentication steps. Detection and
+ solution of such attacks (some of which can appear to be nnot-uncommon
+ 'normal' failure modes for the system) is usually best left to the
+ human administrators and users.
+ * Principals must keep their secret keys secret. If an intruder somehow
+ steals a principal's key, it will be able to masquerade as that
+ principal or impersonate any server to the legitimate principal.
+ * 'Password guessing' attacks are not solved by Kerberos. If a user
+ chooses a poor password, it is possible for an attacker to successfully
+ mount an offline dictionary attack by repeatedly attempting to decrypt,
+ with successive entries from a dictionary, messages obtained which are
+ encrypted under a key derived from the user's password.
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ * Each host on the network must have a clock which is 'loosely
+ synchronized' to the time of the other hosts; this synchronization is
+ used to reduce the bookkeeping needs of application servers when they
+ do replay detection. The degree of "looseness" can be configured on a
+ per-server basis, but is typically on the order of 5 minutes. If the
+ clocks are synchronized over the network, the clock synchronization
+ protocol must itself be secured from network attackers.
+ * Principal identifiers are not recycled on a short-term basis. A typical
+ mode of access control will use access control lists (ACLs) to grant
+ permissions to particular principals. If a stale ACL entry remains for
+ a deleted principal and the principal identifier is reused, the new
+ principal will inherit rights specified in the stale ACL entry. By not
+ re-using principal identifiers, the danger of inadvertent access is
+ removed.
+
+1.4. Glossary of terms
+
+Below is a list of terms used throughout this document.
+
+Authentication
+ Verifying the claimed identity of a principal.
+Authentication header
+ A record containing a Ticket and an Authenticator to be presented to a
+ server as part of the authentication process.
+Authentication path
+ A sequence of intermediate realms transited in the authentication
+ process when communicating from one realm to another.
+Authenticator
+ A record containing information that can be shown to have been recently
+ generated using the session key known only by the client and server.
+Authorization
+ The process of determining whether a client may use a service, which
+ objects the client is allowed to access, and the type of access allowed
+ for each.
+Capability
+ A token that grants the bearer permission to access an object or
+ service. In Kerberos, this might be a ticket whose use is restricted by
+ the contents of the authorization data field, but which lists no
+ network addresses, together with the session key necessary to use the
+ ticket.
+Ciphertext
+ The output of an encryption function. Encryption transforms plaintext
+ into ciphertext.
+Client
+ A process that makes use of a network service on behalf of a user. Note
+ that in some cases a Server may itself be a client of some other server
+ (e.g. a print server may be a client of a file server).
+Credentials
+ A ticket plus the secret session key necessary to successfully use that
+ ticket in an authentication exchange.
+KDC
+ Key Distribution Center, a network service that supplies tickets and
+ temporary session keys; or an instance of that service or the host on
+ which it runs. The KDC services both initial ticket and ticket-granting
+ ticket requests. The initial ticket portion is sometimes referred to as
+ the Authentication Server (or service). The ticket-granting ticket
+ portion is sometimes referred to as the ticket-granting server (or
+ service).
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+Kerberos
+ Aside from the 3-headed dog guarding Hades, the name given to Project
+ Athena's authentication service, the protocol used by that service, or
+ the code used to implement the authentication service.
+Plaintext
+ The input to an encryption function or the output of a decryption
+ function. Decryption transforms ciphertext into plaintext.
+Principal
+ A uniquely named client or server instance that participates in a
+ network communication.
+Principal identifier
+ The name used to uniquely identify each different principal.
+Seal
+ To encipher a record containing several fields in such a way that the
+ fields cannot be individually replaced without either knowledge of the
+ encryption key or leaving evidence of tampering.
+Secret key
+ An encryption key shared by a principal and the KDC, distributed
+ outside the bounds of the system, with a long lifetime. In the case of
+ a human user's principal, the secret key is derived from a password.
+Server
+ A particular Principal which provides a resource to network clients.
+ The server is sometimes refered to as the Application Server.
+Service
+ A resource provided to network clients; often provided by more than one
+ server (for example, remote file service).
+Session key
+ A temporary encryption key used between two principals, with a lifetime
+ limited to the duration of a single login "session".
+Sub-session key
+ A temporary encryption key used between two principals, selected and
+ exchanged by the principals using the session key, and with a lifetime
+ limited to the duration of a single association.
+Ticket
+ A record that helps a client authenticate itself to a server; it
+ contains the client's identity, a session key, a timestamp, and other
+ information, all sealed using the server's secret key. It only serves
+ to authenticate a client when presented along with a fresh
+ Authenticator.
+
+2. Ticket flag uses and requests
+
+Each Kerberos ticket contains a set of flags which are used to indicate
+various attributes of that ticket. Most flags may be requested by a client
+when the ticket is obtained; some are automatically turned on and off by a
+Kerberos server as required. The following sections explain what the various
+flags mean, and gives examples of reasons to use such a flag.
+
+2.1. Initial and pre-authenticated tickets
+
+The INITIAL flag indicates that a ticket was issued using the AS protocol
+and not issued based on a ticket-granting ticket. Application servers that
+want to require the demonstrated knowledge of a client's secret key (e.g. a
+password-changing program) can insist that this flag be set in any tickets
+they accept, and thus be assured that the client's key was recently
+presented to the application client.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+The PRE-AUTHENT and HW-AUTHENT flags provide addition information about the
+initial authentication, regardless of whether the current ticket was issued
+directly (in which case INITIAL will also be set) or issued on the basis of
+a ticket-granting ticket (in which case the INITIAL flag is clear, but the
+PRE-AUTHENT and HW-AUTHENT flags are carried forward from the
+ticket-granting ticket).
+
+2.2. Invalid tickets
+
+The INVALID flag indicates that a ticket is invalid. Application servers
+must reject tickets which have this flag set. A postdated ticket will
+usually be issued in this form. Invalid tickets must be validated by the KDC
+before use, by presenting them to the KDC in a TGS request with the VALIDATE
+option specified. The KDC will only validate tickets after their starttime
+has passed. The validation is required so that postdated tickets which have
+been stolen before their starttime can be rendered permanently invalid
+(through a hot-list mechanism) (see section 3.3.3.1).
+
+2.3. Renewable tickets
+
+Applications may desire to hold tickets which can be valid for long periods
+of time. However, this can expose their credentials to potential theft for
+equally long periods, and those stolen credentials would be valid until the
+expiration time of the ticket(s). Simply using short-lived tickets and
+obtaining new ones periodically would require the client to have long-term
+access to its secret key, an even greater risk. Renewable tickets can be
+used to mitigate the consequences of theft. Renewable tickets have two
+"expiration times": the first is when the current instance of the ticket
+expires, and the second is the latest permissible value for an individual
+expiration time. An application client must periodically (i.e. before it
+expires) present a renewable ticket to the KDC, with the RENEW option set in
+the KDC request. The KDC will issue a new ticket with a new session key and
+a later expiration time. All other fields of the ticket are left unmodified
+by the renewal process. When the latest permissible expiration time arrives,
+the ticket expires permanently. At each renewal, the KDC may consult a
+hot-list to determine if the ticket had been reported stolen since its last
+renewal; it will refuse to renew such stolen tickets, and thus the usable
+lifetime of stolen tickets is reduced.
+
+The RENEWABLE flag in a ticket is normally only interpreted by the
+ticket-granting service (discussed below in section 3.3). It can usually be
+ignored by application servers. However, some particularly careful
+application servers may wish to disallow renewable tickets.
+
+If a renewable ticket is not renewed by its expiration time, the KDC will
+not renew the ticket. The RENEWABLE flag is reset by default, but a client
+may request it be set by setting the RENEWABLE option in the KRB_AS_REQ
+message. If it is set, then the renew-till field in the ticket contains the
+time after which the ticket may not be renewed.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+2.4. Postdated tickets
+
+Applications may occasionally need to obtain tickets for use much later,
+e.g. a batch submission system would need tickets to be valid at the time
+the batch job is serviced. However, it is dangerous to hold valid tickets in
+a batch queue, since they will be on-line longer and more prone to theft.
+Postdated tickets provide a way to obtain these tickets from the KDC at job
+submission time, but to leave them "dormant" until they are activated and
+validated by a further request of the KDC. If a ticket theft were reported
+in the interim, the KDC would refuse to validate the ticket, and the thief
+would be foiled.
+
+The MAY-POSTDATE flag in a ticket is normally only interpreted by the
+ticket-granting service. It can be ignored by application servers. This flag
+must be set in a ticket-granting ticket in order to issue a postdated ticket
+based on the presented ticket. It is reset by default; it may be requested
+by a client by setting the ALLOW-POSTDATE option in the KRB_AS_REQ message.
+This flag does not allow a client to obtain a postdated ticket-granting
+ticket; postdated ticket-granting tickets can only by obtained by requesting
+the postdating in the KRB_AS_REQ message. The life (endtime-starttime) of a
+postdated ticket will be the remaining life of the ticket-granting ticket at
+the time of the request, unless the RENEWABLE option is also set, in which
+case it can be the full life (endtime-starttime) of the ticket-granting
+ticket. The KDC may limit how far in the future a ticket may be postdated.
+
+The POSTDATED flag indicates that a ticket has been postdated. The
+application server can check the authtime field in the ticket to see when
+the original authentication occurred. Some services may choose to reject
+postdated tickets, or they may only accept them within a certain period
+after the original authentication. When the KDC issues a POSTDATED ticket,
+it will also be marked as INVALID, so that the application client must
+present the ticket to the KDC to be validated before use.
+
+2.5. Proxiable and proxy tickets
+
+At times it may be necessary for a principal to allow a service to perform
+an operation on its behalf. The service must be able to take on the identity
+of the client, but only for a particular purpose. A principal can allow a
+service to take on the principal's identity for a particular purpose by
+granting it a proxy.
+
+The process of granting a proxy using the proxy and proxiable flags is used
+to provide credentials for use with specific services. Though conceptually
+also a proxy, user's wishing to delegate their identity for ANY purpose must
+use the ticket forwarding mechanism described in the next section to forward
+a ticket granting ticket.
+
+The PROXIABLE flag in a ticket is normally only interpreted by the
+ticket-granting service. It can be ignored by application servers. When set,
+this flag tells the ticket-granting server that it is OK to issue a new
+ticket (but not a ticket-granting ticket) with a different network address
+based on this ticket. This flag is set if requested by the client on initial
+authentication. By default, the client will request that it be set when
+requesting a ticket granting ticket, and reset when requesting any other
+ticket.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+This flag allows a client to pass a proxy to a server to perform a remote
+request on its behalf, e.g. a print service client can give the print server
+a proxy to access the client's files on a particular file server in order to
+satisfy a print request.
+
+In order to complicate the use of stolen credentials, Kerberos tickets are
+usually valid from only those network addresses specifically included in the
+ticket[4]. When granting a proxy, the client must specify the new network
+address from which the proxy is to be used, or indicate that the proxy is to
+be issued for use from any address.
+
+The PROXY flag is set in a ticket by the TGS when it issues a proxy ticket.
+Application servers may check this flag and at their option they may require
+additional authentication from the agent presenting the proxy in order to
+provide an audit trail.
+
+2.6. Forwardable tickets
+
+Authentication forwarding is an instance of a proxy where the service is
+granted complete use of the client's identity. An example where it might be
+used is when a user logs in to a remote system and wants authentication to
+work from that system as if the login were local.
+
+The FORWARDABLE flag in a ticket is normally only interpreted by the
+ticket-granting service. It can be ignored by application servers. The
+FORWARDABLE flag has an interpretation similar to that of the PROXIABLE
+flag, except ticket-granting tickets may also be issued with different
+network addresses. This flag is reset by default, but users may request that
+it be set by setting the FORWARDABLE option in the AS request when they
+request their initial ticket- granting ticket.
+
+This flag allows for authentication forwarding without requiring the user to
+enter a password again. If the flag is not set, then authentication
+forwarding is not permitted, but the same result can still be achieved if
+the user engages in the AS exchange specifying the requested network
+addresses and supplies a password.
+
+The FORWARDED flag is set by the TGS when a client presents a ticket with
+the FORWARDABLE flag set and requests a forwarded ticket by specifying the
+FORWARDED KDC option and supplying a set of addresses for the new ticket. It
+is also set in all tickets issued based on tickets with the FORWARDED flag
+set. Application servers may choose to process FORWARDED tickets differently
+than non-FORWARDED tickets.
+
+2.7. Other KDC options
+
+There are two additional options which may be set in a client's request of
+the KDC. The RENEWABLE-OK option indicates that the client will accept a
+renewable ticket if a ticket with the requested life cannot otherwise be
+provided. If a ticket with the requested life cannot be provided, then the
+KDC may issue a renewable ticket with a renew-till equal to the the
+requested endtime. The value of the renew-till field may still be adjusted
+by site-determined limits or limits imposed by the individual principal or
+server.
+
+The ENC-TKT-IN-SKEY option is honored only by the ticket-granting service.
+It indicates that the ticket to be issued for the end server is to be
+encrypted in the session key from the a additional second ticket-granting
+ticket provided with the request. See section 3.3.3 for specific details.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+3. Message Exchanges
+
+The following sections describe the interactions between network clients and
+servers and the messages involved in those exchanges.
+
+3.1. The Authentication Service Exchange
+
+ Summary
+ Message direction Message type Section
+ 1. Client to Kerberos KRB_AS_REQ 5.4.1
+ 2. Kerberos to client KRB_AS_REP or 5.4.2
+ KRB_ERROR 5.9.1
+
+The Authentication Service (AS) Exchange between the client and the Kerberos
+Authentication Server is initiated by a client when it wishes to obtain
+authentication credentials for a given server but currently holds no
+credentials. In its basic form, the client's secret key is used for
+encryption and decryption. This exchange is typically used at the initiation
+of a login session to obtain credentials for a Ticket-Granting Server which
+will subsequently be used to obtain credentials for other servers (see
+section 3.3) without requiring further use of the client's secret key. This
+exchange is also used to request credentials for services which must not be
+mediated through the Ticket-Granting Service, but rather require a
+principal's secret key, such as the password-changing service[5]. This
+exchange does not by itself provide any assurance of the the identity of the
+user[6].
+
+The exchange consists of two messages: KRB_AS_REQ from the client to
+Kerberos, and KRB_AS_REP or KRB_ERROR in reply. The formats for these
+messages are described in sections 5.4.1, 5.4.2, and 5.9.1.
+
+In the request, the client sends (in cleartext) its own identity and the
+identity of the server for which it is requesting credentials. The response,
+KRB_AS_REP, contains a ticket for the client to present to the server, and a
+session key that will be shared by the client and the server. The session
+key and additional information are encrypted in the client's secret key. The
+KRB_AS_REP message contains information which can be used to detect replays,
+and to associate it with the message to which it replies. Various errors can
+occur; these are indicated by an error response (KRB_ERROR) instead of the
+KRB_AS_REP response. The error message is not encrypted. The KRB_ERROR
+message contains information which can be used to associate it with the
+message to which it replies. The lack of encryption in the KRB_ERROR message
+precludes the ability to detect replays, fabrications, or modifications of
+such messages.
+
+Without preautentication, the authentication server does not know whether
+the client is actually the principal named in the request. It simply sends a
+reply without knowing or caring whether they are the same. This is
+acceptable because nobody but the principal whose identity was given in the
+request will be able to use the reply. Its critical information is encrypted
+in that principal's key. The initial request supports an optional field that
+can be used to pass additional information that might be needed for the
+initial exchange. This field may be used for preauthentication as described
+in section [hl<>].
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+3.1.1. Generation of KRB_AS_REQ message
+
+The client may specify a number of options in the initial request. Among
+these options are whether pre-authentication is to be performed; whether the
+requested ticket is to be renewable, proxiable, or forwardable; whether it
+should be postdated or allow postdating of derivative tickets; and whether a
+renewable ticket will be accepted in lieu of a non-renewable ticket if the
+requested ticket expiration date cannot be satisfied by a non-renewable
+ticket (due to configuration constraints; see section 4). See section A.1
+for pseudocode.
+
+The client prepares the KRB_AS_REQ message and sends it to the KDC.
+
+3.1.2. Receipt of KRB_AS_REQ message
+
+If all goes well, processing the KRB_AS_REQ message will result in the
+creation of a ticket for the client to present to the server. The format for
+the ticket is described in section 5.3.1. The contents of the ticket are
+determined as follows.
+
+3.1.3. Generation of KRB_AS_REP message
+
+The authentication server looks up the client and server principals named in
+the KRB_AS_REQ in its database, extracting their respective keys. If
+required, the server pre-authenticates the request, and if the
+pre-authentication check fails, an error message with the code
+KDC_ERR_PREAUTH_FAILED is returned. If the server cannot accommodate the
+requested encryption type, an error message with code KDC_ERR_ETYPE_NOSUPP
+is returned. Otherwise it generates a 'random' session key[7].
+
+If there are multiple encryption keys registered for a client in the
+Kerberos database (or if the key registered supports multiple encryption
+types; e.g. DES-CBC-CRC and DES-CBC-MD5), then the etype field from the AS
+request is used by the KDC to select the encryption method to be used for
+encrypting the response to the client. If there is more than one supported,
+strong encryption type in the etype list, the first valid etype for which an
+encryption key is available is used. The encryption method used to respond
+to a TGS request is taken from the keytype of the session key found in the
+ticket granting ticket. [***I will change the example keytypes to be 3DES
+based examples 7/14***]
+
+When the etype field is present in a KDC request, whether an AS or TGS
+request, the KDC will attempt to assign the type of the random session key
+from the list of methods in the etype field. The KDC will select the
+appropriate type using the list of methods provided together with
+information from the Kerberos database indicating acceptable encryption
+methods for the application server. The KDC will not issue tickets with a
+weak session key encryption type.
+
+If the requested start time is absent, indicates a time in the past, or is
+within the window of acceptable clock skew for the KDC and the POSTDATE
+option has not been specified, then the start time of the ticket is set to
+the authentication server's current time. If it indicates a time in the
+future beyond the acceptable clock skew, but the POSTDATED option has not
+been specified then the error KDC_ERR_CANNOT_POSTDATE is returned. Otherwise
+the requested start time is checked against the policy of the local realm
+(the administrator might decide to prohibit certain types or ranges of
+postdated tickets), and if acceptable, the ticket's start time is set as
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+requested and the INVALID flag is set in the new ticket. The postdated
+ticket must be validated before use by presenting it to the KDC after the
+start time has been reached.
+
+The expiration time of the ticket will be set to the minimum of the
+following:
+
+ * The expiration time (endtime) requested in the KRB_AS_REQ message.
+ * The ticket's start time plus the maximum allowable lifetime associated
+ with the client principal (the authentication server's database
+ includes a maximum ticket lifetime field in each principal's record;
+ see section 4).
+ * The ticket's start time plus the maximum allowable lifetime associated
+ with the server principal.
+ * The ticket's start time plus the maximum lifetime set by the policy of
+ the local realm.
+
+If the requested expiration time minus the start time (as determined above)
+is less than a site-determined minimum lifetime, an error message with code
+KDC_ERR_NEVER_VALID is returned. If the requested expiration time for the
+ticket exceeds what was determined as above, and if the 'RENEWABLE-OK'
+option was requested, then the 'RENEWABLE' flag is set in the new ticket,
+and the renew-till value is set as if the 'RENEWABLE' option were requested
+(the field and option names are described fully in section 5.4.1).
+
+If the RENEWABLE option has been requested or if the RENEWABLE-OK option has
+been set and a renewable ticket is to be issued, then the renew-till field
+is set to the minimum of:
+
+ * Its requested value.
+ * The start time of the ticket plus the minimum of the two maximum
+ renewable lifetimes associated with the principals' database entries.
+ * The start time of the ticket plus the maximum renewable lifetime set by
+ the policy of the local realm.
+
+The flags field of the new ticket will have the following options set if
+they have been requested and if the policy of the local realm allows:
+FORWARDABLE, MAY-POSTDATE, POSTDATED, PROXIABLE, RENEWABLE. If the new
+ticket is post-dated (the start time is in the future), its INVALID flag
+will also be set.
+
+If all of the above succeed, the server formats a KRB_AS_REP message (see
+section 5.4.2), copying the addresses in the request into the caddr of the
+response, placing any required pre-authentication data into the padata of
+the response, and encrypts the ciphertext part in the client's key using the
+requested encryption method, and sends it to the client. See section A.2 for
+pseudocode.
+
+3.1.4. Generation of KRB_ERROR message
+
+Several errors can occur, and the Authentication Server responds by
+returning an error message, KRB_ERROR, to the client, with the error-code
+and e-text fields set to appropriate values. The error message contents and
+details are described in Section 5.9.1.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+3.1.5. Receipt of KRB_AS_REP message
+
+If the reply message type is KRB_AS_REP, then the client verifies that the
+cname and crealm fields in the cleartext portion of the reply match what it
+requested. If any padata fields are present, they may be used to derive the
+proper secret key to decrypt the message. The client decrypts the encrypted
+part of the response using its secret key, verifies that the nonce in the
+encrypted part matches the nonce it supplied in its request (to detect
+replays). It also verifies that the sname and srealm in the response match
+those in the request (or are otherwise expected values), and that the host
+address field is also correct. It then stores the ticket, session key, start
+and expiration times, and other information for later use. The
+key-expiration field from the encrypted part of the response may be checked
+to notify the user of impending key expiration (the client program could
+then suggest remedial action, such as a password change). See section A.3
+for pseudocode.
+
+Proper decryption of the KRB_AS_REP message is not sufficient to verify the
+identity of the user; the user and an attacker could cooperate to generate a
+KRB_AS_REP format message which decrypts properly but is not from the proper
+KDC. If the host wishes to verify the identity of the user, it must require
+the user to present application credentials which can be verified using a
+securely-stored secret key for the host. If those credentials can be
+verified, then the identity of the user can be assured.
+
+3.1.6. Receipt of KRB_ERROR message
+
+If the reply message type is KRB_ERROR, then the client interprets it as an
+error and performs whatever application-specific tasks are necessary to
+recover.
+
+3.2. The Client/Server Authentication Exchange
+
+ Summary
+Message direction Message type Section
+Client to Application server KRB_AP_REQ 5.5.1
+[optional] Application server to client KRB_AP_REP or 5.5.2
+ KRB_ERROR 5.9.1
+
+The client/server authentication (CS) exchange is used by network
+applications to authenticate the client to the server and vice versa. The
+client must have already acquired credentials for the server using the AS or
+TGS exchange.
+
+3.2.1. The KRB_AP_REQ message
+
+The KRB_AP_REQ contains authentication information which should be part of
+the first message in an authenticated transaction. It contains a ticket, an
+authenticator, and some additional bookkeeping information (see section
+5.5.1 for the exact format). The ticket by itself is insufficient to
+authenticate a client, since tickets are passed across the network in
+cleartext[DS90], so the authenticator is used to prevent invalid replay of
+tickets by proving to the server that the client knows the session key of
+the ticket and thus is entitled to use the ticket. The KRB_AP_REQ message is
+referred to elsewhere as the 'authentication header.'
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+3.2.2. Generation of a KRB_AP_REQ message
+
+When a client wishes to initiate authentication to a server, it obtains
+(either through a credentials cache, the AS exchange, or the TGS exchange) a
+ticket and session key for the desired service. The client may re-use any
+tickets it holds until they expire. To use a ticket the client constructs a
+new Authenticator from the the system time, its name, and optionally an
+application specific checksum, an initial sequence number to be used in
+KRB_SAFE or KRB_PRIV messages, and/or a session subkey to be used in
+negotiations for a session key unique to this particular session.
+Authenticators may not be re-used and will be rejected if replayed to a
+server[LGDSR87]. If a sequence number is to be included, it should be
+randomly chosen so that even after many messages have been exchanged it is
+not likely to collide with other sequence numbers in use.
+
+The client may indicate a requirement of mutual authentication or the use of
+a session-key based ticket by setting the appropriate flag(s) in the
+ap-options field of the message.
+
+The Authenticator is encrypted in the session key and combined with the
+ticket to form the KRB_AP_REQ message which is then sent to the end server
+along with any additional application-specific information. See section A.9
+for pseudocode.
+
+3.2.3. Receipt of KRB_AP_REQ message
+
+Authentication is based on the server's current time of day (clocks must be
+loosely synchronized), the authenticator, and the ticket. Several errors are
+possible. If an error occurs, the server is expected to reply to the client
+with a KRB_ERROR message. This message may be encapsulated in the
+application protocol if its 'raw' form is not acceptable to the protocol.
+The format of error messages is described in section 5.9.1.
+
+The algorithm for verifying authentication information is as follows. If the
+message type is not KRB_AP_REQ, the server returns the KRB_AP_ERR_MSG_TYPE
+error. If the key version indicated by the Ticket in the KRB_AP_REQ is not
+one the server can use (e.g., it indicates an old key, and the server no
+longer possesses a copy of the old key), the KRB_AP_ERR_BADKEYVER error is
+returned. If the USE-SESSION-KEY flag is set in the ap-options field, it
+indicates to the server that the ticket is encrypted in the session key from
+the server's ticket-granting ticket rather than its secret key[10]. Since it
+is possible for the server to be registered in multiple realms, with
+different keys in each, the srealm field in the unencrypted portion of the
+ticket in the KRB_AP_REQ is used to specify which secret key the server
+should use to decrypt that ticket. The KRB_AP_ERR_NOKEY error code is
+returned if the server doesn't have the proper key to decipher the ticket.
+
+The ticket is decrypted using the version of the server's key specified by
+the ticket. If the decryption routines detect a modification of the ticket
+(each encryption system must provide safeguards to detect modified
+ciphertext; see section 6), the KRB_AP_ERR_BAD_INTEGRITY error is returned
+(chances are good that different keys were used to encrypt and decrypt).
+
+The authenticator is decrypted using the session key extracted from the
+decrypted ticket. If decryption shows it to have been modified, the
+KRB_AP_ERR_BAD_INTEGRITY error is returned. The name and realm of the client
+from the ticket are compared against the same fields in the authenticator.
+If they don't match, the KRB_AP_ERR_BADMATCH error is returned (they might
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+not match, for example, if the wrong session key was used to encrypt the
+authenticator). The addresses in the ticket (if any) are then searched for
+an address matching the operating-system reported address of the client. If
+no match is found or the server insists on ticket addresses but none are
+present in the ticket, the KRB_AP_ERR_BADADDR error is returned.
+
+If the local (server) time and the client time in the authenticator differ
+by more than the allowable clock skew (e.g., 5 minutes), the KRB_AP_ERR_SKEW
+error is returned. If the server name, along with the client name, time and
+microsecond fields from the Authenticator match any recently-seen such
+tuples, the KRB_AP_ERR_REPEAT error is returned[11]. The server must
+remember any authenticator presented within the allowable clock skew, so
+that a replay attempt is guaranteed to fail. If a server loses track of any
+authenticator presented within the allowable clock skew, it must reject all
+requests until the clock skew interval has passed. This assures that any
+lost or re-played authenticators will fall outside the allowable clock skew
+and can no longer be successfully replayed (If this is not done, an attacker
+could conceivably record the ticket and authenticator sent over the network
+to a server, then disable the client's host, pose as the disabled host, and
+replay the ticket and authenticator to subvert the authentication.). If a
+sequence number is provided in the authenticator, the server saves it for
+later use in processing KRB_SAFE and/or KRB_PRIV messages. If a subkey is
+present, the server either saves it for later use or uses it to help
+generate its own choice for a subkey to be returned in a KRB_AP_REP message.
+
+The server computes the age of the ticket: local (server) time minus the
+start time inside the Ticket. If the start time is later than the current
+time by more than the allowable clock skew or if the INVALID flag is set in
+the ticket, the KRB_AP_ERR_TKT_NYV error is returned. Otherwise, if the
+current time is later than end time by more than the allowable clock skew,
+the KRB_AP_ERR_TKT_EXPIRED error is returned.
+
+If all these checks succeed without an error, the server is assured that the
+client possesses the credentials of the principal named in the ticket and
+thus, the client has been authenticated to the server. See section A.10 for
+pseudocode.
+
+Passing these checks provides only authentication of the named principal; it
+does not imply authorization to use the named service. Applications must
+make a separate authorization decisions based upon the authenticated name of
+the user, the requested operation, local acces control information such as
+that contained in a .k5login or .k5users file, and possibly a separate
+distributed authorization service.
+
+3.2.4. Generation of a KRB_AP_REP message
+
+Typically, a client's request will include both the authentication
+information and its initial request in the same message, and the server need
+not explicitly reply to the KRB_AP_REQ. However, if mutual authentication
+(not only authenticating the client to the server, but also the server to
+the client) is being performed, the KRB_AP_REQ message will have
+MUTUAL-REQUIRED set in its ap-options field, and a KRB_AP_REP message is
+required in response. As with the error message, this message may be
+encapsulated in the application protocol if its "raw" form is not acceptable
+to the application's protocol. The timestamp and microsecond field used in
+the reply must be the client's timestamp and microsecond field (as provided
+in the authenticator)[12]. If a sequence number is to be included, it should
+be randomly chosen as described above for the authenticator. A subkey may be
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+included if the server desires to negotiate a different subkey. The
+KRB_AP_REP message is encrypted in the session key extracted from the
+ticket. See section A.11 for pseudocode.
+
+3.2.5. Receipt of KRB_AP_REP message
+
+If a KRB_AP_REP message is returned, the client uses the session key from
+the credentials obtained for the server[13] to decrypt the message, and
+verifies that the timestamp and microsecond fields match those in the
+Authenticator it sent to the server. If they match, then the client is
+assured that the server is genuine. The sequence number and subkey (if
+present) are retained for later use. See section A.12 for pseudocode.
+
+3.2.6. Using the encryption key
+
+After the KRB_AP_REQ/KRB_AP_REP exchange has occurred, the client and server
+share an encryption key which can be used by the application. The 'true
+session key' to be used for KRB_PRIV, KRB_SAFE, or other
+application-specific uses may be chosen by the application based on the
+subkeys in the KRB_AP_REP message and the authenticator[14]. In some cases,
+the use of this session key will be implicit in the protocol; in others the
+method of use must be chosen from several alternatives. We leave the
+protocol negotiations of how to use the key (e.g. selecting an encryption or
+checksum type) to the application programmer; the Kerberos protocol does not
+constrain the implementation options, but an example of how this might be
+done follows.
+
+One way that an application may choose to negotiate a key to be used for
+subequent integrity and privacy protection is for the client to propose a
+key in the subkey field of the authenticator. The server can then choose a
+key using the proposed key from the client as input, returning the new
+subkey in the subkey field of the application reply. This key could then be
+used for subsequent communication. To make this example more concrete, if
+the encryption method in use required a 56 bit key, and for whatever reason,
+one of the parties was prevented from using a key with more than 40 unknown
+bits, this method would allow the the party which is prevented from using
+more than 40 bits to either propose (if the client) an initial key with a
+known quantity for 16 of those bits, or to mask 16 of the bits (if the
+server) with the known quantity. The application implementor is warned,
+however, that this is only an example, and that an analysis of the
+particular crytosystem to be used, and the reasons for limiting the key
+length, must be made before deciding whether it is acceptable to mask bits
+of the key.
+
+With both the one-way and mutual authentication exchanges, the peers should
+take care not to send sensitive information to each other without proper
+assurances. In particular, applications that require privacy or integrity
+should use the KRB_AP_REP response from the server to client to assure both
+client and server of their peer's identity. If an application protocol
+requires privacy of its messages, it can use the KRB_PRIV message (section
+3.5). The KRB_SAFE message (section 3.4) can be used to assure integrity.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+3.3. The Ticket-Granting Service (TGS) Exchange
+
+ Summary
+ Message direction Message type Section
+ 1. Client to Kerberos KRB_TGS_REQ 5.4.1
+ 2. Kerberos to client KRB_TGS_REP or 5.4.2
+ KRB_ERROR 5.9.1
+
+The TGS exchange between a client and the Kerberos Ticket-Granting Server is
+initiated by a client when it wishes to obtain authentication credentials
+for a given server (which might be registered in a remote realm), when it
+wishes to renew or validate an existing ticket, or when it wishes to obtain
+a proxy ticket. In the first case, the client must already have acquired a
+ticket for the Ticket-Granting Service using the AS exchange (the
+ticket-granting ticket is usually obtained when a client initially
+authenticates to the system, such as when a user logs in). The message
+format for the TGS exchange is almost identical to that for the AS exchange.
+The primary difference is that encryption and decryption in the TGS exchange
+does not take place under the client's key. Instead, the session key from
+the ticket-granting ticket or renewable ticket, or sub-session key from an
+Authenticator is used. As is the case for all application servers, expired
+tickets are not accepted by the TGS, so once a renewable or ticket-granting
+ticket expires, the client must use a separate exchange to obtain valid
+tickets.
+
+The TGS exchange consists of two messages: A request (KRB_TGS_REQ) from the
+client to the Kerberos Ticket-Granting Server, and a reply (KRB_TGS_REP or
+KRB_ERROR). The KRB_TGS_REQ message includes information authenticating the
+client plus a request for credentials. The authentication information
+consists of the authentication header (KRB_AP_REQ) which includes the
+client's previously obtained ticket-granting, renewable, or invalid ticket.
+In the ticket-granting ticket and proxy cases, the request may include one
+or more of: a list of network addresses, a collection of typed authorization
+data to be sealed in the ticket for authorization use by the application
+server, or additional tickets (the use of which are described later). The
+TGS reply (KRB_TGS_REP) contains the requested credentials, encrypted in the
+session key from the ticket-granting ticket or renewable ticket, or if
+present, in the sub-session key from the Authenticator (part of the
+authentication header). The KRB_ERROR message contains an error code and
+text explaining what went wrong. The KRB_ERROR message is not encrypted. The
+KRB_TGS_REP message contains information which can be used to detect
+replays, and to associate it with the message to which it replies. The
+KRB_ERROR message also contains information which can be used to associate
+it with the message to which it replies, but the lack of encryption in the
+KRB_ERROR message precludes the ability to detect replays or fabrications of
+such messages.
+
+3.3.1. Generation of KRB_TGS_REQ message
+
+Before sending a request to the ticket-granting service, the client must
+determine in which realm the application server is registered[15]. If the
+client does not already possess a ticket-granting ticket for the appropriate
+realm, then one must be obtained. This is first attempted by requesting a
+ticket-granting ticket for the destination realm from a Kerberos server for
+which the client does posess a ticket-granting ticket (using the KRB_TGS_REQ
+message recursively). The Kerberos server may return a TGT for the desired
+realm in which case one can proceed. Alternatively, the Kerberos server may
+return a TGT for a realm which is 'closer' to the desired realm (further
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+along the standard hierarchical path), in which case this step must be
+repeated with a Kerberos server in the realm specified in the returned TGT.
+If neither are returned, then the request must be retried with a Kerberos
+server for a realm higher in the hierarchy. This request will itself require
+a ticket-granting ticket for the higher realm which must be obtained by
+recursively applying these directions.
+
+Once the client obtains a ticket-granting ticket for the appropriate realm,
+it determines which Kerberos servers serve that realm, and contacts one. The
+list might be obtained through a configuration file or network service or it
+may be generated from the name of the realm; as long as the secret keys
+exchanged by realms are kept secret, only denial of service results from
+using a false Kerberos server.
+
+As in the AS exchange, the client may specify a number of options in the
+KRB_TGS_REQ message. The client prepares the KRB_TGS_REQ message, providing
+an authentication header as an element of the padata field, and including
+the same fields as used in the KRB_AS_REQ message along with several
+optional fields: the enc-authorization-data field for application server use
+and additional tickets required by some options.
+
+In preparing the authentication header, the client can select a sub-session
+key under which the response from the Kerberos server will be encrypted[16].
+If the sub-session key is not specified, the session key from the
+ticket-granting ticket will be used. If the enc-authorization-data is
+present, it must be encrypted in the sub-session key, if present, from the
+authenticator portion of the authentication header, or if not present, using
+the session key from the ticket-granting ticket.
+
+Once prepared, the message is sent to a Kerberos server for the destination
+realm. See section A.5 for pseudocode.
+
+3.3.2. Receipt of KRB_TGS_REQ message
+
+The KRB_TGS_REQ message is processed in a manner similar to the KRB_AS_REQ
+message, but there are many additional checks to be performed. First, the
+Kerberos server must determine which server the accompanying ticket is for
+and it must select the appropriate key to decrypt it. For a normal
+KRB_TGS_REQ message, it will be for the ticket granting service, and the
+TGS's key will be used. If the TGT was issued by another realm, then the
+appropriate inter-realm key must be used. If the accompanying ticket is not
+a ticket granting ticket for the current realm, but is for an application
+server in the current realm, the RENEW, VALIDATE, or PROXY options are
+specified in the request, and the server for which a ticket is requested is
+the server named in the accompanying ticket, then the KDC will decrypt the
+ticket in the authentication header using the key of the server for which it
+was issued. If no ticket can be found in the padata field, the
+KDC_ERR_PADATA_TYPE_NOSUPP error is returned.
+
+Once the accompanying ticket has been decrypted, the user-supplied checksum
+in the Authenticator must be verified against the contents of the request,
+and the message rejected if the checksums do not match (with an error code
+of KRB_AP_ERR_MODIFIED) or if the checksum is not keyed or not
+collision-proof (with an error code of KRB_AP_ERR_INAPP_CKSUM). If the
+checksum type is not supported, the KDC_ERR_SUMTYPE_NOSUPP error is
+returned. If the authorization-data are present, they are decrypted using
+the sub-session key from the Authenticator.
+
+If any of the decryptions indicate failed integrity checks, the
+KRB_AP_ERR_BAD_INTEGRITY error is returned.
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+3.3.3. Generation of KRB_TGS_REP message
+
+The KRB_TGS_REP message shares its format with the KRB_AS_REP (KRB_KDC_REP),
+but with its type field set to KRB_TGS_REP. The detailed specification is in
+section 5.4.2.
+
+The response will include a ticket for the requested server. The Kerberos
+database is queried to retrieve the record for the requested server
+(including the key with which the ticket will be encrypted). If the request
+is for a ticket granting ticket for a remote realm, and if no key is shared
+with the requested realm, then the Kerberos server will select the realm
+"closest" to the requested realm with which it does share a key, and use
+that realm instead. This is the only case where the response from the KDC
+will be for a different server than that requested by the client.
+
+By default, the address field, the client's name and realm, the list of
+transited realms, the time of initial authentication, the expiration time,
+and the authorization data of the newly-issued ticket will be copied from
+the ticket-granting ticket (TGT) or renewable ticket. If the transited field
+needs to be updated, but the transited type is not supported, the
+KDC_ERR_TRTYPE_NOSUPP error is returned.
+
+If the request specifies an endtime, then the endtime of the new ticket is
+set to the minimum of (a) that request, (b) the endtime from the TGT, and
+(c) the starttime of the TGT plus the minimum of the maximum life for the
+application server and the maximum life for the local realm (the maximum
+life for the requesting principal was already applied when the TGT was
+issued). If the new ticket is to be a renewal, then the endtime above is
+replaced by the minimum of (a) the value of the renew_till field of the
+ticket and (b) the starttime for the new ticket plus the life
+(endtime-starttime) of the old ticket.
+
+If the FORWARDED option has been requested, then the resulting ticket will
+contain the addresses specified by the client. This option will only be
+honored if the FORWARDABLE flag is set in the TGT. The PROXY option is
+similar; the resulting ticket will contain the addresses specified by the
+client. It will be honored only if the PROXIABLE flag in the TGT is set. The
+PROXY option will not be honored on requests for additional ticket-granting
+tickets.
+
+If the requested start time is absent, indicates a time in the past, or is
+within the window of acceptable clock skew for the KDC and the POSTDATE
+option has not been specified, then the start time of the ticket is set to
+the authentication server's current time. If it indicates a time in the
+future beyond the acceptable clock skew, but the POSTDATED option has not
+been specified or the MAY-POSTDATE flag is not set in the TGT, then the
+error KDC_ERR_CANNOT_POSTDATE is returned. Otherwise, if the ticket-granting
+ticket has the MAY-POSTDATE flag set, then the resulting ticket will be
+postdated and the requested starttime is checked against the policy of the
+local realm. If acceptable, the ticket's start time is set as requested, and
+the INVALID flag is set. The postdated ticket must be validated before use
+by presenting it to the KDC after the starttime has been reached. However,
+in no case may the starttime, endtime, or renew-till time of a newly-issued
+postdated ticket extend beyond the renew-till time of the ticket-granting
+ticket.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+If the ENC-TKT-IN-SKEY option has been specified and an additional ticket
+has been included in the request, the KDC will decrypt the additional ticket
+using the key for the server to which the additional ticket was issued and
+verify that it is a ticket-granting ticket. If the name of the requested
+server is missing from the request, the name of the client in the additional
+ticket will be used. Otherwise the name of the requested server will be
+compared to the name of the client in the additional ticket and if
+different, the request will be rejected. If the request succeeds, the
+session key from the additional ticket will be used to encrypt the new
+ticket that is issued instead of using the key of the server for which the
+new ticket will be used[17].
+
+If the name of the server in the ticket that is presented to the KDC as part
+of the authentication header is not that of the ticket-granting server
+itself, the server is registered in the realm of the KDC, and the RENEW
+option is requested, then the KDC will verify that the RENEWABLE flag is set
+in the ticket, that the INVALID flag is not set in the ticket, and that the
+renew_till time is still in the future. If the VALIDATE option is rqeuested,
+the KDC will check that the starttime has passed and the INVALID flag is
+set. If the PROXY option is requested, then the KDC will check that the
+PROXIABLE flag is set in the ticket. If the tests succeed, and the ticket
+passes the hotlist check described in the next paragraph, the KDC will issue
+the appropriate new ticket.
+
+3.3.3.1. Checking for revoked tickets
+
+Whenever a request is made to the ticket-granting server, the presented
+ticket(s) is(are) checked against a hot-list of tickets which have been
+canceled. This hot-list might be implemented by storing a range of issue
+timestamps for 'suspect tickets'; if a presented ticket had an authtime in
+that range, it would be rejected. In this way, a stolen ticket-granting
+ticket or renewable ticket cannot be used to gain additional tickets
+(renewals or otherwise) once the theft has been reported. Any normal ticket
+obtained before it was reported stolen will still be valid (because they
+require no interaction with the KDC), but only until their normal expiration
+time.
+
+The ciphertext part of the response in the KRB_TGS_REP message is encrypted
+in the sub-session key from the Authenticator, if present, or the session
+key key from the ticket-granting ticket. It is not encrypted using the
+client's secret key. Furthermore, the client's key's expiration date and the
+key version number fields are left out since these values are stored along
+with the client's database record, and that record is not needed to satisfy
+a request based on a ticket-granting ticket. See section A.6 for pseudocode.
+
+3.3.3.2. Encoding the transited field
+
+If the identity of the server in the TGT that is presented to the KDC as
+part of the authentication header is that of the ticket-granting service,
+but the TGT was issued from another realm, the KDC will look up the
+inter-realm key shared with that realm and use that key to decrypt the
+ticket. If the ticket is valid, then the KDC will honor the request, subject
+to the constraints outlined above in the section describing the AS exchange.
+The realm part of the client's identity will be taken from the
+ticket-granting ticket. The name of the realm that issued the
+ticket-granting ticket will be added to the transited field of the ticket to
+be issued. This is accomplished by reading the transited field from the
+ticket-granting ticket (which is treated as an unordered set of realm
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+names), adding the new realm to the set, then constructing and writing out
+its encoded (shorthand) form (this may involve a rearrangement of the
+existing encoding).
+
+Note that the ticket-granting service does not add the name of its own
+realm. Instead, its responsibility is to add the name of the previous realm.
+This prevents a malicious Kerberos server from intentionally leaving out its
+own name (it could, however, omit other realms' names).
+
+The names of neither the local realm nor the principal's realm are to be
+included in the transited field. They appear elsewhere in the ticket and
+both are known to have taken part in authenticating the principal. Since the
+endpoints are not included, both local and single-hop inter-realm
+authentication result in a transited field that is empty.
+
+Because the name of each realm transited is added to this field, it might
+potentially be very long. To decrease the length of this field, its contents
+are encoded. The initially supported encoding is optimized for the normal
+case of inter-realm communication: a hierarchical arrangement of realms
+using either domain or X.500 style realm names. This encoding (called
+DOMAIN-X500-COMPRESS) is now described.
+
+Realm names in the transited field are separated by a ",". The ",", "\",
+trailing "."s, and leading spaces (" ") are special characters, and if they
+are part of a realm name, they must be quoted in the transited field by
+preced- ing them with a "\".
+
+A realm name ending with a "." is interpreted as being prepended to the
+previous realm. For example, we can encode traversal of EDU, MIT.EDU,
+ATHENA.MIT.EDU, WASHINGTON.EDU, and CS.WASHINGTON.EDU as:
+
+ "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS.".
+
+Note that if ATHENA.MIT.EDU, or CS.WASHINGTON.EDU were end-points, that they
+would not be included in this field, and we would have:
+
+ "EDU,MIT.,WASHINGTON.EDU"
+
+A realm name beginning with a "/" is interpreted as being appended to the
+previous realm[18]. If it is to stand by itself, then it should be preceded
+by a space (" "). For example, we can encode traversal of /COM/HP/APOLLO,
+/COM/HP, /COM, and /COM/DEC as:
+
+ "/COM,/HP,/APOLLO, /COM/DEC".
+
+Like the example above, if /COM/HP/APOLLO and /COM/DEC are endpoints, they
+they would not be included in this field, and we would have:
+
+ "/COM,/HP"
+
+A null subfield preceding or following a "," indicates that all realms
+between the previous realm and the next realm have been traversed[19]. Thus,
+"," means that all realms along the path between the client and the server
+have been traversed. ",EDU, /COM," means that that all realms from the
+client's realm up to EDU (in a domain style hierarchy) have been traversed,
+and that everything from /COM down to the server's realm in an X.500 style
+has also been traversed. This could occur if the EDU realm in one hierarchy
+shares an inter-realm key directly with the /COM realm in another hierarchy.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+3.3.4. Receipt of KRB_TGS_REP message
+
+When the KRB_TGS_REP is received by the client, it is processed in the same
+manner as the KRB_AS_REP processing described above. The primary difference
+is that the ciphertext part of the response must be decrypted using the
+session key from the ticket-granting ticket rather than the client's secret
+key. See section A.7 for pseudocode.
+
+3.4. The KRB_SAFE Exchange
+
+The KRB_SAFE message may be used by clients requiring the ability to detect
+modifications of messages they exchange. It achieves this by including a
+keyed collision-proof checksum of the user data and some control
+information. The checksum is keyed with an encryption key (usually the last
+key negotiated via subkeys, or the session key if no negotiation has
+occured).
+
+3.4.1. Generation of a KRB_SAFE message
+
+When an application wishes to send a KRB_SAFE message, it collects its data
+and the appropriate control information and computes a checksum over them.
+The checksum algorithm should be a keyed one-way hash function (such as the
+RSA- MD5-DES checksum algorithm specified in section 6.4.5, or the DES MAC),
+generated using the sub-session key if present, or the session key.
+Different algorithms may be selected by changing the checksum type in the
+message. Unkeyed or non-collision-proof checksums are not suitable for this
+use.
+
+The control information for the KRB_SAFE message includes both a timestamp
+and a sequence number. The designer of an application using the KRB_SAFE
+message must choose at least one of the two mechanisms. This choice should
+be based on the needs of the application protocol.
+
+Sequence numbers are useful when all messages sent will be received by one's
+peer. Connection state is presently required to maintain the session key, so
+maintaining the next sequence number should not present an additional
+problem.
+
+If the application protocol is expected to tolerate lost messages without
+them being resent, the use of the timestamp is the appropriate replay
+detection mechanism. Using timestamps is also the appropriate mechanism for
+multi-cast protocols where all of one's peers share a common sub-session
+key, but some messages will be sent to a subset of one's peers.
+
+After computing the checksum, the client then transmits the information and
+checksum to the recipient in the message format specified in section 5.6.1.
+
+3.4.2. Receipt of KRB_SAFE message
+
+When an application receives a KRB_SAFE message, it verifies it as follows.
+If any error occurs, an error code is reported for use by the application.
+
+The message is first checked by verifying that the protocol version and type
+fields match the current version and KRB_SAFE, respectively. A mismatch
+generates a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error. The
+application verifies that the checksum used is a collision-proof keyed
+checksum, and if it is not, a KRB_AP_ERR_INAPP_CKSUM error is generated. If
+the sender's address was included in the control information, the recipient
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+verifies that the operating system's report of the sender's address matches
+the sender's address in the message, and (if a recipient address is
+specified or the recipient requires an address) that one of the recipient's
+addresses appears as the recipient's address in the message. A failed match
+for either case generates a KRB_AP_ERR_BADADDR error. Then the timestamp and
+usec and/or the sequence number fields are checked. If timestamp and usec
+are expected and not present, or they are present but not current, the
+KRB_AP_ERR_SKEW error is generated. If the server name, along with the
+client name, time and microsecond fields from the Authenticator match any
+recently-seen (sent or received[20] ) such tuples, the KRB_AP_ERR_REPEAT
+error is generated. If an incorrect sequence number is included, or a
+sequence number is expected but not present, the KRB_AP_ERR_BADORDER error
+is generated. If neither a time-stamp and usec or a sequence number is
+present, a KRB_AP_ERR_MODIFIED error is generated. Finally, the checksum is
+computed over the data and control information, and if it doesn't match the
+received checksum, a KRB_AP_ERR_MODIFIED error is generated.
+
+If all the checks succeed, the application is assured that the message was
+generated by its peer and was not modi- fied in transit.
+
+3.5. The KRB_PRIV Exchange
+
+The KRB_PRIV message may be used by clients requiring confidentiality and
+the ability to detect modifications of exchanged messages. It achieves this
+by encrypting the messages and adding control information.
+
+3.5.1. Generation of a KRB_PRIV message
+
+When an application wishes to send a KRB_PRIV message, it collects its data
+and the appropriate control information (specified in section 5.7.1) and
+encrypts them under an encryption key (usually the last key negotiated via
+subkeys, or the session key if no negotiation has occured). As part of the
+control information, the client must choose to use either a timestamp or a
+sequence number (or both); see the discussion in section 3.4.1 for
+guidelines on which to use. After the user data and control information are
+encrypted, the client transmits the ciphertext and some 'envelope'
+information to the recipient.
+
+3.5.2. Receipt of KRB_PRIV message
+
+When an application receives a KRB_PRIV message, it verifies it as follows.
+If any error occurs, an error code is reported for use by the application.
+
+The message is first checked by verifying that the protocol version and type
+fields match the current version and KRB_PRIV, respectively. A mismatch
+generates a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error. The
+application then decrypts the ciphertext and processes the resultant
+plaintext. If decryption shows the data to have been modified, a
+KRB_AP_ERR_BAD_INTEGRITY error is generated. If the sender's address was
+included in the control information, the recipient verifies that the
+operating system's report of the sender's address matches the sender's
+address in the message, and (if a recipient address is specified or the
+recipient requires an address) that one of the recipient's addresses appears
+as the recipient's address in the message. A failed match for either case
+generates a KRB_AP_ERR_BADADDR error. Then the timestamp and usec and/or the
+sequence number fields are checked. If timestamp and usec are expected and
+not present, or they are present but not current, the KRB_AP_ERR_SKEW error
+is generated. If the server name, along with the client name, time and
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+microsecond fields from the Authenticator match any recently-seen such
+tuples, the KRB_AP_ERR_REPEAT error is generated. If an incorrect sequence
+number is included, or a sequence number is expected but not present, the
+KRB_AP_ERR_BADORDER error is generated. If neither a time-stamp and usec or
+a sequence number is present, a KRB_AP_ERR_MODIFIED error is generated.
+
+If all the checks succeed, the application can assume the message was
+generated by its peer, and was securely transmitted (without intruders able
+to see the unencrypted contents).
+
+3.6. The KRB_CRED Exchange
+
+The KRB_CRED message may be used by clients requiring the ability to send
+Kerberos credentials from one host to another. It achieves this by sending
+the tickets together with encrypted data containing the session keys and
+other information associated with the tickets.
+
+3.6.1. Generation of a KRB_CRED message
+
+When an application wishes to send a KRB_CRED message it first (using the
+KRB_TGS exchange) obtains credentials to be sent to the remote host. It then
+constructs a KRB_CRED message using the ticket or tickets so obtained,
+placing the session key needed to use each ticket in the key field of the
+corresponding KrbCredInfo sequence of the encrypted part of the the KRB_CRED
+message.
+
+Other information associated with each ticket and obtained during the
+KRB_TGS exchange is also placed in the corresponding KrbCredInfo sequence in
+the encrypted part of the KRB_CRED message. The current time and, if
+specifically required by the application the nonce, s-address, and r-address
+fields, are placed in the encrypted part of the KRB_CRED message which is
+then encrypted under an encryption key previosuly exchanged in the KRB_AP
+exchange (usually the last key negotiated via subkeys, or the session key if
+no negotiation has occured).
+
+3.6.2. Receipt of KRB_CRED message
+
+When an application receives a KRB_CRED message, it verifies it. If any
+error occurs, an error code is reported for use by the application. The
+message is verified by checking that the protocol version and type fields
+match the current version and KRB_CRED, respectively. A mismatch generates a
+KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE error. The application then
+decrypts the ciphertext and processes the resultant plaintext. If decryption
+shows the data to have been modified, a KRB_AP_ERR_BAD_INTEGRITY error is
+generated.
+
+If present or required, the recipient verifies that the operating system's
+report of the sender's address matches the sender's address in the message,
+and that one of the recipient's addresses appears as the recipient's address
+in the message. A failed match for either case generates a
+KRB_AP_ERR_BADADDR error. The timestamp and usec fields (and the nonce field
+if required) are checked next. If the timestamp and usec are not present, or
+they are present but not current, the KRB_AP_ERR_SKEW error is generated.
+
+If all the checks succeed, the application stores each of the new tickets in
+its ticket cache together with the session key and other information in the
+corresponding KrbCredInfo sequence from the encrypted part of the KRB_CRED
+message.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+4. The Kerberos Database
+
+The Kerberos server must have access to a database contain- ing the
+principal identifiers and secret keys of principals to be authenticated[21].
+
+4.1. Database contents
+
+A database entry should contain at least the following fields:
+
+Field Value
+
+name Principal's identifier
+key Principal's secret key
+p_kvno Principal's key version
+max_life Maximum lifetime for Tickets
+max_renewable_life Maximum total lifetime for renewable Tickets
+
+The name field is an encoding of the principal's identifier. The key field
+contains an encryption key. This key is the principal's secret key. (The key
+can be encrypted before storage under a Kerberos "master key" to protect it
+in case the database is compromised but the master key is not. In that case,
+an extra field must be added to indicate the master key version used, see
+below.) The p_kvno field is the key version number of the principal's secret
+key. The max_life field contains the maximum allowable lifetime (endtime -
+starttime) for any Ticket issued for this principal. The max_renewable_life
+field contains the maximum allowable total lifetime for any renewable Ticket
+issued for this principal. (See section 3.1 for a description of how these
+lifetimes are used in determining the lifetime of a given Ticket.)
+
+A server may provide KDC service to several realms, as long as the database
+representation provides a mechanism to distinguish between principal records
+with identifiers which differ only in the realm name.
+
+When an application server's key changes, if the change is routine (i.e. not
+the result of disclosure of the old key), the old key should be retained by
+the server until all tickets that had been issued using that key have
+expired. Because of this, it is possible for several keys to be active for a
+single principal. Ciphertext encrypted in a principal's key is always tagged
+with the version of the key that was used for encryption, to help the
+recipient find the proper key for decryption.
+
+When more than one key is active for a particular principal, the principal
+will have more than one record in the Kerberos database. The keys and key
+version numbers will differ between the records (the rest of the fields may
+or may not be the same). Whenever Kerberos issues a ticket, or responds to a
+request for initial authentication, the most recent key (known by the
+Kerberos server) will be used for encryption. This is the key with the
+highest key version number.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+4.2. Additional fields
+
+Project Athena's KDC implementation uses additional fields in its database:
+
+Field Value
+
+K_kvno Kerberos' key version
+expiration Expiration date for entry
+attributes Bit field of attributes
+mod_date Timestamp of last modification
+mod_name Modifying principal's identifier
+
+The K_kvno field indicates the key version of the Kerberos master key under
+which the principal's secret key is encrypted.
+
+After an entry's expiration date has passed, the KDC will return an error to
+any client attempting to gain tickets as or for the principal. (A database
+may want to maintain two expiration dates: one for the principal, and one
+for the principal's current key. This allows password aging to work
+independently of the principal's expiration date. However, due to the
+limited space in the responses, the KDC must combine the key expiration and
+principal expiration date into a single value called 'key_exp', which is
+used as a hint to the user to take administrative action.)
+
+The attributes field is a bitfield used to govern the operations involving
+the principal. This field might be useful in conjunction with user
+registration procedures, for site-specific policy implementations (Project
+Athena currently uses it for their user registration process controlled by
+the system-wide database service, Moira [LGDSR87]), to identify whether a
+principal can play the role of a client or server or both, to note whether a
+server is appropriate trusted to recieve credentials delegated by a client,
+or to identify the 'string to key' conversion algorithm used for a
+principal's key[22]. Other bits are used to indicate that certain ticket
+options should not be allowed in tickets encrypted under a principal's key
+(one bit each): Disallow issuing postdated tickets, disallow issuing
+forwardable tickets, disallow issuing tickets based on TGT authentication,
+disallow issuing renewable tickets, disallow issuing proxiable tickets, and
+disallow issuing tickets for which the principal is the server.
+
+The mod_date field contains the time of last modification of the entry, and
+the mod_name field contains the name of the principal which last modified
+the entry.
+
+4.3. Frequently Changing Fields
+
+Some KDC implementations may wish to maintain the last time that a request
+was made by a particular principal. Information that might be maintained
+includes the time of the last request, the time of the last request for a
+ticket-granting ticket, the time of the last use of a ticket-granting
+ticket, or other times. This information can then be returned to the user in
+the last-req field (see section 5.2).
+
+Other frequently changing information that can be maintained is the latest
+expiration time for any tickets that have been issued using each key. This
+field would be used to indicate how long old keys must remain valid to allow
+the continued use of outstanding tickets.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+4.4. Site Constants
+
+The KDC implementation should have the following configurable constants or
+options, to allow an administrator to make and enforce policy decisions:
+
+ * The minimum supported lifetime (used to determine whether the
+ KDC_ERR_NEVER_VALID error should be returned). This constant should
+ reflect reasonable expectations of round-trip time to the KDC,
+ encryption/decryption time, and processing time by the client and
+ target server, and it should allow for a minimum 'useful' lifetime.
+ * The maximum allowable total (renewable) lifetime of a ticket
+ (renew_till - starttime).
+ * The maximum allowable lifetime of a ticket (endtime - starttime).
+ * Whether to allow the issue of tickets with empty address fields
+ (including the ability to specify that such tickets may only be issued
+ if the request specifies some authorization_data).
+ * Whether proxiable, forwardable, renewable or post-datable tickets are
+ to be issued.
+
+5. Message Specifications
+
+The following sections describe the exact contents and encoding of protocol
+messages and objects. The ASN.1 base definitions are presented in the first
+subsection. The remaining subsections specify the protocol objects (tickets
+and authenticators) and messages. Specification of encryption and checksum
+techniques, and the fields related to them, appear in section 6.
+
+Optional field in ASN.1 sequences
+
+For optional integer value and date fields in ASN.1 sequences where a
+default value has been specified, certain default values will not be allowed
+in the encoding because these values will always be represented through
+defaulting by the absence of the optional field. For example, one will not
+send a microsecond zero value because one must make sure that there is only
+one way to encode this value.
+
+Additional fields in ASN.1 sequences
+
+Implementations receiving Kerberos messages with additional fields present
+in ASN.1 sequences should carry the those fields through, unmodified, when
+the message is forwarded. Implementations should not drop such fields if the
+sequence is reencoded.
+
+5.1. ASN.1 Distinguished Encoding Representation
+
+All uses of ASN.1 in Kerberos shall use the Distinguished Encoding
+Representation of the data elements as described in the X.509 specification,
+section 8.7 [X509-88].
+
+5.3. ASN.1 Base Definitions
+
+The following ASN.1 base definitions are used in the rest of this section.
+Note that since the underscore character (_) is not permitted in ASN.1
+names, the hyphen (-) is used in its place for the purposes of ASN.1 names.
+
+Realm ::= GeneralString
+PrincipalName ::= SEQUENCE {
+ name-type[0] INTEGER,
+ name-string[1] SEQUENCE OF GeneralString
+}
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+Kerberos realms are encoded as GeneralStrings. Realms shall not contain a
+character with the code 0 (the ASCII NUL). Most realms will usually consist
+of several components separated by periods (.), in the style of Internet
+Domain Names, or separated by slashes (/) in the style of X.500 names.
+Acceptable forms for realm names are specified in section 7. A PrincipalName
+is a typed sequence of components consisting of the following sub-fields:
+
+name-type
+ This field specifies the type of name that follows. Pre-defined values
+ for this field are specified in section 7.2. The name-type should be
+ treated as a hint. Ignoring the name type, no two names can be the same
+ (i.e. at least one of the components, or the realm, must be different).
+ This constraint may be eliminated in the future.
+name-string
+ This field encodes a sequence of components that form a name, each
+ component encoded as a GeneralString. Taken together, a PrincipalName
+ and a Realm form a principal identifier. Most PrincipalNames will have
+ only a few components (typically one or two).
+
+KerberosTime ::= GeneralizedTime
+ -- Specifying UTC time zone (Z)
+
+The timestamps used in Kerberos are encoded as GeneralizedTimes. An encoding
+shall specify the UTC time zone (Z) and shall not include any fractional
+portions of the seconds. It further shall not include any separators.
+Example: The only valid format for UTC time 6 minutes, 27 seconds after 9 pm
+on 6 November 1985 is 19851106210627Z.
+
+HostAddress ::= SEQUENCE {
+ addr-type[0] INTEGER,
+ address[1] OCTET STRING
+}
+
+HostAddresses ::= SEQUENCE OF HostAddress
+
+The host adddress encodings consists of two fields:
+
+addr-type
+ This field specifies the type of address that follows. Pre-defined
+ values for this field are specified in section 8.1.
+address
+ This field encodes a single address of type addr-type.
+
+The two forms differ slightly. HostAddress contains exactly one address;
+HostAddresses contains a sequence of possibly many addresses.
+
+AuthorizationData ::= SEQUENCE OF SEQUENCE {
+ ad-type[0] INTEGER,
+ ad-data[1] OCTET STRING
+}
+
+ad-data
+ This field contains authorization data to be interpreted according to
+ the value of the corresponding ad-type field.
+ad-type
+ This field specifies the format for the ad-data subfield. All negative
+ values are reserved for local use. Non-negative values are reserved for
+ registered use.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+Each sequence of type and data is refered to as an authorization element.
+Elements may be application specific, however, there is a common set of
+recursive elements that should be understood by all implementations. These
+elements contain other elements embedded within them, and the interpretation
+of the encapsulating element determines which of the embedded elements must
+be interpreted, and which may be ignored. Definitions for these common
+elements may be found in Appendix B.
+
+TicketExtensions ::= SEQUENCE OF SEQUENCE {
+ te-type[0] INTEGER,
+ te-data[1] OCTET STRING
+}
+
+te-data
+ This field contains opaque data that must be caried with the ticket to
+ support extensions to the Kerberos protocol including but not limited
+ to some forms of inter-realm key exchange and plaintext authorization
+ data. See appendix C for some common uses of this field.
+te-type
+ This field specifies the format for the te-data subfield. All negative
+ values are reserved for local use. Non-negative values are reserved for
+ registered use.
+
+APOptions ::= BIT STRING
+ -- reserved(0),
+ -- use-session-key(1),
+ -- mutual-required(2)
+
+TicketFlags ::= BIT STRING
+ -- reserved(0),
+ -- forwardable(1),
+ -- forwarded(2),
+ -- proxiable(3),
+ -- proxy(4),
+ -- may-postdate(5),
+ -- postdated(6),
+ -- invalid(7),
+ -- renewable(8),
+ -- initial(9),
+ -- pre-authent(10),
+ -- hw-authent(11),
+ -- transited-policy-checked(12),
+ -- ok-as-delegate(13)
+
+KDCOptions ::= BIT STRING
+ -- reserved(0),
+ -- forwardable(1),
+ -- forwarded(2),
+ -- proxiable(3),
+ -- proxy(4),
+ -- allow-postdate(5),
+ -- postdated(6),
+ -- unused7(7),
+ -- renewable(8),
+ -- unused9(9),
+ -- unused10(10),
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ -- unused11(11),
+ -- unused12(12),
+ -- unused13(13),
+ -- disable-transited-check(26),
+ -- renewable-ok(27),
+ -- enc-tkt-in-skey(28),
+ -- renew(30),
+ -- validate(31)
+
+ASN.1 Bit strings have a length and a value. When used in Kerberos for the
+APOptions, TicketFlags, and KDCOptions, the length of the bit string on
+generated values should be the smallest number of bits needed to include the
+highest order bit that is set (1), but in no case less than 32 bits. The
+ASN.1 representation of the bit strings uses unnamed bits, with the meaning
+of the individual bits defined by the comments in the specification above.
+Implementations should accept values of bit strings of any length and treat
+the value of flags corresponding to bits beyond the end of the bit string as
+if the bit were reset (0). Comparison of bit strings of different length
+should treat the smaller string as if it were padded with zeros beyond the
+high order bits to the length of the longer string[23].
+
+LastReq ::= SEQUENCE OF SEQUENCE {
+ lr-type[0] INTEGER,
+ lr-value[1] KerberosTime
+}
+
+lr-type
+ This field indicates how the following lr-value field is to be
+ interpreted. Negative values indicate that the information pertains
+ only to the responding server. Non-negative values pertain to all
+ servers for the realm. If the lr-type field is zero (0), then no
+ information is conveyed by the lr-value subfield. If the absolute value
+ of the lr-type field is one (1), then the lr-value subfield is the time
+ of last initial request for a TGT. If it is two (2), then the lr-value
+ subfield is the time of last initial request. If it is three (3), then
+ the lr-value subfield is the time of issue for the newest
+ ticket-granting ticket used. If it is four (4), then the lr-value
+ subfield is the time of the last renewal. If it is five (5), then the
+ lr-value subfield is the time of last request (of any type). If it is
+ (6), then the lr-value subfield is the time when the password will
+ expire.
+lr-value
+ This field contains the time of the last request. the time must be
+ interpreted according to the contents of the accompanying lr-type
+ subfield.
+
+See section 6 for the definitions of Checksum, ChecksumType, EncryptedData,
+EncryptionKey, EncryptionType, and KeyType.
+
+5.3. Tickets and Authenticators
+
+This section describes the format and encryption parameters for tickets and
+authenticators. When a ticket or authenticator is included in a protocol
+message it is treated as an opaque object.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+5.3.1. Tickets
+
+A ticket is a record that helps a client authenticate to a service. A Ticket
+contains the following information:
+
+Ticket ::= [APPLICATION 1] SEQUENCE {
+ tkt-vno[0] INTEGER,
+ realm[1] Realm,
+ sname[2] PrincipalName,
+ enc-part[3] EncryptedData,
+ extensions[4] TicketExtensions OPTIONAL
+}
+
+-- Encrypted part of ticket
+EncTicketPart ::= [APPLICATION 3] SEQUENCE {
+ flags[0] TicketFlags,
+ key[1] EncryptionKey,
+ crealm[2] Realm,
+ cname[3] PrincipalName,
+ transited[4] TransitedEncoding,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ caddr[9] HostAddresses OPTIONAL,
+ authorization-data[10] AuthorizationData OPTIONAL
+}
+-- encoded Transited field
+TransitedEncoding ::= SEQUENCE {
+ tr-type[0] INTEGER, -- must be
+registered
+ contents[1] OCTET STRING
+}
+
+The encoding of EncTicketPart is encrypted in the key shared by Kerberos and
+the end server (the server's secret key). See section 6 for the format of
+the ciphertext.
+
+tkt-vno
+ This field specifies the version number for the ticket format. This
+ document describes version number 5.
+realm
+ This field specifies the realm that issued a ticket. It also serves to
+ identify the realm part of the server's principal identifier. Since a
+ Kerberos server can only issue tickets for servers within its realm,
+ the two will always be identical.
+sname
+ This field specifies all components of the name part of the server's
+ identity, including those parts that identify a specific instance of a
+ service.
+enc-part
+ This field holds the encrypted encoding of the EncTicketPart sequence.
+extensions
+ [*** This change is still subject to discussion. Several alternatives
+ for this - including none at all - will be distributed to the cat and
+ krb-protocol mailing lists before the Oslo IETF, and an alternative
+ will be selected and the spec modified by 7/14/99 ***] This optional
+ field contains a sequence of extentions that may be used to carry
+ information that must be carried with the ticket to support several
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ extensions, including but not limited to plaintext authorization data,
+ tokens for exchanging inter-realm keys, and other information that must
+ be associated with a ticket for use by the application server. See
+ Appendix C for definitions of some common extensions.
+
+ Note that some older versions of Kerberos did not support this field.
+ Because this is an optional field it will not break older clients, but
+ older clients might strip this field from the ticket before sending it
+ to the application server. This limits the usefulness of this ticket
+ field to environments where the ticket will not be parsed and
+ reconstructed by these older Kerberos clients.
+
+ If it is known that the client will strip this field from the ticket,
+ as an interim measure the KDC may append this field to the end of the
+ enc-part of the ticket and append a traler indicating the lenght of the
+ appended extensions field. (this paragraph is open for discussion,
+ including the form of the traler).
+flags
+ This field indicates which of various options were used or requested
+ when the ticket was issued. It is a bit-field, where the selected
+ options are indicated by the bit being set (1), and the unselected
+ options and reserved fields being reset (0). Bit 0 is the most
+ significant bit. The encoding of the bits is specified in section 5.2.
+ The flags are described in more detail above in section 2. The meanings
+ of the flags are:
+
+ Bit(s) Name Description
+
+ 0 RESERVED
+ Reserved for future expansion of this
+ field.
+
+ 1 FORWARDABLE
+ The FORWARDABLE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. When set, this
+ flag tells the ticket-granting server
+ that it is OK to issue a new ticket-
+ granting ticket with a different network
+ address based on the presented ticket.
+
+ 2 FORWARDED
+ When set, this flag indicates that the
+ ticket has either been forwarded or was
+ issued based on authentication involving
+ a forwarded ticket-granting ticket.
+
+ 3 PROXIABLE
+ The PROXIABLE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. The PROXIABLE
+ flag has an interpretation identical to
+ that of the FORWARDABLE flag, except
+ that the PROXIABLE flag tells the
+ ticket-granting server that only non-
+ ticket-granting tickets may be issued
+ with different network addresses.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ 4 PROXY
+ When set, this flag indicates that a
+ ticket is a proxy.
+
+ 5 MAY-POSTDATE
+ The MAY-POSTDATE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. This flag tells
+ the ticket-granting server that a post-
+ dated ticket may be issued based on this
+ ticket-granting ticket.
+
+ 6 POSTDATED
+ This flag indicates that this ticket has
+ been postdated. The end-service can
+ check the authtime field to see when the
+ original authentication occurred.
+
+ 7 INVALID
+ This flag indicates that a ticket is
+ invalid, and it must be validated by the
+ KDC before use. Application servers
+ must reject tickets which have this flag
+ set.
+
+ 8 RENEWABLE
+ The RENEWABLE flag is normally only
+ interpreted by the TGS, and can usually
+ be ignored by end servers (some particu-
+ larly careful servers may wish to disal-
+ low renewable tickets). A renewable
+ ticket can be used to obtain a replace-
+ ment ticket that expires at a later
+ date.
+
+ 9 INITIAL
+ This flag indicates that this ticket was
+ issued using the AS protocol, and not
+ issued based on a ticket-granting
+ ticket.
+
+ 10 PRE-AUTHENT
+ This flag indicates that during initial
+ authentication, the client was authenti-
+ cated by the KDC before a ticket was
+ issued. The strength of the pre-
+ authentication method is not indicated,
+ but is acceptable to the KDC.
+
+ 11 HW-AUTHENT
+ This flag indicates that the protocol
+ employed for initial authentication
+ required the use of hardware expected to
+ be possessed solely by the named client.
+ The hardware authentication method is
+ selected by the KDC and the strength of
+ the method is not indicated.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ 12 TRANSITED This flag indicates that the KDC for the
+ POLICY-CHECKED realm has checked the transited field
+ against a realm defined policy for
+ trusted certifiers. If this flag is
+ reset (0), then the application server
+ must check the transited field itself,
+ and if unable to do so it must reject
+ the authentication. If the flag is set
+ (1) then the application server may skip
+ its own validation of the transited
+ field, relying on the validation
+ performed by the KDC. At its option the
+ application server may still apply its
+ own validation based on a separate
+ policy for acceptance.
+
+ 13 OK-AS-DELEGATE This flag indicates that the server (not
+ the client) specified in the ticket has
+ been determined by policy of the realm
+ to be a suitable recipient of
+ delegation. A client can use the
+ presence of this flag to help it make a
+ decision whether to delegate credentials
+ (either grant a proxy or a forwarded
+ ticket granting ticket) to this server.
+ The client is free to ignore the value
+ of this flag. When setting this flag,
+ an administrator should consider the
+ Security and placement of the server on
+ which the service will run, as well as
+ whether the service requires the use of
+ delegated credentials.
+
+ 14 ANONYMOUS
+ This flag indicates that the principal
+ named in the ticket is a generic princi-
+ pal for the realm and does not identify
+ the individual using the ticket. The
+ purpose of the ticket is only to
+ securely distribute a session key, and
+ not to identify the user. Subsequent
+ requests using the same ticket and ses-
+ sion may be considered as originating
+ from the same user, but requests with
+ the same username but a different ticket
+ are likely to originate from different
+ users.
+
+ 15-31 RESERVED
+ Reserved for future use.
+
+key
+ This field exists in the ticket and the KDC response and is used to
+ pass the session key from Kerberos to the application server and the
+ client. The field's encoding is described in section 6.2.
+crealm
+ This field contains the name of the realm in which the client is
+ registered and in which initial authentication took place.
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+cname
+ This field contains the name part of the client's principal identifier.
+transited
+ This field lists the names of the Kerberos realms that took part in
+ authenticating the user to whom this ticket was issued. It does not
+ specify the order in which the realms were transited. See section
+ 3.3.3.2 for details on how this field encodes the traversed realms.
+ When the names of CA's are to be embedded inthe transited field (as
+ specified for some extentions to the protocol), the X.500 names of the
+ CA's should be mapped into items in the transited field using the
+ mapping defined by RFC2253.
+authtime
+ This field indicates the time of initial authentication for the named
+ principal. It is the time of issue for the original ticket on which
+ this ticket is based. It is included in the ticket to provide
+ additional information to the end service, and to provide the necessary
+ information for implementation of a `hot list' service at the KDC. An
+ end service that is particularly paranoid could refuse to accept
+ tickets for which the initial authentication occurred "too far" in the
+ past. This field is also returned as part of the response from the KDC.
+ When returned as part of the response to initial authentication
+ (KRB_AS_REP), this is the current time on the Ker- beros server[24].
+starttime
+ This field in the ticket specifies the time after which the ticket is
+ valid. Together with endtime, this field specifies the life of the
+ ticket. If it is absent from the ticket, its value should be treated as
+ that of the authtime field.
+endtime
+ This field contains the time after which the ticket will not be honored
+ (its expiration time). Note that individual services may place their
+ own limits on the life of a ticket and may reject tickets which have
+ not yet expired. As such, this is really an upper bound on the
+ expiration time for the ticket.
+renew-till
+ This field is only present in tickets that have the RENEWABLE flag set
+ in the flags field. It indicates the maximum endtime that may be
+ included in a renewal. It can be thought of as the absolute expiration
+ time for the ticket, including all renewals.
+caddr
+ This field in a ticket contains zero (if omitted) or more (if present)
+ host addresses. These are the addresses from which the ticket can be
+ used. If there are no addresses, the ticket can be used from any
+ location. The decision by the KDC to issue or by the end server to
+ accept zero-address tickets is a policy decision and is left to the
+ Kerberos and end-service administrators; they may refuse to issue or
+ accept such tickets. The suggested and default policy, however, is that
+ such tickets will only be issued or accepted when additional
+ information that can be used to restrict the use of the ticket is
+ included in the authorization_data field. Such a ticket is a
+ capability.
+
+ Network addresses are included in the ticket to make it harder for an
+ attacker to use stolen credentials. Because the session key is not sent
+ over the network in cleartext, credentials can't be stolen simply by
+ listening to the network; an attacker has to gain access to the session
+ key (perhaps through operating system security breaches or a careless
+ user's unattended session) to make use of stolen tickets.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ It is important to note that the network address from which a
+ connection is received cannot be reliably determined. Even if it could
+ be, an attacker who has compromised the client's workstation could use
+ the credentials from there. Including the network addresses only makes
+ it more difficult, not impossible, for an attacker to walk off with
+ stolen credentials and then use them from a "safe" location.
+authorization-data
+ The authorization-data field is used to pass authorization data from
+ the principal on whose behalf a ticket was issued to the application
+ service. If no authorization data is included, this field will be left
+ out. Experience has shown that the name of this field is confusing, and
+ that a better name for this field would be restrictions. Unfortunately,
+ it is not possible to change the name of this field at this time.
+
+ This field contains restrictions on any authority obtained on the basis
+ of authentication using the ticket. It is possible for any principal in
+ posession of credentials to add entries to the authorization data field
+ since these entries further restrict what can be done with the ticket.
+ Such additions can be made by specifying the additional entries when a
+ new ticket is obtained during the TGS exchange, or they may be added
+ during chained delegation using the authorization data field of the
+ authenticator.
+
+ Because entries may be added to this field by the holder of
+ credentials, it is not allowable for the presence of an entry in the
+ authorization data field of a ticket to amplify the priveleges one
+ would obtain from using a ticket.
+
+ The data in this field may be specific to the end service; the field
+ will contain the names of service specific objects, and the rights to
+ those objects. The format for this field is described in section 5.2.
+ Although Kerberos is not concerned with the format of the contents of
+ the sub-fields, it does carry type information (ad-type).
+
+ By using the authorization_data field, a principal is able to issue a
+ proxy that is valid for a specific purpose. For example, a client
+ wishing to print a file can obtain a file server proxy to be passed to
+ the print server. By specifying the name of the file in the
+ authorization_data field, the file server knows that the print server
+ can only use the client's rights when accessing the particular file to
+ be printed.
+
+ A separate service providing authorization or certifying group
+ membership may be built using the authorization-data field. In this
+ case, the entity granting authorization (not the authorized entity),
+ obtains a ticket in its own name (e.g. the ticket is issued in the name
+ of a privelege server), and this entity adds restrictions on its own
+ authority and delegates the restricted authority through a proxy to the
+ client. The client would then present this authorization credential to
+ the application server separately from the authentication exchange.
+
+ Similarly, if one specifies the authorization-data field of a proxy and
+ leaves the host addresses blank, the resulting ticket and session key
+ can be treated as a capability. See [Neu93] for some suggested uses of
+ this field.
+
+ The authorization-data field is optional and does not have to be
+ included in a ticket.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+5.3.2. Authenticators
+
+An authenticator is a record sent with a ticket to a server to certify the
+client's knowledge of the encryption key in the ticket, to help the server
+detect replays, and to help choose a "true session key" to use with the
+particular session. The encoding is encrypted in the ticket's session key
+shared by the client and the server:
+
+-- Unencrypted authenticator
+Authenticator ::= [APPLICATION 2] SEQUENCE {
+ authenticator-vno[0] INTEGER,
+ crealm[1] Realm,
+ cname[2] PrincipalName,
+ cksum[3] Checksum OPTIONAL,
+ cusec[4] INTEGER,
+ ctime[5] KerberosTime,
+ subkey[6] EncryptionKey OPTIONAL,
+ seq-number[7] INTEGER OPTIONAL,
+ authorization-data[8] AuthorizationData OPTIONAL
+}
+
+authenticator-vno
+ This field specifies the version number for the format of the
+ authenticator. This document specifies version 5.
+crealm and cname
+ These fields are the same as those described for the ticket in section
+ 5.3.1.
+cksum
+ This field contains a checksum of the the applica- tion data that
+ accompanies the KRB_AP_REQ.
+cusec
+ This field contains the microsecond part of the client's timestamp. Its
+ value (before encryption) ranges from 0 to 999999. It often appears
+ along with ctime. The two fields are used together to specify a
+ reasonably accurate timestamp.
+ctime
+ This field contains the current time on the client's host.
+subkey
+ This field contains the client's choice for an encryption key which is
+ to be used to protect this specific application session. Unless an
+ application specifies otherwise, if this field is left out the session
+ key from the ticket will be used.
+seq-number
+ This optional field includes the initial sequence number to be used by
+ the KRB_PRIV or KRB_SAFE messages when sequence numbers are used to
+ detect replays (It may also be used by application specific messages).
+ When included in the authenticator this field specifies the initial
+ sequence number for messages from the client to the server. When
+ included in the AP-REP message, the initial sequence number is that for
+ messages from the server to the client. When used in KRB_PRIV or
+ KRB_SAFE messages, it is incremented by one after each message is sent.
+ Sequence numbers fall in the range of 0 through 2^32 - 1 and wrap to
+ zero following the value 2^32 - 1.
+
+ For sequence numbers to adequately support the detection of replays
+ they should be non-repeating, even across connection boundaries. The
+ initial sequence number should be random and uniformly distributed
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ across the full space of possible sequence numbers, so that it cannot
+ be guessed by an attacker and so that it and the successive sequence
+ numbers do not repeat other sequences.
+authorization-data
+ This field is the same as described for the ticket in section 5.3.1. It
+ is optional and will only appear when additional restrictions are to be
+ placed on the use of a ticket, beyond those carried in the ticket
+ itself.
+
+5.4. Specifications for the AS and TGS exchanges
+
+This section specifies the format of the messages used in the exchange
+between the client and the Kerberos server. The format of possible error
+messages appears in section 5.9.1.
+
+5.4.1. KRB_KDC_REQ definition
+
+The KRB_KDC_REQ message has no type of its own. Instead, its type is one of
+KRB_AS_REQ or KRB_TGS_REQ depending on whether the request is for an initial
+ticket or an additional ticket. In either case, the message is sent from the
+client to the Authentication Server to request credentials for a service.
+
+The message fields are:
+
+AS-REQ ::= [APPLICATION 10] KDC-REQ
+TGS-REQ ::= [APPLICATION 12] KDC-REQ
+
+KDC-REQ ::= SEQUENCE {
+ pvno[1] INTEGER,
+ msg-type[2] INTEGER,
+ padata[3] SEQUENCE OF PA-DATA OPTIONAL,
+ req-body[4] KDC-REQ-BODY
+}
+
+PA-DATA ::= SEQUENCE {
+ padata-type[1] INTEGER,
+ padata-value[2] OCTET STRING,
+ -- might be encoded AP-REQ
+}
+
+KDC-REQ-BODY ::= SEQUENCE {
+ kdc-options[0] KDCOptions,
+ cname[1] PrincipalName OPTIONAL,
+ -- Used only in AS-REQ
+ realm[2] Realm, -- Server's realm
+ -- Also client's in AS-REQ
+ sname[3] PrincipalName OPTIONAL,
+ from[4] KerberosTime OPTIONAL,
+ till[5] KerberosTime OPTIONAL,
+ rtime[6] KerberosTime OPTIONAL,
+ nonce[7] INTEGER,
+ etype[8] SEQUENCE OF INTEGER,
+ -- EncryptionType,
+ -- in preference order
+ addresses[9] HostAddresses OPTIONAL,
+ enc-authorization-data[10] EncryptedData OPTIONAL,
+ -- Encrypted AuthorizationData
+ -- encoding
+ additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
+}
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+The fields in this message are:
+
+pvno
+ This field is included in each message, and specifies the protocol
+ version number. This document specifies protocol version 5.
+msg-type
+ This field indicates the type of a protocol message. It will almost
+ always be the same as the application identifier associated with a
+ message. It is included to make the identifier more readily accessible
+ to the application. For the KDC-REQ message, this type will be
+ KRB_AS_REQ or KRB_TGS_REQ.
+padata
+ The padata (pre-authentication data) field contains a sequence of
+ authentication information which may be needed before credentials can
+ be issued or decrypted. In the case of requests for additional tickets
+ (KRB_TGS_REQ), this field will include an element with padata-type of
+ PA-TGS-REQ and data of an authentication header (ticket-granting ticket
+ and authenticator). The checksum in the authenticator (which must be
+ collision-proof) is to be computed over the KDC-REQ-BODY encoding. In
+ most requests for initial authentication (KRB_AS_REQ) and most replies
+ (KDC-REP), the padata field will be left out.
+
+ This field may also contain information needed by certain extensions to
+ the Kerberos protocol. For example, it might be used to initially
+ verify the identity of a client before any response is returned. This
+ is accomplished with a padata field with padata-type equal to
+ PA-ENC-TIMESTAMP and padata-value defined as follows:
+
+ padata-type ::= PA-ENC-TIMESTAMP
+ padata-value ::= EncryptedData -- PA-ENC-TS-ENC
+
+ PA-ENC-TS-ENC ::= SEQUENCE {
+ patimestamp[0] KerberosTime, -- client's time
+ pausec[1] INTEGER OPTIONAL
+ }
+
+ with patimestamp containing the client's time and pausec containing the
+ microseconds which may be omitted if a client will not generate more
+ than one request per second. The ciphertext (padata-value) consists of
+ the PA-ENC-TS-ENC sequence, encrypted using the client's secret key.
+
+ [use-specified-kvno item is here for discussion and may be removed] It
+ may also be used by the client to specify the version of a key that is
+ being used for accompanying preauthentication, and/or which should be
+ used to encrypt the reply from the KDC.
+
+ PA-USE-SPECIFIED-KVNO ::= Integer
+
+ The KDC should only accept and abide by the value of the
+ use-specified-kvno preauthentication data field when the specified key
+ is still valid and until use of a new key is confirmed. This situation
+ is likely to occur primarily during the period during which an updated
+ key is propagating to other KDC's in a realm.
+
+ The padata field can also contain information needed to help the KDC or
+ the client select the key needed for generating or decrypting the
+ response. This form of the padata is useful for supporting the use of
+ certain token cards with Kerberos. The details of such extensions are
+ specified in separate documents. See [Pat92] for additional uses of
+ this field.
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+padata-type
+ The padata-type element of the padata field indicates the way that the
+ padata-value element is to be interpreted. Negative values of
+ padata-type are reserved for unregistered use; non-negative values are
+ used for a registered interpretation of the element type.
+req-body
+ This field is a placeholder delimiting the extent of the remaining
+ fields. If a checksum is to be calculated over the request, it is
+ calculated over an encoding of the KDC-REQ-BODY sequence which is
+ enclosed within the req-body field.
+kdc-options
+ This field appears in the KRB_AS_REQ and KRB_TGS_REQ requests to the
+ KDC and indicates the flags that the client wants set on the tickets as
+ well as other information that is to modify the behavior of the KDC.
+ Where appropriate, the name of an option may be the same as the flag
+ that is set by that option. Although in most case, the bit in the
+ options field will be the same as that in the flags field, this is not
+ guaranteed, so it is not acceptable to simply copy the options field to
+ the flags field. There are various checks that must be made before
+ honoring an option anyway.
+
+ The kdc_options field is a bit-field, where the selected options are
+ indicated by the bit being set (1), and the unselected options and
+ reserved fields being reset (0). The encoding of the bits is specified
+ in section 5.2. The options are described in more detail above in
+ section 2. The meanings of the options are:
+
+ Bit(s) Name Description
+ 0 RESERVED
+ Reserved for future expansion of
+this
+ field.
+
+ 1 FORWARDABLE
+ The FORWARDABLE option indicates
+that
+ the ticket to be issued is to have
+its
+ forwardable flag set. It may only
+be
+ set on the initial request, or in a
+sub-
+ sequent request if the
+ticket-granting
+ ticket on which it is based is also
+for-
+ wardable.
+
+ 2 FORWARDED
+ The FORWARDED option is only
+specified
+ in a request to the
+ticket-granting
+ server and will only be honored if
+the
+ ticket-granting ticket in the
+request
+ has its FORWARDABLE bit set.
+This
+ option indicates that this is a
+request
+ for forwarding. The address(es) of
+the
+ host from which the resulting ticket
+is
+ to be valid are included in
+the
+ addresses field of the request.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ 3 PROXIABLE
+ The PROXIABLE option indicates that
+the
+ ticket to be issued is to have its
+prox-
+ iable flag set. It may only be set
+on
+ the initial request, or in a
+subsequent
+ request if the ticket-granting ticket
+on
+ which it is based is also proxiable.
+
+ 4 PROXY
+ The PROXY option indicates that this
+is
+ a request for a proxy. This option
+will
+ only be honored if the
+ticket-granting
+ ticket in the request has its
+PROXIABLE
+ bit set. The address(es) of the
+host
+ from which the resulting ticket is to
+be
+ valid are included in the
+addresses
+ field of the request.
+
+ 5 ALLOW-POSTDATE
+ The ALLOW-POSTDATE option indicates
+that
+ the ticket to be issued is to have
+its
+ MAY-POSTDATE flag set. It may only
+be
+ set on the initial request, or in a
+sub-
+ sequent request if the
+ticket-granting
+ ticket on which it is based also has
+its
+ MAY-POSTDATE flag set.
+
+ 6 POSTDATED
+ The POSTDATED option indicates that
+this
+ is a request for a postdated
+ticket.
+ This option will only be honored if
+the
+ ticket-granting ticket on which it
+is
+ based has its MAY-POSTDATE flag
+set.
+ The resulting ticket will also have
+its
+ INVALID flag set, and that flag may
+be
+ reset by a subsequent request to the
+KDC
+ after the starttime in the ticket
+has
+ been reached.
+
+ 7 UNUSED
+ This option is presently unused.
+
+ 8 RENEWABLE
+ The RENEWABLE option indicates that
+the
+ ticket to be issued is to have
+its
+ RENEWABLE flag set. It may only be
+set
+ on the initial request, or when
+the
+ ticket-granting ticket on which
+the
+ request is based is also renewable.
+If
+ this option is requested, then the
+rtime
+ field in the request contains
+the
+ desired absolute expiration time for
+the
+ ticket.
+
+ 9-13 UNUSED
+ These options are presently unused.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ 14 REQUEST-ANONYMOUS
+ The REQUEST-ANONYMOUS option
+indicates
+ that the ticket to be issued is not
+to
+ identify the user to which it
+was
+ issued. Instead, the principal
+identif-
+ ier is to be generic, as specified
+by
+ the policy of the realm (e.g.
+usually
+ anonymous@realm). The purpose of
+the
+ ticket is only to securely distribute
+a
+ session key, and not to identify
+the
+ user. The ANONYMOUS flag on the
+ticket
+ to be returned should be set. If
+the
+ local realms policy does not
+permit
+ anonymous credentials, the request is
+to
+ be rejected.
+
+ 15-25 RESERVED
+ Reserved for future use.
+
+ 26 DISABLE-TRANSITED-CHECK
+ By default the KDC will check the
+ transited field of a ticket-granting-
+ ticket against the policy of the local
+ realm before it will issue derivative
+ tickets based on the ticket granting
+ ticket. If this flag is set in the
+ request, checking of the transited
+field
+ is disabled. Tickets issued without
+the
+ performance of this check will be
+noted
+ by the reset (0) value of the
+ TRANSITED-POLICY-CHECKED flag,
+ indicating to the application server
+ that the tranisted field must be
+checked
+ locally. KDC's are encouraged but not
+ required to honor the
+ DISABLE-TRANSITED-CHECK option.
+
+ 27 RENEWABLE-OK
+ The RENEWABLE-OK option indicates that
+a
+ renewable ticket will be acceptable if
+a
+ ticket with the requested life
+cannot
+ otherwise be provided. If a ticket
+with
+ the requested life cannot be
+provided,
+ then a renewable ticket may be
+issued
+ with a renew-till equal to the
+the
+ requested endtime. The value of
+the
+ renew-till field may still be limited
+by
+ local limits, or limits selected by
+the
+ individual principal or server.
+
+ 28 ENC-TKT-IN-SKEY
+ This option is used only by the
+ticket-
+ granting service. The
+ENC-TKT-IN-SKEY
+ option indicates that the ticket for
+the
+ end server is to be encrypted in
+the
+ session key from the additional
+ticket-
+ granting ticket provided.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ 29 RESERVED
+ Reserved for future use.
+
+ 30 RENEW
+ This option is used only by the
+ticket-
+ granting service. The RENEW
+option
+ indicates that the present request
+is
+ for a renewal. The ticket provided
+is
+ encrypted in the secret key for
+the
+ server on which it is valid.
+This
+ option will only be honored if
+the
+ ticket to be renewed has its
+RENEWABLE
+ flag set and if the time in its
+renew-
+ till field has not passed. The
+ticket
+ to be renewed is passed in the
+padata
+ field as part of the
+authentication
+ header.
+
+ 31 VALIDATE
+ This option is used only by the
+ticket-
+ granting service. The VALIDATE
+option
+ indicates that the request is to
+vali-
+ date a postdated ticket. It will
+only
+ be honored if the ticket presented
+is
+ postdated, presently has its
+INVALID
+ flag set, and would be otherwise
+usable
+ at this time. A ticket cannot be
+vali-
+ dated before its starttime. The
+ticket
+ presented for validation is encrypted
+in
+ the key of the server for which it
+is
+ valid and is passed in the padata
+field
+ as part of the authentication header.
+
+cname and sname
+ These fields are the same as those described for the ticket in section
+ 5.3.1. sname may only be absent when the ENC-TKT-IN-SKEY option is
+ specified. If absent, the name of the server is taken from the name of
+ the client in the ticket passed as additional-tickets.
+enc-authorization-data
+ The enc-authorization-data, if present (and it can only be present in
+ the TGS_REQ form), is an encoding of the desired authorization-data
+ encrypted under the sub-session key if present in the Authenticator, or
+ alternatively from the session key in the ticket-granting ticket, both
+ from the padata field in the KRB_AP_REQ.
+realm
+ This field specifies the realm part of the server's principal
+ identifier. In the AS exchange, this is also the realm part of the
+ client's principal identifier.
+from
+ This field is included in the KRB_AS_REQ and KRB_TGS_REQ ticket
+ requests when the requested ticket is to be postdated. It specifies the
+ desired start time for the requested ticket. If this field is omitted
+ then the KDC should use the current time instead.
+till
+ This field contains the expiration date requested by the client in a
+ ticket request. It is optional and if omitted the requested ticket is
+ to have the maximum endtime permitted according to KDC policy for the
+ parties to the authentication exchange as limited by expiration date of
+ the ticket granting ticket or other preauthentication credentials.
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+rtime
+ This field is the requested renew-till time sent from a client to the
+ KDC in a ticket request. It is optional.
+nonce
+ This field is part of the KDC request and response. It it intended to
+ hold a random number generated by the client. If the same number is
+ included in the encrypted response from the KDC, it provides evidence
+ that the response is fresh and has not been replayed by an attacker.
+ Nonces must never be re-used. Ideally, it should be generated randomly,
+ but if the correct time is known, it may suffice[25].
+etype
+ This field specifies the desired encryption algorithm to be used in the
+ response.
+addresses
+ This field is included in the initial request for tickets, and
+ optionally included in requests for additional tickets from the
+ ticket-granting server. It specifies the addresses from which the
+ requested ticket is to be valid. Normally it includes the addresses for
+ the client's host. If a proxy is requested, this field will contain
+ other addresses. The contents of this field are usually copied by the
+ KDC into the caddr field of the resulting ticket.
+additional-tickets
+ Additional tickets may be optionally included in a request to the
+ ticket-granting server. If the ENC-TKT-IN-SKEY option has been
+ specified, then the session key from the additional ticket will be used
+ in place of the server's key to encrypt the new ticket. If more than
+ one option which requires additional tickets has been specified, then
+ the additional tickets are used in the order specified by the ordering
+ of the options bits (see kdc-options, above).
+
+The application code will be either ten (10) or twelve (12) depending on
+whether the request is for an initial ticket (AS-REQ) or for an additional
+ticket (TGS-REQ).
+
+The optional fields (addresses, authorization-data and additional-tickets)
+are only included if necessary to perform the operation specified in the
+kdc-options field.
+
+It should be noted that in KRB_TGS_REQ, the protocol version number appears
+twice and two different message types appear: the KRB_TGS_REQ message
+contains these fields as does the authentication header (KRB_AP_REQ) that is
+passed in the padata field.
+
+5.4.2. KRB_KDC_REP definition
+
+The KRB_KDC_REP message format is used for the reply from the KDC for either
+an initial (AS) request or a subsequent (TGS) request. There is no message
+type for KRB_KDC_REP. Instead, the type will be either KRB_AS_REP or
+KRB_TGS_REP. The key used to encrypt the ciphertext part of the reply
+depends on the message type. For KRB_AS_REP, the ciphertext is encrypted in
+the client's secret key, and the client's key version number is included in
+the key version number for the encrypted data. For KRB_TGS_REP, the
+ciphertext is encrypted in the sub-session key from the Authenticator, or if
+absent, the session key from the ticket-granting ticket used in the request.
+In that case, no version number will be present in the EncryptedData
+sequence.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+The KRB_KDC_REP message contains the following fields:
+
+AS-REP ::= [APPLICATION 11] KDC-REP
+TGS-REP ::= [APPLICATION 13] KDC-REP
+
+KDC-REP ::= SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ padata[2] SEQUENCE OF PA-DATA OPTIONAL,
+ crealm[3] Realm,
+ cname[4] PrincipalName,
+ ticket[5] Ticket,
+ enc-part[6] EncryptedData
+}
+
+EncASRepPart ::= [APPLICATION 25[27]] EncKDCRepPart
+EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
+
+EncKDCRepPart ::= SEQUENCE {
+ key[0] EncryptionKey,
+ last-req[1] LastReq,
+ nonce[2] INTEGER,
+ key-expiration[3] KerberosTime OPTIONAL,
+ flags[4] TicketFlags,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ srealm[9] Realm,
+ sname[10] PrincipalName,
+ caddr[11] HostAddresses OPTIONAL
+}
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is either
+ KRB_AS_REP or KRB_TGS_REP.
+padata
+ This field is described in detail in section 5.4.1. One possible use
+ for this field is to encode an alternate "mix-in" string to be used
+ with a string-to-key algorithm (such as is described in section 6.3.2).
+ This ability is useful to ease transitions if a realm name needs to
+ change (e.g. when a company is acquired); in such a case all existing
+ password-derived entries in the KDC database would be flagged as
+ needing a special mix-in string until the next password change.
+crealm, cname, srealm and sname
+ These fields are the same as those described for the ticket in section
+ 5.3.1.
+ticket
+ The newly-issued ticket, from section 5.3.1.
+enc-part
+ This field is a place holder for the ciphertext and related information
+ that forms the encrypted part of a message. The description of the
+ encrypted part of the message follows each appearance of this field.
+ The encrypted part is encoded as described in section 6.1.
+key
+ This field is the same as described for the ticket in section 5.3.1.
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+last-req
+ This field is returned by the KDC and specifies the time(s) of the last
+ request by a principal. Depending on what information is available,
+ this might be the last time that a request for a ticket-granting ticket
+ was made, or the last time that a request based on a ticket-granting
+ ticket was successful. It also might cover all servers for a realm, or
+ just the particular server. Some implementations may display this
+ information to the user to aid in discovering unauthorized use of one's
+ identity. It is similar in spirit to the last login time displayed when
+ logging into timesharing systems.
+nonce
+ This field is described above in section 5.4.1.
+key-expiration
+ The key-expiration field is part of the response from the KDC and
+ specifies the time that the client's secret key is due to expire. The
+ expiration might be the result of password aging or an account
+ expiration. This field will usually be left out of the TGS reply since
+ the response to the TGS request is encrypted in a session key and no
+ client information need be retrieved from the KDC database. It is up to
+ the application client (usually the login program) to take appropriate
+ action (such as notifying the user) if the expiration time is imminent.
+flags, authtime, starttime, endtime, renew-till and caddr
+ These fields are duplicates of those found in the encrypted portion of
+ the attached ticket (see section 5.3.1), provided so the client may
+ verify they match the intended request and to assist in proper ticket
+ caching. If the message is of type KRB_TGS_REP, the caddr field will
+ only be filled in if the request was for a proxy or forwarded ticket,
+ or if the user is substituting a subset of the addresses from the
+ ticket granting ticket. If the client-requested addresses are not
+ present or not used, then the addresses contained in the ticket will be
+ the same as those included in the ticket-granting ticket.
+
+5.5. Client/Server (CS) message specifications
+
+This section specifies the format of the messages used for the
+authentication of the client to the application server.
+
+5.5.1. KRB_AP_REQ definition
+
+The KRB_AP_REQ message contains the Kerberos protocol version number, the
+message type KRB_AP_REQ, an options field to indicate any options in use,
+and the ticket and authenticator themselves. The KRB_AP_REQ message is often
+referred to as the 'authentication header'.
+
+AP-REQ ::= [APPLICATION 14] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ap-options[2] APOptions,
+ ticket[3] Ticket,
+ authenticator[4] EncryptedData
+}
+
+APOptions ::= BIT STRING {
+ reserved(0),
+ use-session-key(1),
+ mutual-required(2)
+}
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_AP_REQ.
+ap-options
+ This field appears in the application request (KRB_AP_REQ) and affects
+ the way the request is processed. It is a bit-field, where the selected
+ options are indicated by the bit being set (1), and the unselected
+ options and reserved fields being reset (0). The encoding of the bits
+ is specified in section 5.2. The meanings of the options are:
+
+ Bit(s) Name Description
+
+ 0 RESERVED
+ Reserved for future expansion of this
+ field.
+
+ 1 USE-SESSION-KEY
+ The USE-SESSION-KEY option indicates
+ that the ticket the client is presenting
+ to a server is encrypted in the session
+ key from the server's ticket-granting
+ ticket. When this option is not speci-
+ fied, the ticket is encrypted in the
+ server's secret key.
+
+ 2 MUTUAL-REQUIRED
+ The MUTUAL-REQUIRED option tells the
+ server that the client requires mutual
+ authentication, and that it must respond
+ with a KRB_AP_REP message.
+
+ 3-31 RESERVED
+ Reserved for future use.
+
+ticket
+ This field is a ticket authenticating the client to the server.
+authenticator
+ This contains the authenticator, which includes the client's choice of
+ a subkey. Its encoding is described in section 5.3.2.
+
+5.5.2. KRB_AP_REP definition
+
+The KRB_AP_REP message contains the Kerberos protocol version number, the
+message type, and an encrypted time- stamp. The message is sent in in
+response to an application request (KRB_AP_REQ) where the mutual
+authentication option has been selected in the ap-options field.
+
+AP-REP ::= [APPLICATION 15] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[2] EncryptedData
+}
+
+EncAPRepPart ::= [APPLICATION 27[29]] SEQUENCE {
+ ctime[0] KerberosTime,
+ cusec[1] INTEGER,
+ subkey[2] EncryptionKey OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL
+}
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+The encoded EncAPRepPart is encrypted in the shared session key of the
+ticket. The optional subkey field can be used in an application-arranged
+negotiation to choose a per association session key.
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_AP_REP.
+enc-part
+ This field is described above in section 5.4.2.
+ctime
+ This field contains the current time on the client's host.
+cusec
+ This field contains the microsecond part of the client's timestamp.
+subkey
+ This field contains an encryption key which is to be used to protect
+ this specific application session. See section 3.2.6 for specifics on
+ how this field is used to negotiate a key. Unless an application
+ specifies otherwise, if this field is left out, the sub-session key
+ from the authenticator, or if also left out, the session key from the
+ ticket will be used.
+
+5.5.3. Error message reply
+
+If an error occurs while processing the application request, the KRB_ERROR
+message will be sent in response. See section 5.9.1 for the format of the
+error message. The cname and crealm fields may be left out if the server
+cannot determine their appropriate values from the corresponding KRB_AP_REQ
+message. If the authenticator was decipherable, the ctime and cusec fields
+will contain the values from it.
+
+5.6. KRB_SAFE message specification
+
+This section specifies the format of a message that can be used by either
+side (client or server) of an application to send a tamper-proof message to
+its peer. It presumes that a session key has previously been exchanged (for
+example, by using the KRB_AP_REQ/KRB_AP_REP messages).
+
+5.6.1. KRB_SAFE definition
+
+The KRB_SAFE message contains user data along with a collision-proof
+checksum keyed with the last encryption key negotiated via subkeys, or the
+session key if no negotiation has occured. The message fields are:
+
+KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ safe-body[2] KRB-SAFE-BODY,
+ cksum[3] Checksum
+}
+
+KRB-SAFE-BODY ::= SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+}
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_SAFE.
+safe-body
+ This field is a placeholder for the body of the KRB-SAFE message.
+cksum
+ This field contains the checksum of the application data. Checksum
+ details are described in section 6.4. The checksum is computed over the
+ encoding of the KRB-SAFE sequence. First, the cksum is zeroed and the
+ checksum is computed over the encoding of the KRB-SAFE sequence, then
+ the checksum is set to the result of that computation, and finally the
+ KRB-SAFE sequence is encoded again.
+user-data
+ This field is part of the KRB_SAFE and KRB_PRIV messages and contain
+ the application specific data that is being passed from the sender to
+ the recipient.
+timestamp
+ This field is part of the KRB_SAFE and KRB_PRIV messages. Its contents
+ are the current time as known by the sender of the message. By checking
+ the timestamp, the recipient of the message is able to make sure that
+ it was recently generated, and is not a replay.
+usec
+ This field is part of the KRB_SAFE and KRB_PRIV headers. It contains
+ the microsecond part of the timestamp.
+seq-number
+ This field is described above in section 5.3.2.
+s-address
+ This field specifies the address in use by the sender of the message.
+ It may be omitted if not required by the application protocol. The
+ application designer considering omission of this field is warned, that
+ the inclusion of this address prevents some kinds of replay attacks
+ (e.g., reflection attacks) and that it is only acceptable to omit this
+ address if there is sufficient information in the integrity protected
+ part of the application message for the recipient to unambiguously
+ determine if it was the intended recipient.
+r-address
+ This field specifies the address in use by the recipient of the
+ message. It may be omitted for some uses (such as broadcast protocols),
+ but the recipient may arbitrarily reject such messages. This field
+ along with s-address can be used to help detect messages which have
+ been incorrectly or maliciously delivered to the wrong recipient.
+
+5.7. KRB_PRIV message specification
+
+This section specifies the format of a message that can be used by either
+side (client or server) of an application to securely and privately send a
+message to its peer. It presumes that a session key has previously been
+exchanged (for example, by using the KRB_AP_REQ/KRB_AP_REP messages).
+
+5.7.1. KRB_PRIV definition
+
+The KRB_PRIV message contains user data encrypted in the Session Key. The
+message fields are:
+
+KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[3] EncryptedData
+}
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+EncKrbPrivPart ::= [APPLICATION 28[31]] SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL, -- sender's
+addr
+ r-address[5] HostAddress OPTIONAL -- recip's
+addr
+}
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_PRIV.
+enc-part
+ This field holds an encoding of the EncKrbPrivPart sequence encrypted
+ under the session key[32]. This encrypted encoding is used for the
+ enc-part field of the KRB-PRIV message. See section 6 for the format of
+ the ciphertext.
+user-data, timestamp, usec, s-address and r-address
+ These fields are described above in section 5.6.1.
+seq-number
+ This field is described above in section 5.3.2.
+
+5.8. KRB_CRED message specification
+
+This section specifies the format of a message that can be used to send
+Kerberos credentials from one principal to another. It is presented here to
+encourage a common mechanism to be used by applications when forwarding
+tickets or providing proxies to subordinate servers. It presumes that a
+session key has already been exchanged perhaps by using the
+KRB_AP_REQ/KRB_AP_REP messages.
+
+5.8.1. KRB_CRED definition
+
+The KRB_CRED message contains a sequence of tickets to be sent and
+information needed to use the tickets, including the session key from each.
+The information needed to use the tickets is encrypted under an encryption
+key previously exchanged or transferred alongside the KRB_CRED message. The
+message fields are:
+
+KRB-CRED ::= [APPLICATION 22] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER, -- KRB_CRED
+ tickets[2] SEQUENCE OF Ticket,
+ enc-part[3] EncryptedData
+}
+
+EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
+ ticket-info[0] SEQUENCE OF KrbCredInfo,
+ nonce[1] INTEGER OPTIONAL,
+ timestamp[2] KerberosTime OPTIONAL,
+ usec[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+}
+
+KrbCredInfo ::= SEQUENCE {
+ key[0] EncryptionKey,
+ prealm[1] Realm OPTIONAL,
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ pname[2] PrincipalName OPTIONAL,
+ flags[3] TicketFlags OPTIONAL,
+ authtime[4] KerberosTime OPTIONAL,
+ starttime[5] KerberosTime OPTIONAL,
+ endtime[6] KerberosTime OPTIONAL
+ renew-till[7] KerberosTime OPTIONAL,
+ srealm[8] Realm OPTIONAL,
+ sname[9] PrincipalName OPTIONAL,
+ caddr[10] HostAddresses OPTIONAL
+}
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_CRED.
+tickets
+ These are the tickets obtained from the KDC specifically for use by the
+ intended recipient. Successive tickets are paired with the
+ corresponding KrbCredInfo sequence from the enc-part of the KRB-CRED
+ message.
+enc-part
+ This field holds an encoding of the EncKrbCredPart sequence encrypted
+ under the session key shared between the sender and the intended
+ recipient. This encrypted encoding is used for the enc-part field of
+ the KRB-CRED message. See section 6 for the format of the ciphertext.
+nonce
+ If practical, an application may require the inclusion of a nonce
+ generated by the recipient of the message. If the same value is
+ included as the nonce in the message, it provides evidence that the
+ message is fresh and has not been replayed by an attacker. A nonce must
+ never be re-used; it should be generated randomly by the recipient of
+ the message and provided to the sender of the message in an application
+ specific manner.
+timestamp and usec
+ These fields specify the time that the KRB-CRED message was generated.
+ The time is used to provide assurance that the message is fresh.
+s-address and r-address
+ These fields are described above in section 5.6.1. They are used
+ optionally to provide additional assurance of the integrity of the
+ KRB-CRED message.
+key
+ This field exists in the corresponding ticket passed by the KRB-CRED
+ message and is used to pass the session key from the sender to the
+ intended recipient. The field's encoding is described in section 6.2.
+
+The following fields are optional. If present, they can be associated with
+the credentials in the remote ticket file. If left out, then it is assumed
+that the recipient of the credentials already knows their value.
+
+prealm and pname
+ The name and realm of the delegated principal identity.
+flags, authtime, starttime, endtime, renew-till, srealm, sname, and caddr
+ These fields contain the values of the correspond- ing fields from the
+ ticket found in the ticket field. Descriptions of the fields are
+ identical to the descriptions in the KDC-REP message.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+5.9. Error message specification
+
+This section specifies the format for the KRB_ERROR message. The fields
+included in the message are intended to return as much information as
+possible about an error. It is not expected that all the information
+required by the fields will be available for all types of errors. If the
+appropriate information is not available when the message is composed, the
+corresponding field will be left out of the message.
+
+Note that since the KRB_ERROR message is only optionally integrity
+protected, it is quite possible for an intruder to synthesize or modify such
+a message. In particular, this means that unless appropriate integrity
+protection mechanisms have been applied to the KRB_ERROR message, the client
+should not use any fields in this message for security-critical purposes,
+such as setting a system clock or generating a fresh authenticator. The
+message can be useful, however, for advising a user on the reason for some
+failure.
+
+5.9.1. KRB_ERROR definition
+
+The KRB_ERROR message consists of the following fields:
+
+KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ctime[2] KerberosTime OPTIONAL,
+ cusec[3] INTEGER OPTIONAL,
+ stime[4] KerberosTime,
+ susec[5] INTEGER,
+ error-code[6] INTEGER,
+ crealm[7] Realm OPTIONAL,
+ cname[8] PrincipalName OPTIONAL,
+ realm[9] Realm, -- Correct realm
+ sname[10] PrincipalName, -- Correct name
+ e-text[11] GeneralString OPTIONAL,
+ e-data[12] OCTET STRING OPTIONAL,
+ e-cksum[13] Checksum OPTIONAL,
+(*REMOVE7/14*) e-typed-data[14] SEQUENCE of ETypedData
+OPTIONAL
+}
+
+pvno and msg-type
+ These fields are described above in section 5.4.1. msg-type is
+ KRB_ERROR.
+ctime
+ This field is described above in section 5.4.1.
+cusec
+ This field is described above in section 5.5.2.
+stime
+ This field contains the current time on the server. It is of type
+ KerberosTime.
+susec
+ This field contains the microsecond part of the server's timestamp. Its
+ value ranges from 0 to 999999. It appears along with stime. The two
+ fields are used in conjunction to specify a reasonably accurate
+ timestamp.
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+error-code
+ This field contains the error code returned by Kerberos or the server
+ when a request fails. To interpret the value of this field see the list
+ of error codes in section 8. Implementations are encouraged to provide
+ for national language support in the display of error messages.
+crealm, cname, srealm and sname
+ These fields are described above in section 5.3.1.
+e-text
+ This field contains additional text to help explain the error code
+ associated with the failed request (for example, it might include a
+ principal name which was unknown).
+e-data
+ This field contains additional data about the error for use by the
+ application to help it recover from or handle the error. If present,
+ this field will contain the encoding of a sequence of TypedData
+ (TYPED-DATA below), unless the errorcode is KDC_ERR_PREAUTH_REQUIRED,
+ in which case it will contain the encoding of a sequence of of padata
+ fields (METHOD-DATA below), each corresponding to an acceptable
+ pre-authentication method and optionally containing data for the
+ method:
+
+ TYPED-DATA ::= SEQUENCE of TypeData
+ METHOD-DATA ::= SEQUENCE of PA-DATA
+
+ TypedData ::= SEQUENCE {
+ data-type[0] INTEGER,
+ data-value[1] OCTET STRING OPTIONAL
+ }
+
+ Note that e-data-types have been reserved for all PA data types defined
+ prior to July 1999. For the KDC_ERR_PREAUTH_REQUIRED message, when
+ using new PA data types defined in July 1999 or later, the METHOD-DATA
+ sequence must itself be encapsulated in an TypedData element of type
+ TD-PADATA. All new implementations interpreting the METHOD-DATA field
+ for the KDC_ERR_PREAUTH_REQUIRED message must accept a type of
+ TD-PADATA, extract the typed data field and interpret the use any
+ elements encapsulated in the TD-PADATA elements as if they were present
+ in the METHOD-DATA sequence.
+e-cksum
+ This field contains an optional checksum for the KRB-ERROR message. The
+ checksum is calculated over the Kerberos ASN.1 encoding of the
+ KRB-ERROR message with the checksum absent. The checksum is then added
+ to the KRB-ERROR structure and the message is re-encoded. The Checksum
+ should be calculated using the session key from the ticket granting
+ ticket or service ticket, where available. If the error is in response
+ to a TGS or AP request, the checksum should be calculated uing the the
+ session key from the client's ticket. If the error is in response to an
+ AS request, then the checksum should be calulated using the client's
+ secret key ONLY if there has been suitable preauthentication to prove
+ knowledge of the secret key by the client[33]. If a checksum can not be
+ computed because the key to be used is not available, no checksum will
+ be included.
+e-typed-data
+ [***Will be deleted 7/14***] This field contains optional data that may
+ be used to help the client recover from the indicated error. [This
+ could contain the METHOD-DATA specified since I don't think anyone
+ actually uses it yet. It could also contain the PA-DATA sequence for
+ the preauth required error if we had a clear way to transition to the
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ use of this field from the use of the untyped e-data field.] For
+ example, this field may specify the key version of the key used to
+ verify preauthentication:
+
+ e-data-type := 20 -- Key version number
+ e-data-value := Integer -- Key version number used to
+ verify preauthentication
+
+6. Encryption and Checksum Specifications
+
+The Kerberos protocols described in this document are designed to use stream
+encryption ciphers, which can be simulated using commonly available block
+encryption ciphers, such as the Data Encryption Standard, [DES77] in
+conjunction with block chaining and checksum methods [DESM80]. Encryption is
+used to prove the identities of the network entities participating in
+message exchanges. The Key Distribution Center for each realm is trusted by
+all principals registered in that realm to store a secret key in confidence.
+Proof of knowledge of this secret key is used to verify the authenticity of
+a principal. [*** Discussion above will change to use 3DES as example
+7/14/99 ***]
+
+The KDC uses the principal's secret key (in the AS exchange) or a shared
+session key (in the TGS exchange) to encrypt responses to ticket requests;
+the ability to obtain the secret key or session key implies the knowledge of
+the appropriate keys and the identity of the KDC. The ability of a principal
+to decrypt the KDC response and present a Ticket and a properly formed
+Authenticator (generated with the session key from the KDC response) to a
+service verifies the identity of the principal; likewise the ability of the
+service to extract the session key from the Ticket and prove its knowledge
+thereof in a response verifies the identity of the service.
+
+The Kerberos protocols generally assume that the encryption used is secure
+from cryptanalysis; however, in some cases, the order of fields in the
+encrypted portions of messages are arranged to minimize the effects of
+poorly chosen keys. It is still important to choose good keys. If keys are
+derived from user-typed passwords, those passwords need to be well chosen to
+make brute force attacks more difficult. Poorly chosen keys still make easy
+targets for intruders.
+
+The following sections specify the encryption and checksum mechanisms
+currently defined for Kerberos. The encodings, chaining, and padding
+requirements for each are described. For encryption methods, it is often
+desirable to place random information (often referred to as a confounder) at
+the start of the message. The requirements for a confounder are specified
+with each encryption mechanism.
+
+Some encryption systems use a block-chaining method to improve the the
+security characteristics of the ciphertext. However, these chaining methods
+often don't provide an integrity check upon decryption. Such systems (such
+as DES in CBC mode) must be augmented with a checksum of the plain-text
+which can be verified at decryption and used to detect any tampering or
+damage. Such checksums should be good at detecting burst errors in the
+input. If any damage is detected, the decryption routine is expected to
+return an error indicating the failure of an integrity check. Each
+encryption type is expected to provide and verify an appropriate checksum.
+The specification of each encryption method sets out its checksum
+requirements.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+Finally, where a key is to be derived from a user's password, an algorithm
+for converting the password to a key of the appropriate type is included. It
+is desirable for the string to key function to be one-way, and for the
+mapping to be different in different realms. This is important because users
+who are registered in more than one realm will often use the same password
+in each, and it is desirable that an attacker compromising the Kerberos
+server in one realm not obtain or derive the user's key in another.
+
+For an discussion of the integrity characteristics of the candidate
+encryption and checksum methods considered for Kerberos, the reader is
+referred to [SG92].
+
+6.1. Encryption Specifications
+
+The following ASN.1 definition describes all encrypted messages. The
+enc-part field which appears in the unencrypted part of messages in section
+5 is a sequence consisting of an encryption type, an optional key version
+number, and the ciphertext.
+
+EncryptedData ::= SEQUENCE {
+ etype[0] INTEGER, -- EncryptionType
+ kvno[1] INTEGER OPTIONAL,
+ cipher[2] OCTET STRING -- ciphertext
+}
+
+etype
+ This field identifies which encryption algorithm was used to encipher
+ the cipher. Detailed specifications for selected encryption types
+ appear later in this section.
+kvno
+ This field contains the version number of the key under which data is
+ encrypted. It is only present in messages encrypted under long lasting
+ keys, such as principals' secret keys.
+cipher
+ This field contains the enciphered text, encoded as an OCTET STRING.
+
+The cipher field is generated by applying the specified encryption algorithm
+to data composed of the message and algorithm-specific inputs. Encryption
+mechanisms defined for use with Kerberos must take sufficient measures to
+guarantee the integrity of the plaintext, and we recommend they also take
+measures to protect against precomputed dictionary attacks. If the
+encryption algorithm is not itself capable of doing so, the protections can
+often be enhanced by adding a checksum and a confounder.
+
+The suggested format for the data to be encrypted includes a confounder, a
+checksum, the encoded plaintext, and any necessary padding. The msg-seq
+field contains the part of the protocol message described in section 5 which
+is to be encrypted. The confounder, checksum, and padding are all untagged
+and untyped, and their length is exactly sufficient to hold the appropriate
+item. The type and length is implicit and specified by the particular
+encryption type being used (etype). The format for the data to be encrypted
+is described in the following diagram:
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ +-----------+----------+-------------+-----+
+ |confounder | check | msg-seq | pad |
+ +-----------+----------+-------------+-----+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+CipherText ::= ENCRYPTED SEQUENCE {
+ confounder[0] UNTAGGED[35] OCTET STRING(conf_length) OPTIONAL,
+ check[1] UNTAGGED OCTET STRING(checksum_length) OPTIONAL,
+ msg-seq[2] MsgSequence,
+ pad UNTAGGED OCTET STRING(pad_length) OPTIONAL
+}
+
+One generates a random confounder of the appropriate length, placing it in
+confounder; zeroes out check; calculates the appropriate checksum over
+confounder, check, and msg-seq, placing the result in check; adds the
+necessary padding; then encrypts using the specified encryption type and the
+appropriate key.
+
+Unless otherwise specified, a definition of an encryption algorithm that
+specifies a checksum, a length for the confounder field, or an octet
+boundary for padding uses this ciphertext format[36]. Those fields which are
+not specified will be omitted.
+
+In the interest of allowing all implementations using a particular
+encryption type to communicate with all others using that type, the
+specification of an encryption type defines any checksum that is needed as
+part of the encryption process. If an alternative checksum is to be used, a
+new encryption type must be defined.
+
+Some cryptosystems require additional information beyond the key and the
+data to be encrypted. For example, DES, when used in cipher-block-chaining
+mode, requires an initialization vector. If required, the description for
+each encryption type must specify the source of such additional information.
+6.2. Encryption Keys
+
+The sequence below shows the encoding of an encryption key:
+
+ EncryptionKey ::= SEQUENCE {
+ keytype[0] INTEGER,
+ keyvalue[1] OCTET STRING
+ }
+
+keytype
+ This field specifies the type of encryption that is to be performed
+ using the key that follows in the keyvalue field. It will always
+ correspond to the etype to be used to generate or decode the
+ EncryptedData. In cases when multiple algorithms use a common kind of
+ key (e.g., if the encryption algorithm uses an alternate checksum
+ algorithm for an integrity check, or a different chaining mechanism),
+ the keytype provides information needed to determine which algorithm is
+ to be used.
+keyvalue
+ This field contains the key itself, encoded as an octet string.
+
+All negative values for the encryption key type are reserved for local use.
+All non-negative values are reserved for officially assigned type fields and
+interpreta- tions.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+6.3. Encryption Systems
+
+6.3.1. The NULL Encryption System (null)
+
+If no encryption is in use, the encryption system is said to be the NULL
+encryption system. In the NULL encryption system there is no checksum,
+confounder or padding. The ciphertext is simply the plaintext. The NULL Key
+is used by the null encryption system and is zero octets in length, with
+keytype zero (0).
+
+6.3.2. DES in CBC mode with a CRC-32 checksum (des-cbc-crc)
+
+The des-cbc-crc encryption mode encrypts information under the Data
+Encryption Standard [DES77] using the cipher block chaining mode [DESM80]. A
+CRC-32 checksum (described in ISO 3309 [ISO3309]) is applied to the
+confounder and message sequence (msg-seq) and placed in the cksum field. DES
+blocks are 8 bytes. As a result, the data to be encrypted (the concatenation
+of confounder, checksum, and message) must be padded to an 8 byte boundary
+before encryption. The details of the encryption of this data are identical
+to those for the des-cbc-md5 encryption mode.
+
+Note that, since the CRC-32 checksum is not collision-proof, an attacker
+could use a probabilistic chosen-plaintext attack to generate a valid
+message even if a confounder is used [SG92]. The use of collision-proof
+checksums is recommended for environments where such attacks represent a
+significant threat. The use of the CRC-32 as the checksum for ticket or
+authenticator is no longer mandated as an interoperability requirement for
+Kerberos Version 5 Specification 1 (See section 9.1 for specific details).
+
+6.3.3. DES in CBC mode with an MD4 checksum (des-cbc-md4)
+
+The des-cbc-md4 encryption mode encrypts information under the Data
+Encryption Standard [DES77] using the cipher block chaining mode [DESM80].
+An MD4 checksum (described in [MD492]) is applied to the confounder and
+message sequence (msg-seq) and placed in the cksum field. DES blocks are 8
+bytes. As a result, the data to be encrypted (the concatenation of
+confounder, checksum, and message) must be padded to an 8 byte boundary
+before encryption. The details of the encryption of this data are identical
+to those for the des-cbc-md5 encryption mode.
+
+6.3.4. DES in CBC mode with an MD5 checksum (des-cbc-md5)
+
+The des-cbc-md5 encryption mode encrypts information under the Data
+Encryption Standard [DES77] using the cipher block chaining mode [DESM80].
+An MD5 checksum (described in [MD5-92].) is applied to the confounder and
+message sequence (msg-seq) and placed in the cksum field. DES blocks are 8
+bytes. As a result, the data to be encrypted (the concatenation of
+confounder, checksum, and message) must be padded to an 8 byte boundary
+before encryption.
+
+Plaintext and DES ciphtertext are encoded as blocks of 8 octets which are
+concatenated to make the 64-bit inputs for the DES algorithms. The first
+octet supplies the 8 most significant bits (with the octet's MSbit used as
+the DES input block's MSbit, etc.), the second octet the next 8 bits, ...,
+and the eighth octet supplies the 8 least significant bits.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+Encryption under DES using cipher block chaining requires an additional
+input in the form of an initialization vector. Unless otherwise specified,
+zero should be used as the initialization vector. Kerberos' use of DES
+requires an 8 octet confounder.
+
+The DES specifications identify some 'weak' and 'semi-weak' keys; those keys
+shall not be used for encrypting messages for use in Kerberos. Additionally,
+because of the way that keys are derived for the encryption of checksums,
+keys shall not be used that yield 'weak' or 'semi-weak' keys when
+eXclusive-ORed with the hexadecimal constant F0F0F0F0F0F0F0F0.
+
+A DES key is 8 octets of data, with keytype one (1). This consists of 56
+bits of key, and 8 parity bits (one per octet). The key is encoded as a
+series of 8 octets written in MSB-first order. The bits within the key are
+also encoded in MSB order. For example, if the encryption key is
+(B1,B2,...,B7,P1,B8,...,B14,P2,B15,...,B49,P7,B50,...,B56,P8) where
+B1,B2,...,B56 are the key bits in MSB order, and P1,P2,...,P8 are the parity
+bits, the first octet of the key would be B1,B2,...,B7,P1 (with B1 as the
+MSbit). [See the FIPS 81 introduction for reference.]
+
+String to key transformation
+
+To generate a DES key from a text string (password), a "salt" is
+concatenated to the text string, and then padded with ASCII nulls to an 8
+byte boundary. This "salt" is normally the realm and each component of the
+principal's name appended. However, sometimes different salts are used ---
+for example, when a realm is renamed, or if a user changes her username, or
+for compatibility with Kerberos V4 (whose string-to-key algorithm uses a
+null string for the salt). This string is then fan-folded and eXclusive-ORed
+with itself to form an 8 byte DES key. Before eXclusive-ORing a block, every
+byte is shifted one bit to the left to leave the lowest bit zero. The key is
+the "corrected" by correcting the parity on the key, and if the key matches
+a 'weak' or 'semi-weak' key as described in the DES specification, it is
+eXclusive-ORed with the constant 00000000000000F0. This key is then used to
+generate a DES CBC checksum on the initial string (with the salt appended).
+The result of the CBC checksum is the "corrected" as described above to form
+the result which is return as the key. Pseudocode follows:
+
+ name_to_default_salt(realm, name) {
+ s = realm
+ for(each component in name) {
+ s = s + component;
+ }
+ return s;
+ }
+
+ key_correction(key) {
+ fixparity(key);
+ if (is_weak_key_key(key))
+ key = key XOR 0xF0;
+ return(key);
+ }
+
+ string_to_key(string,salt) {
+
+ odd = 1;
+ s = string + salt;
+ tempkey = NULL;
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ pad(s); /* with nulls to 8 byte boundary */
+ for(8byteblock in s) {
+ if(odd == 0) {
+ odd = 1;
+ reverse(8byteblock)
+ }
+ else odd = 0;
+ left shift every byte in 8byteblock one bit;
+ tempkey = tempkey XOR 8byteblock;
+ }
+ tempkey = key_correction(tempkey);
+ key = key_correction(DES-CBC-check(s,tempkey));
+ return(key);
+ }
+
+6.3.5. Triple DES with HMAC-SHA1 Kerberos Encryption Type with Key
+Derivation [Horowitz]
+
+[*** Note that there are several 3DES varients in use in different Kerberos
+implemenations, updates to this section will be sent to the cat list and
+krb-protocol list prior to the Oslo IETF, including the key derivation and
+non-key derivation varients ***] NOTE: This description currently refers to
+documents, the contents of which might be bettered included by value in this
+spec. The description below was provided by Marc Horowitz, and the form in
+which it will finally appear is yet to be determined. This description is
+included in this version of the draft because it does describe the
+implemenation ready for use with the MIT implementation. Note also that the
+encryption identifier has been left unspecified here because the value from
+Marc Horowitz's spec conflicted with some other impmenentations implemented
+based on perevious versions of the specification.
+
+This encryption type is based on the Triple DES cryptosystem, the HMAC-SHA1
+[Krawczyk96] message authentication algorithm, and key derivation for
+Kerberos V5 [HorowitzB96].
+
+The des3-cbc-hmac-sha1 encryption type has been assigned the value ??. The
+hmac-sha1-des3 checksum type has been assigned the value 12.
+
+Encryption Type des3-cbc-hmac-sha1
+
+EncryptedData using this type must be generated as described in
+[Horowitz96]. The encryption algorithm is Triple DES in Outer-CBC mode. The
+keyed hash algorithm is HMAC-SHA1. Unless otherwise specified, a zero IV
+must be used. If the length of the input data is not a multiple of the block
+size, zero octets must be used to pad the plaintext to the next eight-octet
+boundary. The counfounder must be eight random octets (one block).
+
+Checksum Type hmac-sha1-des3
+
+Checksums using this type must be generated as described in [Horowitz96].
+The keyed hash algorithm is HMAC-SHA1.
+
+Common Requirements
+
+The EncryptionKey value is 24 octets long. The 7 most significant bits of
+each octet contain key bits, and the least significant bit is the inverse of
+the xor of the key bits.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+For the purposes of key derivation, the block size is 64 bits, and the key
+size is 168 bits. The 168 bits output by key derivation are converted to an
+EncryptionKey value as follows. First, the 168 bits are divided into three
+groups of 56 bits, which are expanded individually into 64 bits as follows:
+
+ 1 2 3 4 5 6 7 p
+ 9 10 11 12 13 14 15 p
+17 18 19 20 21 22 23 p
+25 26 27 28 29 30 31 p
+33 34 35 36 37 38 39 p
+41 42 43 44 45 46 47 p
+49 50 51 52 53 54 55 p
+56 48 40 32 24 16 8 p
+
+The "p" bits are parity bits computed over the data bits. The output of the
+three expansions are concatenated to form the EncryptionKey value.
+
+When the HMAC-SHA1 of a string is computed, the key is used in the
+EncryptedKey form.
+
+Key Derivation
+
+In the Kerberos protocol, cryptographic keys are used in a number of places.
+In order to minimize the effect of compromising a key, it is desirable to
+use a different key for each of these places. Key derivation [Horowitz96]
+can be used to construct different keys for each operation from the keys
+transported on the network. For this to be possible, a small change to the
+specification is necessary.
+
+This section specifies a profile for the use of key derivation [Horowitz96]
+with Kerberos. For each place where a key is used, a ``key usage'' must is
+specified for that purpose. The key, key usage, and encryption/checksum type
+together describe the transformation from plaintext to ciphertext, or
+plaintext to checksum.
+
+Key Usage Values
+
+This is a complete list of places keys are used in the kerberos protocol,
+with key usage values and RFC 1510 section numbers:
+
+ 1. AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
+ client key (section 5.4.1)
+ 2. AS-REP Ticket and TGS-REP Ticket (includes tgs session key or
+ application session key), encrypted with the service key
+ (section 5.4.2)
+ 3. AS-REP encrypted part (includes tgs session key or application
+ session key), encrypted with the client key (section 5.4.2)
+ 4. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ session key (section 5.4.1)
+ 5. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ authenticator subkey (section 5.4.1)
+ 6. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
+ with the tgs session key (sections 5.3.2, 5.4.1)
+ 7. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes tgs
+ authenticator subkey), encrypted with the tgs session key
+ (section 5.3.2)
+ 8. TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs session key (section 5.4.2)
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ 9. TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs authenticator subkey (section 5.4.2)
+10. AP-REQ Authenticator cksum, keyed with the application session
+ key (section 5.3.2)
+11. AP-REQ Authenticator (includes application authenticator
+ subkey), encrypted with the application session key (section
+ 5.3.2)
+12. AP-REP encrypted part (includes application session subkey),
+ encrypted with the application session key (section 5.5.2)
+13. KRB-PRIV encrypted part, encrypted with a key chosen by the
+ application (section 5.7.1)
+14. KRB-CRED encrypted part, encrypted with a key chosen by the
+ application (section 5.6.1)
+15. KRB-SAVE cksum, keyed with a key chosen by the application
+ (section 5.8.1)
+18. KRB-ERROR checksum (e-cksum in section 5.9.1)
+19. AD-KDCIssued checksum (ad-checksum in appendix B.1)
+20. Checksum for Mandatory Ticket Extensions (appendix B.6)
+21. Checksum in Authorization Data in Ticket Extensions (appendix B.7)
+
+Key usage values between 1024 and 2047 (inclusive) are reserved for
+application use. Applications should use even values for encryption and odd
+values for checksums within this range.
+
+A few of these key usages need a little clarification. A service which
+receives an AP-REQ has no way to know if the enclosed Ticket was part of an
+AS-REP or TGS-REP. Therefore, key usage 2 must always be used for generating
+a Ticket, whether it is in response to an AS- REQ or TGS-REQ.
+
+There might exist other documents which define protocols in terms of the
+RFC1510 encryption types or checksum types. Such documents would not know
+about key usages. In order that these documents continue to be meaningful
+until they are updated, key usages 1024 and 1025 must be used to derive keys
+for encryption and checksums, respectively. New protocols defined in terms
+of the Kerberos encryption and checksum types should use their own key
+usages. Key usages may be registered with IANA to avoid conflicts. Key
+usages must be unsigned 32 bit integers. Zero is not permitted.
+
+Defining Cryptosystems Using Key Derivation
+
+Kerberos requires that the ciphertext component of EncryptedData be
+tamper-resistant as well as confidential. This implies encryption and
+integrity functions, which must each use their own separate keys. So, for
+each key usage, two keys must be generated, one for encryption (Ke), and one
+for integrity (Ki):
+
+ Ke = DK(protocol key, key usage | 0xAA)
+ Ki = DK(protocol key, key usage | 0x55)
+
+where the protocol key is from the EncryptionKey from the wire protocol, and
+the key usage is represented as a 32 bit integer in network byte order. The
+ciphertest must be generated from the plaintext as follows:
+
+ ciphertext = E(Ke, confounder | plaintext | padding) |
+ H(Ki, confounder | plaintext | padding)
+
+The confounder and padding are specific to the encryption algorithm E.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+When generating a checksum only, there is no need for a confounder or
+padding. Again, a new key (Kc) must be used. Checksums must be generated
+from the plaintext as follows:
+
+ Kc = DK(protocol key, key usage | 0x99)
+
+ MAC = H(Kc, plaintext)
+
+Note that each enctype is described by an encryption algorithm E and a keyed
+hash algorithm H, and each checksum type is described by a keyed hash
+algorithm H. HMAC, with an appropriate hash, is recommended for use as H.
+
+Key Derivation from Passwords
+
+The well-known constant for password key derivation must be the byte string
+{0x6b 0x65 0x72 0x62 0x65 0x72 0x6f 0x73}. These values correspond to the
+ASCII encoding for the string "kerberos".
+
+6.4. Checksums
+
+The following is the ASN.1 definition used for a checksum:
+
+ Checksum ::= SEQUENCE {
+ cksumtype[0] INTEGER,
+ checksum[1] OCTET STRING
+ }
+
+cksumtype
+ This field indicates the algorithm used to generate the accompanying
+ checksum.
+checksum
+ This field contains the checksum itself, encoded as an octet string.
+
+Detailed specification of selected checksum types appear later in this
+section. Negative values for the checksum type are reserved for local use.
+All non-negative values are reserved for officially assigned type fields and
+interpretations.
+
+Checksums used by Kerberos can be classified by two properties: whether they
+are collision-proof, and whether they are keyed. It is infeasible to find
+two plaintexts which generate the same checksum value for a collision-proof
+checksum. A key is required to perturb or initialize the algorithm in a
+keyed checksum. To prevent message-stream modification by an active
+attacker, unkeyed checksums should only be used when the checksum and
+message will be subsequently encrypted (e.g. the checksums defined as part
+of the encryption algorithms covered earlier in this section).
+
+Collision-proof checksums can be made tamper-proof if the checksum value is
+encrypted before inclusion in a message. In such cases, the composition of
+the checksum and the encryption algorithm must be considered a separate
+checksum algorithm (e.g. RSA-MD5 encrypted using DES is a new checksum
+algorithm of type RSA-MD5-DES). For most keyed checksums, as well as for the
+encrypted forms of unkeyed collision-proof checksums, Kerberos prepends a
+confounder before the checksum is calculated.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+6.4.1. The CRC-32 Checksum (crc32)
+
+The CRC-32 checksum calculates a checksum based on a cyclic redundancy check
+as described in ISO 3309 [ISO3309]. The resulting checksum is four (4)
+octets in length. The CRC-32 is neither keyed nor collision-proof. The use
+of this checksum is not recommended. An attacker using a probabilistic
+chosen-plaintext attack as described in [SG92] might be able to generate an
+alternative message that satisfies the checksum. The use of collision-proof
+checksums is recommended for environments where such attacks represent a
+significant threat.
+
+6.4.2. The RSA MD4 Checksum (rsa-md4)
+
+The RSA-MD4 checksum calculates a checksum using the RSA MD4 algorithm
+[MD4-92]. The algorithm takes as input an input message of arbitrary length
+and produces as output a 128-bit (16 octet) checksum. RSA-MD4 is believed to
+be collision-proof.
+
+6.4.3. RSA MD4 Cryptographic Checksum Using DES (rsa-md4-des)
+
+The RSA-MD4-DES checksum calculates a keyed collision-proof checksum by
+prepending an 8 octet confounder before the text, applying the RSA MD4
+checksum algorithm, and encrypting the confounder and the checksum using DES
+in cipher-block-chaining (CBC) mode using a variant of the key, where the
+variant is computed by eXclusive-ORing the key with the constant
+F0F0F0F0F0F0F0F0[39]. The initialization vector should be zero. The
+resulting checksum is 24 octets long (8 octets of which are redundant). This
+checksum is tamper-proof and believed to be collision-proof.
+
+The DES specifications identify some weak keys' and 'semi-weak keys'; those
+keys shall not be used for generating RSA-MD4 checksums for use in Kerberos.
+
+The format for the checksum is described in the follow- ing diagram:
+
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+| des-cbc(confounder + rsa-md4(confounder+msg),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+rsa-md4-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(16)
+}
+
+6.4.4. The RSA MD5 Checksum (rsa-md5)
+
+The RSA-MD5 checksum calculates a checksum using the RSA MD5 algorithm.
+[MD5-92]. The algorithm takes as input an input message of arbitrary length
+and produces as output a 128-bit (16 octet) checksum. RSA-MD5 is believed to
+be collision-proof.
+
+6.4.5. RSA MD5 Cryptographic Checksum Using DES (rsa-md5-des)
+
+The RSA-MD5-DES checksum calculates a keyed collision-proof checksum by
+prepending an 8 octet confounder before the text, applying the RSA MD5
+checksum algorithm, and encrypting the confounder and the checksum using DES
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+in cipher-block-chaining (CBC) mode using a variant of the key, where the
+variant is computed by eXclusive-ORing the key with the hexadecimal constant
+F0F0F0F0F0F0F0F0. The initialization vector should be zero. The resulting
+checksum is 24 octets long (8 octets of which are redundant). This checksum
+is tamper-proof and believed to be collision-proof.
+
+The DES specifications identify some 'weak keys' and 'semi-weak keys'; those
+keys shall not be used for encrypting RSA-MD5 checksums for use in Kerberos.
+
+The format for the checksum is described in the following diagram:
+
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+| des-cbc(confounder + rsa-md5(confounder+msg),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+rsa-md5-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(16)
+}
+
+6.4.6. DES cipher-block chained checksum (des-mac)
+
+The DES-MAC checksum is computed by prepending an 8 octet confounder to the
+plaintext, performing a DES CBC-mode encryption on the result using the key
+and an initialization vector of zero, taking the last block of the
+ciphertext, prepending the same confounder and encrypting the pair using DES
+in cipher-block-chaining (CBC) mode using a a variant of the key, where the
+variant is computed by eXclusive-ORing the key with the hexadecimal constant
+F0F0F0F0F0F0F0F0. The initialization vector should be zero. The resulting
+checksum is 128 bits (16 octets) long, 64 bits of which are redundant. This
+checksum is tamper-proof and collision-proof.
+
+The format for the checksum is described in the following diagram:
+
++--+--+--+--+--+--+--+--+-----+-----+-----+-----+-----+-----+-----+-----+
+| des-cbc(confounder + des-mac(conf+msg,iv=0,key),key=var(key),iv=0) |
++--+--+--+--+--+--+--+--+-----+-----+-----+-----+-----+-----+-----+-----+
+
+The format cannot be described in ASN.1, but for those who prefer an
+ASN.1-like notation:
+
+des-mac-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(8)
+}
+
+The DES specifications identify some 'weak' and 'semi-weak' keys; those keys
+shall not be used for generating DES-MAC checksums for use in Kerberos, nor
+shall a key be used whose variant is 'weak' or 'semi-weak'.
+
+6.4.7. RSA MD4 Cryptographic Checksum Using DES alternative (rsa-md4-des-k)
+
+The RSA-MD4-DES-K checksum calculates a keyed collision-proof checksum by
+applying the RSA MD4 checksum algorithm and encrypting the results using DES
+in cipher-block-chaining (CBC) mode using a DES key as both key and
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+initialization vector. The resulting checksum is 16 octets long. This
+checksum is tamper-proof and believed to be collision-proof. Note that this
+checksum type is the old method for encoding the RSA-MD4-DES checksum and it
+is no longer recommended.
+
+6.4.8. DES cipher-block chained checksum alternative (des-mac-k)
+
+The DES-MAC-K checksum is computed by performing a DES CBC-mode encryption
+of the plaintext, and using the last block of the ciphertext as the checksum
+value. It is keyed with an encryption key and an initialization vector; any
+uses which do not specify an additional initialization vector will use the
+key as both key and initialization vector. The resulting checksum is 64 bits
+(8 octets) long. This checksum is tamper-proof and collision-proof. Note
+that this checksum type is the old method for encoding the DES-MAC checksum
+and it is no longer recommended. The DES specifications identify some 'weak
+keys' and 'semi-weak keys'; those keys shall not be used for generating
+DES-MAC checksums for use in Kerberos.
+
+7. Naming Constraints
+
+7.1. Realm Names
+
+Although realm names are encoded as GeneralStrings and although a realm can
+technically select any name it chooses, interoperability across realm
+boundaries requires agreement on how realm names are to be assigned, and
+what information they imply.
+
+To enforce these conventions, each realm must conform to the conventions
+itself, and it must require that any realms with which inter-realm keys are
+shared also conform to the conventions and require the same from its
+neighbors.
+
+Kerberos realm names are case sensitive. Realm names that differ only in the
+case of the characters are not equivalent. There are presently four styles
+of realm names: domain, X500, other, and reserved. Examples of each style
+follow:
+
+ domain: ATHENA.MIT.EDU (example)
+ X500: C=US/O=OSF (example)
+ other: NAMETYPE:rest/of.name=without-restrictions (example)
+ reserved: reserved, but will not conflict with above
+
+Domain names must look like domain names: they consist of components
+separated by periods (.) and they contain neither colons (:) nor slashes
+(/). Domain names must be converted to upper case when used as realm names.
+
+X.500 names contain an equal (=) and cannot contain a colon (:) before the
+equal. The realm names for X.500 names will be string representations of the
+names with components separated by slashes. Leading and trailing slashes
+will not be included.
+
+Names that fall into the other category must begin with a prefix that
+contains no equal (=) or period (.) and the prefix must be followed by a
+colon (:) and the rest of the name. All prefixes must be assigned before
+they may be used. Presently none are assigned.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+The reserved category includes strings which do not fall into the first
+three categories. All names in this category are reserved. It is unlikely
+that names will be assigned to this category unless there is a very strong
+argument for not using the 'other' category.
+
+These rules guarantee that there will be no conflicts between the various
+name styles. The following additional constraints apply to the assignment of
+realm names in the domain and X.500 categories: the name of a realm for the
+domain or X.500 formats must either be used by the organization owning (to
+whom it was assigned) an Internet domain name or X.500 name, or in the case
+that no such names are registered, authority to use a realm name may be
+derived from the authority of the parent realm. For example, if there is no
+domain name for E40.MIT.EDU, then the administrator of the MIT.EDU realm can
+authorize the creation of a realm with that name.
+
+This is acceptable because the organization to which the parent is assigned
+is presumably the organization authorized to assign names to its children in
+the X.500 and domain name systems as well. If the parent assigns a realm
+name without also registering it in the domain name or X.500 hierarchy, it
+is the parent's responsibility to make sure that there will not in the
+future exists a name identical to the realm name of the child unless it is
+assigned to the same entity as the realm name.
+
+7.2. Principal Names
+
+As was the case for realm names, conventions are needed to ensure that all
+agree on what information is implied by a principal name. The name-type
+field that is part of the principal name indicates the kind of information
+implied by the name. The name-type should be treated as a hint. Ignoring the
+name type, no two names can be the same (i.e. at least one of the
+components, or the realm, must be different). The following name types are
+defined:
+
+ name-type value meaning
+
+ NT-UNKNOWN 0 Name type not known
+ NT-PRINCIPAL 1 General principal name (e.g. username, or DCE
+principal)
+ NT-SRV-INST 2 Service and other unique instance (krbtgt)
+ NT-SRV-HST 3 Service with host name as instance (telnet,
+rcommands)
+ NT-SRV-XHST 4 Service with slash-separated host name components
+ NT-UID 5 Unique ID
+ NT-X500-PRINCIPAL 6 Encoded X.509 Distingished name [RFC 1779]
+
+When a name implies no information other than its uniqueness at a particular
+time the name type PRINCIPAL should be used. The principal name type should
+be used for users, and it might also be used for a unique server. If the
+name is a unique machine generated ID that is guaranteed never to be
+reassigned then the name type of UID should be used (note that it is
+generally a bad idea to reassign names of any type since stale entries might
+remain in access control lists).
+
+If the first component of a name identifies a service and the remaining
+components identify an instance of the service in a server specified manner,
+then the name type of SRV-INST should be used. An example of this name type
+is the Kerberos ticket-granting service whose name has a first component of
+krbtgt and a second component identifying the realm for which the ticket is
+valid.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+If instance is a single component following the service name and the
+instance identifies the host on which the server is running, then the name
+type SRV-HST should be used. This type is typically used for Internet
+services such as telnet and the Berkeley R commands. If the separate
+components of the host name appear as successive components following the
+name of the service, then the name type SRV-XHST should be used. This type
+might be used to identify servers on hosts with X.500 names where the slash
+(/) might otherwise be ambiguous.
+
+A name type of NT-X500-PRINCIPAL should be used when a name from an X.509
+certificiate is translated into a Kerberos name. The encoding of the X.509
+name as a Kerberos principal shall conform to the encoding rules specified
+in RFC 2253.
+
+A name type of UNKNOWN should be used when the form of the name is not
+known. When comparing names, a name of type UNKNOWN will match principals
+authenticated with names of any type. A principal authenticated with a name
+of type UNKNOWN, however, will only match other names of type UNKNOWN.
+
+Names of any type with an initial component of 'krbtgt' are reserved for the
+Kerberos ticket granting service. See section 8.2.3 for the form of such
+names.
+
+7.2.1. Name of server principals
+
+The principal identifier for a server on a host will generally be composed
+of two parts: (1) the realm of the KDC with which the server is registered,
+and (2) a two-component name of type NT-SRV-HST if the host name is an
+Internet domain name or a multi-component name of type NT-SRV-XHST if the
+name of the host is of a form such as X.500 that allows slash (/)
+separators. The first component of the two- or multi-component name will
+identify the service and the latter components will identify the host. Where
+the name of the host is not case sensitive (for example, with Internet
+domain names) the name of the host must be lower case. If specified by the
+application protocol for services such as telnet and the Berkeley R commands
+which run with system privileges, the first component may be the string
+'host' instead of a service specific identifier. When a host has an official
+name and one or more aliases, the official name of the host must be used
+when constructing the name of the server principal.
+
+8. Constants and other defined values
+
+8.1. Host address types
+
+All negative values for the host address type are reserved for local use.
+All non-negative values are reserved for officially assigned type fields and
+interpretations.
+
+The values of the types for the following addresses are chosen to match the
+defined address family constants in the Berkeley Standard Distributions of
+Unix. They can be found in with symbolic names AF_xxx (where xxx is an
+abbreviation of the address family name).
+
+Internet (IPv4) Addresses
+
+Internet (IPv4) addresses are 32-bit (4-octet) quantities, encoded in MSB
+order. The type of IPv4 addresses is two (2).
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+Internet (IPv6) Addresses [Westerlund]
+
+IPv6 addresses are 128-bit (16-octet) quantities, encoded in MSB order. The
+type of IPv6 addresses is twenty-four (24). [RFC1883] [RFC1884]. The
+following addresses (see [RFC1884]) MUST not appear in any Kerberos packet:
+
+ * the Unspecified Address
+ * the Loopback Address
+ * Link-Local addresses
+
+IPv4-mapped IPv6 addresses MUST be represented as addresses of type 2.
+
+CHAOSnet addresses
+
+CHAOSnet addresses are 16-bit (2-octet) quantities, encoded in MSB order.
+The type of CHAOSnet addresses is five (5).
+
+ISO addresses
+
+ISO addresses are variable-length. The type of ISO addresses is seven (7).
+
+Xerox Network Services (XNS) addresses
+
+XNS addresses are 48-bit (6-octet) quantities, encoded in MSB order. The
+type of XNS addresses is six (6).
+
+AppleTalk Datagram Delivery Protocol (DDP) addresses
+
+AppleTalk DDP addresses consist of an 8-bit node number and a 16-bit network
+number. The first octet of the address is the node number; the remaining two
+octets encode the network number in MSB order. The type of AppleTalk DDP
+addresses is sixteen (16).
+
+DECnet Phase IV addresses
+
+DECnet Phase IV addresses are 16-bit addresses, encoded in LSB order. The
+type of DECnet Phase IV addresses is twelve (12).
+
+Netbios addresses
+
+Netbios addresses are 16-octet addresses typically composed of 1 to 15
+characters, trailing blank (ascii char 20) filled, with a 16th octet of 0x0.
+The type of Netbios addresses is 20 (0x14).
+
+8.2. KDC messages
+
+8.2.1. UDP/IP transport
+
+When contacting a Kerberos server (KDC) for a KRB_KDC_REQ request using UDP
+IP transport, the client shall send a UDP datagram containing only an
+encoding of the request to port 88 (decimal) at the KDC's IP address; the
+KDC will respond with a reply datagram containing only an encoding of the
+reply message (either a KRB_ERROR or a KRB_KDC_REP) to the sending port at
+the sender's IP address. Kerberos servers supporting IP transport must
+accept UDP requests on port 88 (decimal). The response to a request made
+through UDP/IP transport must also use UDP/IP transport.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+8.2.2. TCP/IP transport [Westerlund,Danielsson]
+
+Kerberos servers (KDC's) should accept TCP requests on port 88 (decimal) and
+clients should support the sending of TCP requests on port 88 (decimal).
+When the KRB_KDC_REQ message is sent to the KDC over a TCP stream, a new
+connection will be established for each authentication exchange (request and
+response). The KRB_KDC_REP or KRB_ERROR message will be returned to the
+client on the same TCP stream that was established for the request. The
+response to a request made through TCP/IP transport must also use TCP/IP
+transport. Implementors should note that some extentions to the Kerberos
+protocol will not work if any implementation not supporting the TCP
+transport is involved (client or KDC). Implementors are strongly urged to
+support the TCP transport on both the client and server and are advised that
+the current notation of "should" support will likely change in the future to
+must support. The KDC may close the TCP stream after sending a response, but
+may leave the stream open if it expects a followup - in which case it may
+close the stream at any time if resource constratints or other factors make
+it desirable to do so. Care must be taken in managing TCP/IP connections
+with the KDC to prevent denial of service attacks based on the number of
+TCP/IP connections with the KDC that remain open. If multiple exchanges with
+the KDC are needed for certain forms of preauthentication, multiple TCP
+connections may be required. A client may close the stream after receiving
+response, and should close the stream if it does not expect to send followup
+messages. The client must be prepared to have the stream closed by the KDC
+at anytime, in which case it must simply connect again when it is ready to
+send subsequent messages.
+
+The first four octets of the TCP stream used to transmit the request request
+will encode in network byte order the length of the request (KRB_KDC_REQ),
+and the length will be followed by the request itself. The response will
+similarly be preceeded by a 4 octet encoding in network byte order of the
+length of the KRB_KDC_REP or the KRB_ERROR message and will be followed by
+the KRB_KDC_REP or the KRB_ERROR response. If the sign bit is set on the
+integer represented by the first 4 octets, then the next 4 octets will be
+read, extending the length of the field by another 4 octets (less the sign
+bit which is reserved for future expansion).
+
+8.2.3. OSI transport
+
+During authentication of an OSI client to an OSI server, the mutual
+authentication of an OSI server to an OSI client, the transfer of
+credentials from an OSI client to an OSI server, or during exchange of
+private or integrity checked messages, Kerberos protocol messages may be
+treated as opaque objects and the type of the authentication mechanism will
+be:
+
+OBJECT IDENTIFIER ::= {iso (1), org(3), dod(6),internet(1),
+ security(5),kerberosv5(2)}
+
+Depending on the situation, the opaque object will be an authentication
+header (KRB_AP_REQ), an authentication reply (KRB_AP_REP), a safe message
+(KRB_SAFE), a private message (KRB_PRIV), or a credentials message
+(KRB_CRED). The opaque data contains an application code as specified in the
+ASN.1 description for each message. The application code may be used by
+Kerberos to determine the message type.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+8.2.3. Name of the TGS
+
+The principal identifier of the ticket-granting service shall be composed of
+three parts: (1) the realm of the KDC issuing the TGS ticket (2) a two-part
+name of type NT-SRV-INST, with the first part "krbtgt" and the second part
+the name of the realm which will accept the ticket-granting ticket. For
+example, a ticket-granting ticket issued by the ATHENA.MIT.EDU realm to be
+used to get tickets from the ATHENA.MIT.EDU KDC has a principal identifier
+of "ATHENA.MIT.EDU" (realm), ("krbtgt", "ATHENA.MIT.EDU") (name). A
+ticket-granting ticket issued by the ATHENA.MIT.EDU realm to be used to get
+tickets from the MIT.EDU realm has a principal identifier of
+"ATHENA.MIT.EDU" (realm), ("krbtgt", "MIT.EDU") (name).
+
+8.3. Protocol constants and associated values
+
+The following tables list constants used in the protocol and defines their
+meanings. Ranges are specified in the "specification" section that limit the
+values of constants for which values are defined here. This allows
+implementations to make assumptions about the maximum values that will be
+received for these constants. Implementation receiving values outside the
+range specified in the "specification" section may reject the request, but
+they must recover cleanly.
+
+Encryption type etype value block size minimum pad size confounder
+size
+NULL 0 1 0 0
+des-cbc-crc 1 8 4 8
+des-cbc-md4 2 8 0 8
+des-cbc-md5 3 8 0 8
+ 4
+des3-cbc-md5 5 8 0 8
+ 6
+des3-cbc-sha1 7 8 0 8
+sign-dsa-generate 8
+(old-pkinit-will-remove)
+dsaWithSHA1-CmsOID 9 (pkinit)
+md5WithRSAEncryption-CmsOID 10 (pkinit)
+sha1WithRSAEncryption-CmsOID 11 (pkinit)
+rc2CBC-EnvOID 12 (pkinit)
+rsaEncryption-EnvOID 13 (pkinit from PKCS#1
+v1.5)
+rsaES-OAEP-ENV-OID 14 (pkinit from PKCS#1
+v2.0)
+des-ede3-cbc-Env-OID 15 (pkinit)
+des3kd-cbc-sha1 ?? 8 0 8
+ENCTYPE_PK_CROSS 48 (reserved for pkcross)
+ 0x8003
+
+Checksum type sumtype value checksum size
+CRC32 1 4
+rsa-md4 2 16
+rsa-md4-des 3 24
+des-mac 4 16
+des-mac-k 5 8
+rsa-md4-des-k 6 16
+rsa-md5 7 16
+rsa-md5-des 8 24
+rsa-md5-des3 9 24
+hmac-sha1-des3 12 20 (I had this as 10, is it
+12)
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+padata type padata-type value
+
+PA-TGS-REQ 1
+PA-ENC-TIMESTAMP 2
+PA-PW-SALT 3
+ 4
+PA-ENC-UNIX-TIME 5
+PA-SANDIA-SECUREID 6
+PA-SESAME 7
+PA-OSF-DCE 8
+PA-CYBERSAFE-SECUREID 9
+PA-AFS3-SALT 10
+PA-ETYPE-INFO 11
+SAM-CHALLENGE 12 (sam/otp)
+SAM-RESPONSE 13 (sam/otp)
+PA-PK-AS-REQ 14 (pkinit)
+PA-PK-AS-REP 15 (pkinit)
+PA-PK-AS-SIGN 16 (***remove on 7/14***)
+PA-PK-KEY-REQ 17 (***remove on 7/14***)
+PA-PK-KEY-REP 18 (***remove on 7/14***)
+PA-USE-SPECIFIED-KVNO 20
+SAM-REDIRECT 21 (sam/otp)
+PA-GET-FROM-TYPED-DATA 22
+
+data-type value form of typed-data
+
+ 1-21
+TD-PADATA 22
+TD-PKINIT-CMS-CERTIFICATES 101 CertificateSet from CMS
+TD-KRB-PRINCIPAL 102
+TD-KRB-REALM 103
+TD-TRUSTED-CERTIFIERS 104
+TD-CERTIFICATE-INDEX 105
+
+authorization data type ad-type value
+AD-IF-RELEVANT 1
+AD-INTENDED-FOR-SERVER 2
+AD-INTENDED-FOR-APPLICATION-CLASS 3
+AD-KDC-ISSUED 4
+AD-OR 5
+AD-MANDATORY-TICKET-EXTENSIONS 6
+AD-IN-TICKET-EXTENSIONS 7
+reserved values 8-63
+OSF-DCE 64
+SESAME 65
+
+Ticket Extension Types
+
+TE-TYPE-NULL 0 Null ticket extension
+TE-TYPE-EXTERNAL-ADATA 1 Integrity protected authorization data
+ 2 TE-TYPE-PKCROSS-KDC (I have reservations)
+TE-TYPE-PKCROSS-CLIENT 3 PKCROSS cross realm key ticket
+TE-TYPE-CYBERSAFE-EXT 4 Assigned to CyberSafe Corp
+ 5 TE-TYPE-DEST-HOST (I have reservations)
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+alternate authentication type method-type value
+reserved values 0-63
+ATT-CHALLENGE-RESPONSE 64
+
+transited encoding type tr-type value
+DOMAIN-X500-COMPRESS 1
+reserved values all others
+
+Label Value Meaning or MIT code
+
+pvno 5 current Kerberos protocol version number
+
+message types
+
+KRB_AS_REQ 10 Request for initial authentication
+KRB_AS_REP 11 Response to KRB_AS_REQ request
+KRB_TGS_REQ 12 Request for authentication based on TGT
+KRB_TGS_REP 13 Response to KRB_TGS_REQ request
+KRB_AP_REQ 14 application request to server
+KRB_AP_REP 15 Response to KRB_AP_REQ_MUTUAL
+KRB_SAFE 20 Safe (checksummed) application message
+KRB_PRIV 21 Private (encrypted) application message
+KRB_CRED 22 Private (encrypted) message to forward
+credentials
+KRB_ERROR 30 Error response
+
+name types
+
+KRB_NT_UNKNOWN 0 Name type not known
+KRB_NT_PRINCIPAL 1 Just the name of the principal as in DCE, or for
+users
+KRB_NT_SRV_INST 2 Service and other unique instance (krbtgt)
+KRB_NT_SRV_HST 3 Service with host name as instance (telnet,
+rcommands)
+KRB_NT_SRV_XHST 4 Service with host as remaining components
+KRB_NT_UID 5 Unique ID
+KRB_NT_X500_PRINCIPAL 6 Encoded X.509 Distingished name [RFC 2253]
+
+error codes
+
+KDC_ERR_NONE 0 No error
+KDC_ERR_NAME_EXP 1 Client's entry in database has expired
+KDC_ERR_SERVICE_EXP 2 Server's entry in database has expired
+KDC_ERR_BAD_PVNO 3 Requested protocol version # not
+supported
+KDC_ERR_C_OLD_MAST_KVNO 4 Client's key encrypted in old master key
+KDC_ERR_S_OLD_MAST_KVNO 5 Server's key encrypted in old master key
+KDC_ERR_C_PRINCIPAL_UNKNOWN 6 Client not found in Kerberos database
+KDC_ERR_S_PRINCIPAL_UNKNOWN 7 Server not found in Kerberos database
+KDC_ERR_PRINCIPAL_NOT_UNIQUE 8 Multiple principal entries in database
+KDC_ERR_NULL_KEY 9 The client or server has a null key
+KDC_ERR_CANNOT_POSTDATE 10 Ticket not eligible for postdating
+KDC_ERR_NEVER_VALID 11 Requested start time is later than end
+time
+KDC_ERR_POLICY 12 KDC policy rejects request
+KDC_ERR_BADOPTION 13 KDC cannot accommodate requested option
+KDC_ERR_ETYPE_NOSUPP 14 KDC has no support for encryption type
+KDC_ERR_SUMTYPE_NOSUPP 15 KDC has no support for checksum type
+KDC_ERR_PADATA_TYPE_NOSUPP 16 KDC has no support for padata type
+KDC_ERR_TRTYPE_NOSUPP 17 KDC has no support for transited type
+KDC_ERR_CLIENT_REVOKED 18 Clients credentials have been revoked
+KDC_ERR_SERVICE_REVOKED 19 Credentials for server have been revoked
+KDC_ERR_TGT_REVOKED 20 TGT has been revoked
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+KDC_ERR_CLIENT_NOTYET 21 Client not yet valid - try again later
+KDC_ERR_SERVICE_NOTYET 22 Server not yet valid - try again later
+KDC_ERR_KEY_EXPIRED 23 Password has expired - change password
+KDC_ERR_PREAUTH_FAILED 24 Pre-authentication information was
+invalid
+KDC_ERR_PREAUTH_REQUIRED 25 Additional pre-authenticationrequired
+[40]
+KDC_ERR_SERVER_NOMATCH 26 Requested server and ticket don't match
+KDC_ERR_MUST_USE_USER2USER 27 Server principal valid for user2user
+only
+KDC_ERR_PATH_NOT_ACCPETED 28 KDC Policy rejects transited path
+KDC_ERR_SVC_UNAVAILABLE 29 A service is not available
+KRB_AP_ERR_BAD_INTEGRITY 31 Integrity check on decrypted field
+failed
+KRB_AP_ERR_TKT_EXPIRED 32 Ticket expired
+KRB_AP_ERR_TKT_NYV 33 Ticket not yet valid
+KRB_AP_ERR_REPEAT 34 Request is a replay
+KRB_AP_ERR_NOT_US 35 The ticket isn't for us
+KRB_AP_ERR_BADMATCH 36 Ticket and authenticator don't match
+KRB_AP_ERR_SKEW 37 Clock skew too great
+KRB_AP_ERR_BADADDR 38 Incorrect net address
+KRB_AP_ERR_BADVERSION 39 Protocol version mismatch
+KRB_AP_ERR_MSG_TYPE 40 Invalid msg type
+KRB_AP_ERR_MODIFIED 41 Message stream modified
+KRB_AP_ERR_BADORDER 42 Message out of order
+KRB_AP_ERR_BADKEYVER 44 Specified version of key is not
+available
+KRB_AP_ERR_NOKEY 45 Service key not available
+KRB_AP_ERR_MUT_FAIL 46 Mutual authentication failed
+KRB_AP_ERR_BADDIRECTION 47 Incorrect message direction
+KRB_AP_ERR_METHOD 48 Alternative authentication method
+required
+KRB_AP_ERR_BADSEQ 49 Incorrect sequence number in message
+KRB_AP_ERR_INAPP_CKSUM 50 Inappropriate type of checksum in
+message
+KRB_AP_PATH_NOT_ACCEPTED 51 Policy rejects transited path
+KRB_ERR_RESPONSE_TOO_BIG 52 Response too big for UDP, retry with TCP
+KRB_ERR_GENERIC 60 Generic error (description in e-text)
+KRB_ERR_FIELD_TOOLONG 61 Field is too long for this
+implementation
+KDC_ERROR_CLIENT_NOT_TRUSTED 62 (pkinit)
+KDC_ERROR_KDC_NOT_TRUSTED 63 (pkinit)
+KDC_ERROR_INVALID_SIG 64 (pkinit)
+KDC_ERR_KEY_TOO_WEAK 65 (pkinit)
+KDC_ERR_CERTIFICATE_MISMATCH 66 (pkinit)
+KRB_AP_ERR_NO_TGT 67 (user-to-user)
+KDC_ERR_WRONG_REALM 68 (user-to-user)
+KRB_AP_ERR_USER_TO_USER_REQUIRED 69 (user-to-user)
+KDC_ERR_CANT_VERIFY_CERTIFICATE 70 (pkinit)
+KDC_ERR_INVALID_CERTIFICATE 71 (pkinit)
+KDC_ERR_REVOKED_CERTIFICATE 72 (pkinit)
+KDC_ERR_REVOCATION_STATUS_UNKNOWN 73 (pkinit)
+KDC_ERR_REVOCATION_STATUS_UNAVAILABLE 74 (pkinit)
+KDC_ERR_CLIENT_NAME_MISMATCH 75 (pkinit)
+KDC_ERR_KDC_NAME_MISMATCH 76 (pkinit)
+
+9. Interoperability requirements
+
+Version 5 of the Kerberos protocol supports a myriad of options. Among these
+are multiple encryption and checksum types, alternative encoding schemes for
+the transited field, optional mechanisms for pre-authentication, the
+handling of tickets with no addresses, options for mutual authentication,
+user to user authentication, support for proxies, forwarding, postdating,
+and renewing tickets, the format of realm names, and the handling of
+authorization data.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+In order to ensure the interoperability of realms, it is necessary to define
+a minimal configuration which must be supported by all implementations. This
+minimal configuration is subject to change as technology does. For example,
+if at some later date it is discovered that one of the required encryption
+or checksum algorithms is not secure, it will be replaced.
+
+9.1. Specification 2
+
+This section defines the second specification of these options.
+Implementations which are configured in this way can be said to support
+Kerberos Version 5 Specification 2 (5.1). Specification 1 (depricated) may
+be found in RFC1510.
+
+Transport
+
+TCP/IP and UDP/IP transport must be supported by KDCs claiming conformance
+to specification 2. Kerberos clients claiming conformance to specification 2
+must support UDP/IP transport for messages with the KDC and should support
+TCP/IP transport.
+
+Encryption and checksum methods
+
+The following encryption and checksum mechanisms must be supported.
+Implementations may support other mechanisms as well, but the additional
+mechanisms may only be used when communicating with principals known to also
+support them: This list is to be determined. [***This section will change,
+and alternatives will be sent to the cat and krb-protocol list prior to the
+Oslo IETF - change will be made 7/14/99 ***]
+
+Encryption: DES-CBC-MD5
+Checksums: CRC-32, DES-MAC, DES-MAC-K, and DES-MD5
+
+Realm Names
+
+All implementations must understand hierarchical realms in both the Internet
+Domain and the X.500 style. When a ticket granting ticket for an unknown
+realm is requested, the KDC must be able to determine the names of the
+intermediate realms between the KDCs realm and the requested realm.
+
+Transited field encoding
+
+DOMAIN-X500-COMPRESS (described in section 3.3.3.2) must be supported.
+Alternative encodings may be supported, but they may be used only when that
+encoding is supported by ALL intermediate realms.
+
+Pre-authentication methods
+
+The TGS-REQ method must be supported. The TGS-REQ method is not used on the
+initial request. The PA-ENC-TIMESTAMP method must be supported by clients
+but whether it is enabled by default may be determined on a realm by realm
+basis. If not used in the initial request and the error
+KDC_ERR_PREAUTH_REQUIRED is returned specifying PA-ENC-TIMESTAMP as an
+acceptable method, the client should retry the initial request using the
+PA-ENC-TIMESTAMP preauthentication method. Servers need not support the
+PA-ENC-TIMESTAMP method, but if not supported the server should ignore the
+presence of PA-ENC-TIMESTAMP pre-authentication in a request.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+Mutual authentication
+
+Mutual authentication (via the KRB_AP_REP message) must be supported.
+
+Ticket addresses and flags
+
+All KDC's must pass on tickets that carry no addresses (i.e. if a TGT
+contains no addresses, the KDC will return derivative tickets), but each
+realm may set its own policy for issuing such tickets, and each application
+server will set its own policy with respect to accepting them.
+
+Proxies and forwarded tickets must be supported. Individual realms and
+application servers can set their own policy on when such tickets will be
+accepted.
+
+All implementations must recognize renewable and postdated tickets, but need
+not actually implement them. If these options are not supported, the
+starttime and endtime in the ticket shall specify a ticket's entire useful
+life. When a postdated ticket is decoded by a server, all implementations
+shall make the presence of the postdated flag visible to the calling server.
+
+User-to-user authentication
+
+Support for user to user authentication (via the ENC-TKT-IN-SKEY KDC option)
+must be provided by implementations, but individual realms may decide as a
+matter of policy to reject such requests on a per-principal or realm-wide
+basis.
+
+Authorization data
+
+Implementations must pass all authorization data subfields from
+ticket-granting tickets to any derivative tickets unless directed to
+suppress a subfield as part of the definition of that registered subfield
+type (it is never incorrect to pass on a subfield, and no registered
+subfield types presently specify suppression at the KDC).
+
+Implementations must make the contents of any authorization data subfields
+available to the server when a ticket is used. Implementations are not
+required to allow clients to specify the contents of the authorization data
+fields.
+
+Constant ranges
+
+All protocol constants are constrained to 32 bit (signed) values unless
+further constrained by the protocol definition. This limit is provided to
+allow implementations to make assumptions about the maximum values that will
+be received for these constants. Implementation receiving values outside
+this range may reject the request, but they must recover cleanly.
+
+9.2. Recommended KDC values
+
+Following is a list of recommended values for a KDC implementation, based on
+the list of suggested configuration constants (see section 4.4).
+
+minimum lifetime 5 minutes
+maximum renewable lifetime 1 week
+maximum ticket lifetime 1 day
+empty addresses only when suitable restrictions appear
+ in authorization data
+proxiable, etc. Allowed.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+10. REFERENCES
+
+[NT94] B. Clifford Neuman and Theodore Y. Ts'o, "An Authenti-
+ cation Service for Computer Networks," IEEE Communica-
+ tions Magazine, Vol. 32(9), pp. 33-38 (September 1994).
+
+[MNSS87] S. P. Miller, B. C. Neuman, J. I. Schiller, and J. H.
+ Saltzer, Section E.2.1: Kerberos Authentication and
+ Authorization System, M.I.T. Project Athena, Cambridge,
+ Massachusetts (December 21, 1987).
+
+[SNS88] J. G. Steiner, B. C. Neuman, and J. I. Schiller, "Ker-
+ beros: An Authentication Service for Open Network Sys-
+ tems," pp. 191-202 in Usenix Conference Proceedings,
+ Dallas, Texas (February, 1988).
+
+[NS78] Roger M. Needham and Michael D. Schroeder, "Using
+ Encryption for Authentication in Large Networks of Com-
+ puters," Communications of the ACM, Vol. 21(12),
+ pp. 993-999 (December, 1978).
+
+[DS81] Dorothy E. Denning and Giovanni Maria Sacco, "Time-
+ stamps in Key Distribution Protocols," Communications
+ of the ACM, Vol. 24(8), pp. 533-536 (August 1981).
+
+[KNT92] John T. Kohl, B. Clifford Neuman, and Theodore Y. Ts'o,
+ "The Evolution of the Kerberos Authentication Service,"
+ in an IEEE Computer Society Text soon to be published
+ (June 1992).
+
+[Neu93] B. Clifford Neuman, "Proxy-Based Authorization and
+ Accounting for Distributed Systems," in Proceedings of
+ the 13th International Conference on Distributed Com-
+ puting Systems, Pittsburgh, PA (May, 1993).
+
+[DS90] Don Davis and Ralph Swick, "Workstation Services and
+ Kerberos Authentication at Project Athena," Technical
+ Memorandum TM-424, MIT Laboratory for Computer Science
+ (February 1990).
+
+[LGDSR87] P. J. Levine, M. R. Gretzinger, J. M. Diaz, W. E. Som-
+ merfeld, and K. Raeburn, Section E.1: Service Manage-
+ ment System, M.I.T. Project Athena, Cambridge, Mas-
+ sachusetts (1987).
+
+[X509-88] CCITT, Recommendation X.509: The Directory Authentica-
+ tion Framework, December 1988.
+
+[Pat92]. J. Pato, Using Pre-Authentication to Avoid Password
+ Guessing Attacks, Open Software Foundation DCE Request
+ for Comments 26 (December 1992).
+
+[DES77] National Bureau of Standards, U.S. Department of Com-
+ merce, "Data Encryption Standard," Federal Information
+ Processing Standards Publication 46, Washington, DC
+ (1977).
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+[DESM80] National Bureau of Standards, U.S. Department of Com-
+ merce, "DES Modes of Operation," Federal Information
+ Processing Standards Publication 81, Springfield, VA
+ (December 1980).
+
+[SG92] Stuart G. Stubblebine and Virgil D. Gligor, "On Message
+ Integrity in Cryptographic Protocols," in Proceedings
+ of the IEEE Symposium on Research in Security and
+ Privacy, Oakland, California (May 1992).
+
+[IS3309] International Organization for Standardization, "ISO
+ Information Processing Systems - Data Communication -
+ High-Level Data Link Control Procedure - Frame Struc-
+ ture," IS 3309 (October 1984). 3rd Edition.
+
+[MD4-92] R. Rivest, "The MD4 Message Digest Algorithm," RFC
+ 1320, MIT Laboratory for Computer Science (April
+ 1992).
+
+[MD5-92] R. Rivest, "The MD5 Message Digest Algorithm," RFC
+ 1321, MIT Laboratory for Computer Science (April
+ 1992).
+
+[KBC96] H. Krawczyk, M. Bellare, and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication," Working Draft
+ draft-ietf-ipsec-hmac-md5-01.txt, (August 1996).
+
+[Horowitz96] Horowitz, M., "Key Derivation for Authentication,
+ Integrity, and Privacy", draft-horowitz-key-derivation-02.txt,
+ August 1998.
+
+[HorowitzB96] Horowitz, M., "Key Derivation for Kerberos V5", draft-
+ horowitz-kerb-key-derivation-01.txt, September 1998.
+
+[Krawczyk96] Krawczyk, H., Bellare, and M., Canetti, R., "HMAC:
+ Keyed-Hashing for Message Authentication", draft-ietf-ipsec-hmac-
+ md5-01.txt, August, 1996.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+A. Pseudo-code for protocol processing
+
+This appendix provides pseudo-code describing how the messages are to be
+constructed and interpreted by clients and servers.
+
+A.1. KRB_AS_REQ generation
+
+ request.pvno := protocol version; /* pvno = 5 */
+ request.msg-type := message type; /* type = KRB_AS_REQ */
+
+ if(pa_enc_timestamp_required) then
+ request.padata.padata-type = PA-ENC-TIMESTAMP;
+ get system_time;
+ padata-body.patimestamp,pausec = system_time;
+ encrypt padata-body into request.padata.padata-value
+ using client.key; /* derived from password */
+ endif
+
+ body.kdc-options := users's preferences;
+ body.cname := user's name;
+ body.realm := user's realm;
+ body.sname := service's name; /* usually "krbtgt", "localrealm" */
+ if (body.kdc-options.POSTDATED is set) then
+ body.from := requested starting time;
+ else
+ omit body.from;
+ endif
+ body.till := requested end time;
+ if (body.kdc-options.RENEWABLE is set) then
+ body.rtime := requested final renewal time;
+ endif
+ body.nonce := random_nonce();
+ body.etype := requested etypes;
+ if (user supplied addresses) then
+ body.addresses := user's addresses;
+ else
+ omit body.addresses;
+ endif
+ omit body.enc-authorization-data;
+ request.req-body := body;
+
+ kerberos := lookup(name of local kerberos server (or servers));
+ send(packet,kerberos);
+
+ wait(for response);
+ if (timed_out) then
+ retry or use alternate server;
+ endif
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+A.2. KRB_AS_REQ verification and KRB_AS_REP generation
+
+ decode message into req;
+
+ client := lookup(req.cname,req.realm);
+ server := lookup(req.sname,req.realm);
+
+ get system_time;
+ kdc_time := system_time.seconds;
+
+ if (!client) then
+ /* no client in Database */
+ error_out(KDC_ERR_C_PRINCIPAL_UNKNOWN);
+ endif
+ if (!server) then
+ /* no server in Database */
+ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
+ endif
+
+ if(client.pa_enc_timestamp_required and
+ pa_enc_timestamp not present) then
+ error_out(KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP));
+ endif
+
+ if(pa_enc_timestamp present) then
+ decrypt req.padata-value into decrypted_enc_timestamp
+ using client.key;
+ using auth_hdr.authenticator.subkey;
+ if (decrypt_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ if(decrypted_enc_timestamp is not within allowable skew)
+then
+ error_out(KDC_ERR_PREAUTH_FAILED);
+ endif
+ if(decrypted_enc_timestamp and usec is replay)
+ error_out(KDC_ERR_PREAUTH_FAILED);
+ endif
+ add decrypted_enc_timestamp and usec to replay cache;
+ endif
+
+ use_etype := first supported etype in req.etypes;
+
+ if (no support for req.etypes) then
+ error_out(KDC_ERR_ETYPE_NOSUPP);
+ endif
+
+ new_tkt.vno := ticket version; /* = 5 */
+ new_tkt.sname := req.sname;
+ new_tkt.srealm := req.srealm;
+ reset all flags in new_tkt.flags;
+
+ /* It should be noted that local policy may affect the */
+ /* processing of any of these flags. For example, some */
+ /* realms may refuse to issue renewable tickets */
+
+ if (req.kdc-options.FORWARDABLE is set) then
+ set new_tkt.flags.FORWARDABLE;
+ endif
+ if (req.kdc-options.PROXIABLE is set) then
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ set new_tkt.flags.PROXIABLE;
+ endif
+
+ if (req.kdc-options.ALLOW-POSTDATE is set) then
+ set new_tkt.flags.MAY-POSTDATE;
+ endif
+ if ((req.kdc-options.RENEW is set) or
+ (req.kdc-options.VALIDATE is set) or
+ (req.kdc-options.PROXY is set) or
+ (req.kdc-options.FORWARDED is set) or
+ (req.kdc-options.ENC-TKT-IN-SKEY is set)) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+ new_tkt.session := random_session_key();
+ new_tkt.cname := req.cname;
+ new_tkt.crealm := req.crealm;
+ new_tkt.transited := empty_transited_field();
+
+ new_tkt.authtime := kdc_time;
+
+ if (req.kdc-options.POSTDATED is set) then
+ if (against_postdate_policy(req.from)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ set new_tkt.flags.POSTDATED;
+ set new_tkt.flags.INVALID;
+ new_tkt.starttime := req.from;
+ else
+ omit new_tkt.starttime; /* treated as authtime when omitted */
+ endif
+ if (req.till = 0) then
+ till := infinity;
+ else
+ till := req.till;
+ endif
+
+ new_tkt.endtime := min(till,
+ new_tkt.starttime+client.max_life,
+ new_tkt.starttime+server.max_life,
+ new_tkt.starttime+max_life_for_realm);
+
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (new_tkt.endtime < req.till)) then
+ /* we set the RENEWABLE option for later processing */
+ set req.kdc-options.RENEWABLE;
+ req.rtime := req.till;
+ endif
+
+ if (req.rtime = 0) then
+ rtime := infinity;
+ else
+ rtime := req.rtime;
+ endif
+
+ if (req.kdc-options.RENEWABLE is set) then
+ set new_tkt.flags.RENEWABLE;
+ new_tkt.renew-till := min(rtime,
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ new_tkt.starttime+client.max_rlife,
+ new_tkt.starttime+server.max_rlife,
+ new_tkt.starttime+max_rlife_for_realm);
+ else
+ omit new_tkt.renew-till; /* only present if RENEWABLE */
+ endif
+
+ if (req.addresses) then
+ new_tkt.caddr := req.addresses;
+ else
+ omit new_tkt.caddr;
+ endif
+
+ new_tkt.authorization_data := empty_authorization_data();
+
+ encode to-be-encrypted part of ticket into OCTET STRING;
+ new_tkt.enc-part := encrypt OCTET STRING
+ using etype_for_key(server.key), server.key, server.p_kvno;
+
+ /* Start processing the response */
+
+ resp.pvno := 5;
+ resp.msg-type := KRB_AS_REP;
+ resp.cname := req.cname;
+ resp.crealm := req.realm;
+ resp.ticket := new_tkt;
+
+ resp.key := new_tkt.session;
+ resp.last-req := fetch_last_request_info(client);
+ resp.nonce := req.nonce;
+ resp.key-expiration := client.expiration;
+ resp.flags := new_tkt.flags;
+
+ resp.authtime := new_tkt.authtime;
+ resp.starttime := new_tkt.starttime;
+ resp.endtime := new_tkt.endtime;
+
+ if (new_tkt.flags.RENEWABLE) then
+ resp.renew-till := new_tkt.renew-till;
+ endif
+
+ resp.realm := new_tkt.realm;
+ resp.sname := new_tkt.sname;
+
+ resp.caddr := new_tkt.caddr;
+
+ encode body of reply into OCTET STRING;
+
+ resp.enc-part := encrypt OCTET STRING
+ using use_etype, client.key, client.p_kvno;
+ send(resp);
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+A.3. KRB_AS_REP verification
+
+ decode response into resp;
+
+ if (resp.msg-type = KRB_ERROR) then
+ if(error = KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP)) then
+ set pa_enc_timestamp_required;
+ goto KRB_AS_REQ;
+ endif
+ process_error(resp);
+ return;
+ endif
+
+ /* On error, discard the response, and zero the session key */
+ /* from the response immediately */
+
+ key = get_decryption_key(resp.enc-part.kvno, resp.enc-part.etype,
+ resp.padata);
+ unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and key;
+ zero(key);
+
+ if (common_as_rep_tgs_rep_checks fail) then
+ destroy resp.key;
+ return error;
+ endif
+
+ if near(resp.princ_exp) then
+ print(warning message);
+ endif
+ save_for_later(ticket,session,client,server,times,flags);
+
+A.4. KRB_AS_REP and KRB_TGS_REP common checks
+
+ if (decryption_error() or
+ (req.cname != resp.cname) or
+ (req.realm != resp.crealm) or
+ (req.sname != resp.sname) or
+ (req.realm != resp.realm) or
+ (req.nonce != resp.nonce) or
+ (req.addresses != resp.caddr)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ /* make sure no flags are set that shouldn't be, and that all that
+*/
+ /* should be are set
+*/
+ if (!check_flags_for_compatability(req.kdc-options,resp.flags)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ if ((req.from = 0) and
+ (resp.starttime is not within allowable skew)) then
+ destroy resp.key;
+ return KRB_AP_ERR_SKEW;
+ endif
+ if ((req.from != 0) and (req.from != resp.starttime)) then
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+ if ((req.till != 0) and (resp.endtime > req.till)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ if ((req.kdc-options.RENEWABLE is set) and
+ (req.rtime != 0) and (resp.renew-till > req.rtime)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (resp.flags.RENEWABLE) and
+ (req.till != 0) and
+ (resp.renew-till > req.till)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+A.5. KRB_TGS_REQ generation
+
+ /* Note that make_application_request might have to recursivly
+*/
+ /* call this routine to get the appropriate ticket-granting ticket
+*/
+
+ request.pvno := protocol version; /* pvno = 5 */
+ request.msg-type := message type; /* type = KRB_TGS_REQ */
+
+ body.kdc-options := users's preferences;
+ /* If the TGT is not for the realm of the end-server */
+ /* then the sname will be for a TGT for the end-realm */
+ /* and the realm of the requested ticket (body.realm) */
+ /* will be that of the TGS to which the TGT we are */
+ /* sending applies */
+ body.sname := service's name;
+ body.realm := service's realm;
+
+ if (body.kdc-options.POSTDATED is set) then
+ body.from := requested starting time;
+ else
+ omit body.from;
+ endif
+ body.till := requested end time;
+ if (body.kdc-options.RENEWABLE is set) then
+ body.rtime := requested final renewal time;
+ endif
+ body.nonce := random_nonce();
+ body.etype := requested etypes;
+ if (user supplied addresses) then
+ body.addresses := user's addresses;
+ else
+ omit body.addresses;
+ endif
+
+ body.enc-authorization-data := user-supplied data;
+ if (body.kdc-options.ENC-TKT-IN-SKEY) then
+ body.additional-tickets_ticket := second TGT;
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ endif
+
+ request.req-body := body;
+ check := generate_checksum (req.body,checksumtype);
+
+ request.padata[0].padata-type := PA-TGS-REQ;
+ request.padata[0].padata-value := create a KRB_AP_REQ using
+ the TGT and checksum
+
+ /* add in any other padata as required/supplied */
+
+ kerberos := lookup(name of local kerberose server (or servers));
+ send(packet,kerberos);
+
+ wait(for response);
+ if (timed_out) then
+ retry or use alternate server;
+ endif
+
+A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation
+
+ /* note that reading the application request requires first
+ determining the server for which a ticket was issued, and choosing
+the
+ correct key for decryption. The name of the server appears in the
+ plaintext part of the ticket. */
+
+ if (no KRB_AP_REQ in req.padata) then
+ error_out(KDC_ERR_PADATA_TYPE_NOSUPP);
+ endif
+ verify KRB_AP_REQ in req.padata;
+
+ /* Note that the realm in which the Kerberos server is operating is
+ determined by the instance from the ticket-granting ticket. The
+realm
+ in the ticket-granting ticket is the realm under which the ticket
+ granting ticket was issued. It is possible for a single Kerberos
+ server to support more than one realm. */
+
+ auth_hdr := KRB_AP_REQ;
+ tgt := auth_hdr.ticket;
+
+ if (tgt.sname is not a TGT for local realm and is not req.sname)
+then
+ error_out(KRB_AP_ERR_NOT_US);
+
+ realm := realm_tgt_is_for(tgt);
+
+ decode remainder of request;
+
+ if (auth_hdr.authenticator.cksum is missing) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+
+ if (auth_hdr.authenticator.cksum type is not supported) then
+ error_out(KDC_ERR_SUMTYPE_NOSUPP);
+ endif
+ if (auth_hdr.authenticator.cksum is not both collision-proof and
+ keyed) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ set computed_checksum := checksum(req);
+ if (computed_checksum != auth_hdr.authenticatory.cksum) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ server := lookup(req.sname,realm);
+
+ if (!server) then
+ if (is_foreign_tgt_name(req.sname)) then
+ server := best_intermediate_tgs(req.sname);
+ else
+ /* no server in Database */
+ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
+ endif
+ endif
+
+ session := generate_random_session_key();
+
+ use_etype := first supported etype in req.etypes;
+
+ if (no support for req.etypes) then
+ error_out(KDC_ERR_ETYPE_NOSUPP);
+ endif
+
+ new_tkt.vno := ticket version; /* = 5 */
+ new_tkt.sname := req.sname;
+ new_tkt.srealm := realm;
+ reset all flags in new_tkt.flags;
+
+ /* It should be noted that local policy may affect the */
+ /* processing of any of these flags. For example, some */
+ /* realms may refuse to issue renewable tickets */
+
+ new_tkt.caddr := tgt.caddr;
+ resp.caddr := NULL; /* We only include this if they change */
+ if (req.kdc-options.FORWARDABLE is set) then
+ if (tgt.flags.FORWARDABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.FORWARDABLE;
+ endif
+ if (req.kdc-options.FORWARDED is set) then
+ if (tgt.flags.FORWARDABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.FORWARDED;
+ new_tkt.caddr := req.addresses;
+ resp.caddr := req.addresses;
+ endif
+ if (tgt.flags.FORWARDED is set) then
+ set new_tkt.flags.FORWARDED;
+ endif
+
+ if (req.kdc-options.PROXIABLE is set) then
+ if (tgt.flags.PROXIABLE is reset)
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ set new_tkt.flags.PROXIABLE;
+ endif
+ if (req.kdc-options.PROXY is set) then
+ if (tgt.flags.PROXIABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.PROXY;
+ new_tkt.caddr := req.addresses;
+ resp.caddr := req.addresses;
+ endif
+
+ if (req.kdc-options.ALLOW-POSTDATE is set) then
+ if (tgt.flags.MAY-POSTDATE is reset)
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.MAY-POSTDATE;
+ endif
+ if (req.kdc-options.POSTDATED is set) then
+ if (tgt.flags.MAY-POSTDATE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.POSTDATED;
+ set new_tkt.flags.INVALID;
+ if (against_postdate_policy(req.from)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ new_tkt.starttime := req.from;
+ endif
+
+ if (req.kdc-options.VALIDATE is set) then
+ if (tgt.flags.INVALID is reset) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ if (tgt.starttime > kdc_time) then
+ error_out(KRB_AP_ERR_NYV);
+ endif
+ if (check_hot_list(tgt)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ tkt := tgt;
+ reset new_tkt.flags.INVALID;
+ endif
+
+ if (req.kdc-options.(any flag except ENC-TKT-IN-SKEY, RENEW,
+ and those already processed) is set) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+ new_tkt.authtime := tgt.authtime;
+
+ if (req.kdc-options.RENEW is set) then
+ /* Note that if the endtime has already passed, the ticket would
+*/
+ /* have been rejected in the initial authentication stage, so
+*/
+ /* there is no need to check again here
+*/
+ if (tgt.flags.RENEWABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ if (tgt.renew-till < kdc_time) then
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ error_out(KRB_AP_ERR_TKT_EXPIRED);
+ endif
+ tkt := tgt;
+ new_tkt.starttime := kdc_time;
+ old_life := tgt.endttime - tgt.starttime;
+ new_tkt.endtime := min(tgt.renew-till,
+ new_tkt.starttime + old_life);
+ else
+ new_tkt.starttime := kdc_time;
+ if (req.till = 0) then
+ till := infinity;
+ else
+ till := req.till;
+ endif
+ new_tkt.endtime := min(till,
+ new_tkt.starttime+client.max_life,
+ new_tkt.starttime+server.max_life,
+ new_tkt.starttime+max_life_for_realm,
+ tgt.endtime);
+
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (new_tkt.endtime < req.till) and
+ (tgt.flags.RENEWABLE is set) then
+ /* we set the RENEWABLE option for later processing
+*/
+ set req.kdc-options.RENEWABLE;
+ req.rtime := min(req.till, tgt.renew-till);
+ endif
+ endif
+
+ if (req.rtime = 0) then
+ rtime := infinity;
+ else
+ rtime := req.rtime;
+ endif
+
+ if ((req.kdc-options.RENEWABLE is set) and
+ (tgt.flags.RENEWABLE is set)) then
+ set new_tkt.flags.RENEWABLE;
+ new_tkt.renew-till := min(rtime,
+ new_tkt.starttime+client.max_rlife,
+ new_tkt.starttime+server.max_rlife,
+ new_tkt.starttime+max_rlife_for_realm,
+ tgt.renew-till);
+ else
+ new_tkt.renew-till := OMIT; /* leave the renew-till field out
+*/
+ endif
+ if (req.enc-authorization-data is present) then
+ decrypt req.enc-authorization-data into
+decrypted_authorization_data
+ using auth_hdr.authenticator.subkey;
+ if (decrypt_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ endif
+ new_tkt.authorization_data := req.auth_hdr.ticket.authorization_data
++
+ decrypted_authorization_data;
+
+ new_tkt.key := session;
+ new_tkt.crealm := tgt.crealm;
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ new_tkt.cname := req.auth_hdr.ticket.cname;
+
+ if (realm_tgt_is_for(tgt) := tgt.realm) then
+ /* tgt issued by local realm */
+ new_tkt.transited := tgt.transited;
+ else
+ /* was issued for this realm by some other realm */
+ if (tgt.transited.tr-type not supported) then
+ error_out(KDC_ERR_TRTYPE_NOSUPP);
+ endif
+ new_tkt.transited := compress_transited(tgt.transited +
+tgt.realm)
+ /* Don't check tranited field if TGT for foreign realm,
+ * or requested not to check */
+ if (is_not_foreign_tgt_name(new_tkt.server)
+ && req.kdc-options.DISABLE-TRANSITED-CHECK not set) then
+ /* Check it, so end-server does not have to
+ * but don't fail, end-server may still accept it */
+ if (check_transited_field(new_tkt.transited) == OK)
+ set new_tkt.flags.TRANSITED-POLICY-CHECKED;
+ endif
+ endif
+ endif
+
+ encode encrypted part of new_tkt into OCTET STRING;
+ if (req.kdc-options.ENC-TKT-IN-SKEY is set) then
+ if (server not specified) then
+ server = req.second_ticket.client;
+ endif
+ if ((req.second_ticket is not a TGT) or
+ (req.second_ticket.client != server)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+
+ new_tkt.enc-part := encrypt OCTET STRING using
+ using etype_for_key(second-ticket.key), second-ticket.key;
+ else
+ new_tkt.enc-part := encrypt OCTET STRING
+ using etype_for_key(server.key), server.key, server.p_kvno;
+ endif
+
+ resp.pvno := 5;
+ resp.msg-type := KRB_TGS_REP;
+ resp.crealm := tgt.crealm;
+ resp.cname := tgt.cname;
+ resp.ticket := new_tkt;
+
+ resp.key := session;
+ resp.nonce := req.nonce;
+ resp.last-req := fetch_last_request_info(client);
+ resp.flags := new_tkt.flags;
+
+ resp.authtime := new_tkt.authtime;
+ resp.starttime := new_tkt.starttime;
+ resp.endtime := new_tkt.endtime;
+
+ omit resp.key-expiration;
+
+ resp.sname := new_tkt.sname;
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ resp.realm := new_tkt.realm;
+
+ if (new_tkt.flags.RENEWABLE) then
+ resp.renew-till := new_tkt.renew-till;
+ endif
+
+ encode body of reply into OCTET STRING;
+
+ if (req.padata.authenticator.subkey)
+ resp.enc-part := encrypt OCTET STRING using use_etype,
+ req.padata.authenticator.subkey;
+ else resp.enc-part := encrypt OCTET STRING using use_etype, tgt.key;
+
+ send(resp);
+
+A.7. KRB_TGS_REP verification
+
+ decode response into resp;
+
+ if (resp.msg-type = KRB_ERROR) then
+ process_error(resp);
+ return;
+ endif
+
+ /* On error, discard the response, and zero the session key from
+ the response immediately */
+
+ if (req.padata.authenticator.subkey)
+ unencrypted part of resp := decode of decrypt of
+resp.enc-part
+ using resp.enc-part.etype and subkey;
+ else unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and tgt's session key;
+ if (common_as_rep_tgs_rep_checks fail) then
+ destroy resp.key;
+ return error;
+ endif
+
+ check authorization_data as necessary;
+ save_for_later(ticket,session,client,server,times,flags);
+
+A.8. Authenticator generation
+
+ body.authenticator-vno := authenticator vno; /* = 5 */
+ body.cname, body.crealm := client name;
+ if (supplying checksum) then
+ body.cksum := checksum;
+ endif
+ get system_time;
+ body.ctime, body.cusec := system_time;
+ if (selecting sub-session key) then
+ select sub-session key;
+ body.subkey := sub-session key;
+ endif
+ if (using sequence numbers) then
+ select initial sequence number;
+ body.seq-number := initial sequence;
+ endif
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+A.9. KRB_AP_REQ generation
+
+ obtain ticket and session_key from cache;
+
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_AP_REQ */
+
+ if (desired(MUTUAL_AUTHENTICATION)) then
+ set packet.ap-options.MUTUAL-REQUIRED;
+ else
+ reset packet.ap-options.MUTUAL-REQUIRED;
+ endif
+ if (using session key for ticket) then
+ set packet.ap-options.USE-SESSION-KEY;
+ else
+ reset packet.ap-options.USE-SESSION-KEY;
+ endif
+ packet.ticket := ticket; /* ticket */
+ generate authenticator;
+ encode authenticator into OCTET STRING;
+ encrypt OCTET STRING into packet.authenticator using session_key;
+
+A.10. KRB_AP_REQ verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_AP_REQ) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ if (packet.ticket.tkt_vno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.ap_options.USE-SESSION-KEY is set) then
+ retrieve session key from ticket-granting ticket for
+ packet.ticket.{sname,srealm,enc-part.etype};
+ else
+ retrieve service key for
+ packet.ticket.{sname,srealm,enc-part.etype,enc-part.skvno};
+ endif
+ if (no_key_available) then
+ if (cannot_find_specified_skvno) then
+ error_out(KRB_AP_ERR_BADKEYVER);
+ else
+ error_out(KRB_AP_ERR_NOKEY);
+ endif
+ endif
+ decrypt packet.ticket.enc-part into decr_ticket using retrieved key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ decrypt packet.authenticator into decr_authenticator
+ using decr_ticket.key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ endif
+ if (decr_authenticator.{cname,crealm} !=
+ decr_ticket.{cname,crealm}) then
+ error_out(KRB_AP_ERR_BADMATCH);
+ endif
+ if (decr_ticket.caddr is present) then
+ if (sender_address(packet) is not in decr_ticket.caddr) then
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ elseif (application requires addresses) then
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (not in_clock_skew(decr_authenticator.ctime,
+ decr_authenticator.cusec)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(decr_authenticator.{ctime,cusec,cname,crealm})) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ save_identifier(decr_authenticator.{ctime,cusec,cname,crealm});
+ get system_time;
+ if ((decr_ticket.starttime-system_time > CLOCK_SKEW) or
+ (decr_ticket.flags.INVALID is set)) then
+ /* it hasn't yet become valid */
+ error_out(KRB_AP_ERR_TKT_NYV);
+ endif
+ if (system_time-decr_ticket.endtime > CLOCK_SKEW) then
+ error_out(KRB_AP_ERR_TKT_EXPIRED);
+ endif
+ if (decr_ticket.transited) then
+ /* caller may ignore the TRANSITED-POLICY-CHECKED and do
+ * check anyway */
+ if (decr_ticket.flags.TRANSITED-POLICY-CHECKED not set) then
+ if (check_transited_field(decr_ticket.transited) then
+ error_out(KDC_AP_PATH_NOT_ACCPETED);
+ endif
+ endif
+ endif
+ /* caller must check decr_ticket.flags for any pertinent details */
+ return(OK, decr_ticket, packet.ap_options.MUTUAL-REQUIRED);
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+A.11. KRB_AP_REP generation
+
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_AP_REP */
+
+ body.ctime := packet.ctime;
+ body.cusec := packet.cusec;
+ if (selecting sub-session key) then
+ select sub-session key;
+ body.subkey := sub-session key;
+ endif
+ if (using sequence numbers) then
+ select initial sequence number;
+ body.seq-number := initial sequence;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part;
+
+A.12. KRB_AP_REP verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_AP_REP) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ cleartext := decrypt(packet.enc-part) using ticket's session key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if (cleartext.ctime != authenticator.ctime) then
+ error_out(KRB_AP_ERR_MUT_FAIL);
+ endif
+ if (cleartext.cusec != authenticator.cusec) then
+ error_out(KRB_AP_ERR_MUT_FAIL);
+ endif
+ if (cleartext.subkey is present) then
+ save cleartext.subkey for future use;
+ endif
+ if (cleartext.seq-number is present) then
+ save cleartext.seq-number for future verifications;
+ endif
+ return(AUTHENTICATION_SUCCEEDED);
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+A.13. KRB_SAFE generation
+
+ collect user data in buffer;
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_SAFE */
+
+ body.user-data := buffer; /* DATA */
+ if (using timestamp) then
+ get system_time;
+ body.timestamp, body.usec := system_time;
+ endif
+ if (using sequence numbers) then
+ body.seq-number := sequence number;
+ endif
+ body.s-address := sender host addresses;
+ if (only one recipient) then
+ body.r-address := recipient host address;
+ endif
+ checksum.cksumtype := checksum type;
+ compute checksum over body;
+ checksum.checksum := checksum value; /* checksum.checksum */
+ packet.cksum := checksum;
+ packet.safe-body := body;
+
+A.14. KRB_SAFE verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_SAFE) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ if (packet.checksum.cksumtype is not both collision-proof
+ and keyed) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+ if (safe_priv_common_checks_ok(packet)) then
+ set computed_checksum := checksum(packet.body);
+ if (computed_checksum != packet.checksum) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+ return (packet, PACKET_IS_GENUINE);
+ else
+ return common_checks_error;
+ endif
+
+A.15. KRB_SAFE and KRB_PRIV common checks
+
+ if (packet.s-address != O/S_sender(packet)) then
+ /* O/S report of sender not who claims to have sent it */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if ((packet.r-address is present) and
+ (packet.r-address != local_host_address)) then
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ /* was not sent to proper place */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (((packet.timestamp is present) and
+ (not in_clock_skew(packet.timestamp,packet.usec))) or
+ (packet.timestamp is not present and timestamp expected)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(packet.timestamp,packet.usec,packet.s-address)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+
+ if (((packet.seq-number is present) and
+ ((not in_sequence(packet.seq-number)))) or
+ (packet.seq-number is not present and sequence expected)) then
+ error_out(KRB_AP_ERR_BADORDER);
+ endif
+ if (packet.timestamp not present and packet.seq-number
+ not present) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ save_identifier(packet.{timestamp,usec,s-address},
+ sender_principal(packet));
+
+ return PACKET_IS_OK;
+
+A.16. KRB_PRIV generation
+
+ collect user data in buffer;
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_PRIV */
+
+ packet.enc-part.etype := encryption type;
+
+ body.user-data := buffer;
+ if (using timestamp) then
+ get system_time;
+ body.timestamp, body.usec := system_time;
+ endif
+ if (using sequence numbers) then
+ body.seq-number := sequence number;
+ endif
+ body.s-address := sender host addresses;
+ if (only one recipient) then
+ body.r-address := recipient host address;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part.cipher;
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+A.17. KRB_PRIV verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_PRIV) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+
+ cleartext := decrypt(packet.enc-part) using negotiated key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+
+ if (safe_priv_common_checks_ok(cleartext)) then
+ return(cleartext.DATA, PACKET_IS_GENUINE_AND_UNMODIFIED);
+ else
+ return common_checks_error;
+ endif
+
+A.18. KRB_CRED generation
+
+ invoke KRB_TGS; /* obtain tickets to be provided to peer */
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_CRED */
+
+ for (tickets[n] in tickets to be forwarded) do
+ packet.tickets[n] = tickets[n].ticket;
+ done
+
+ packet.enc-part.etype := encryption type;
+
+ for (ticket[n] in tickets to be forwarded) do
+ body.ticket-info[n].key = tickets[n].session;
+ body.ticket-info[n].prealm = tickets[n].crealm;
+ body.ticket-info[n].pname = tickets[n].cname;
+ body.ticket-info[n].flags = tickets[n].flags;
+ body.ticket-info[n].authtime = tickets[n].authtime;
+ body.ticket-info[n].starttime = tickets[n].starttime;
+ body.ticket-info[n].endtime = tickets[n].endtime;
+ body.ticket-info[n].renew-till = tickets[n].renew-till;
+ body.ticket-info[n].srealm = tickets[n].srealm;
+ body.ticket-info[n].sname = tickets[n].sname;
+ body.ticket-info[n].caddr = tickets[n].caddr;
+ done
+
+ get system_time;
+ body.timestamp, body.usec := system_time;
+
+ if (using nonce) then
+ body.nonce := nonce;
+ endif
+
+ if (using s-address) then
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+ body.s-address := sender host addresses;
+ endif
+ if (limited recipients) then
+ body.r-address := recipient host address;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part.cipher
+ using negotiated encryption key;
+
+A.19. KRB_CRED verification
+
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_CRED) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+
+ cleartext := decrypt(packet.enc-part) using negotiated key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if ((packet.r-address is present or required) and
+ (packet.s-address != O/S_sender(packet)) then
+ /* O/S report of sender not who claims to have sent it */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if ((packet.r-address is present) and
+ (packet.r-address != local_host_address)) then
+ /* was not sent to proper place */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (not in_clock_skew(packet.timestamp,packet.usec)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(packet.timestamp,packet.usec,packet.s-address)) then
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ if (packet.nonce is required or present) and
+ (packet.nonce != expected-nonce) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ for (ticket[n] in tickets that were forwarded) do
+ save_for_later(ticket[n],key[n],principal[n],
+ server[n],times[n],flags[n]);
+ return
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+A.20. KRB_ERROR generation
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_ERROR */
+
+ get system_time;
+ packet.stime, packet.susec := system_time;
+ packet.realm, packet.sname := server name;
+
+ if (client time available) then
+ packet.ctime, packet.cusec := client_time;
+ endif
+ packet.error-code := error code;
+ if (client name available) then
+ packet.cname, packet.crealm := client name;
+ endif
+ if (error text available) then
+ packet.e-text := error text;
+ endif
+ if (error data available) then
+ packet.e-data := error data;
+ endif
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+B. Definition of common authorization data elements
+
+This appendix contains the definitions of common authorization data
+elements. These common authorization data elements are recursivly defined,
+meaning the ad-data for these types will itself contain a sequence of
+authorization data whose interpretation is affected by the encapsulating
+element. Depending on the meaning of the encapsulating element, the
+encapsulated elements may be ignored, might be interpreted as issued
+directly by the KDC, or they might be stored in a separate plaintext part of
+the ticket. The types of the encapsulating elements are specified as part of
+the Kerberos specification because the behavior based on these values should
+be understood across implementations whereas other elements need only be
+understood by the applications which they affect.
+
+In the definitions that follow, the value of the ad-type for the element
+will be specified in the subsection number, and the value of the ad-data
+will be as shown in the ASN.1 structure that follows the subsection heading.
+
+B.1. If relevant
+
+AD-IF-RELEVANT AuthorizationData
+
+AD elements encapsulated within the if-relevant element are intended for
+interpretation only by application servers that understand the particular
+ad-type of the embedded element. Application servers that do not understand
+the type of an element embedded within the if-relevant element may ignore
+the uninterpretable element. This element promotes interoperability across
+implementations which may have local extensions for authorization.
+
+B.2. Intended for server
+
+AD-INTENDED-FOR-SERVER SEQUENCE {
+ intended-server[0] SEQUENCE OF PrincipalName
+ elements[1] AuthorizationData
+}
+
+AD elements encapsulated within the intended-for-server element may be
+ignored if the application server is not in the list of principal names of
+intended servers. Further, a KDC issuing a ticket for an application server
+can remove this element if the application server is not in the list of
+intended servers.
+
+Application servers should check for their principal name in the
+intended-server field of this element. If their principal name is not found,
+this element should be ignored. If found, then the encapsulated elements
+should be evaluated in the same manner as if they were present in the top
+level authorization data field. Applications and application servers that do
+not implement this element should reject tickets that contain authorization
+data elements of this type.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+B.3. Intended for application class
+
+AD-INTENDED-FOR-APPLICATION-CLASS SEQUENCE { intended-application-class[0]
+SEQUENCE OF GeneralString elements[1] AuthorizationData } AD elements
+encapsulated within the intended-for-application-class element may be
+ignored if the application server is not in one of the named classes of
+application servers. Examples of application server classes include
+"FILESYSTEM", and other kinds of servers.
+
+This element and the elements it encapulates may be safely ignored by
+applications, application servers, and KDCs that do not implement this
+element.
+
+B.4. KDC Issued
+
+AD-KDCIssued SEQUENCE {
+ ad-checksum[0] Checksum,
+ i-realm[1] Realm OPTIONAL,
+ i-sname[2] PrincipalName OPTIONAL,
+ elements[3] AuthorizationData.
+}
+
+ad-checksum
+ A checksum over the elements field using a cryptographic checksum
+ method that is identical to the checksum used to protect the ticket
+ itself (i.e. using the same hash function and the same encryption
+ algorithm used to encrypt the ticket) and using a key derived from the
+ same key used to protect the ticket.
+i-realm, i-sname
+ The name of the issuing principal if different from the KDC itself.
+ This field would be used when the KDC can verify the authenticity of
+ elements signed by the issuing principal and it allows this KDC to
+ notify the application server of the validity of those elements.
+elements
+ A sequence of authorization data elements issued by the KDC.
+
+The KDC-issued ad-data field is intended to provide a means for Kerberos
+principal credentials to embed within themselves privilege attributes and
+other mechanisms for positive authorization, amplifying the priveleges of
+the principal beyond what can be done using a credentials without such an
+a-data element.
+
+This can not be provided without this element because the definition of the
+authorization-data field allows elements to be added at will by the bearer
+of a TGT at the time that they request service tickets and elements may also
+be added to a delegated ticket by inclusion in the authenticator.
+
+For KDC-issued elements this is prevented because the elements are signed by
+the KDC by including a checksum encrypted using the server's key (the same
+key used to encrypt the ticket - or a key derived from that key). Elements
+encapsulated with in the KDC-issued element will be ignored by the
+application server if this "signature" is not present. Further, elements
+encapsulated within this element from a ticket granting ticket may be
+interpreted by the KDC, and used as a basis according to policy for
+including new signed elements within derivative tickets, but they will not
+be copied to a derivative ticket directly. If they are copied directly to a
+derivative ticket by a KDC that is not aware of this element, the signature
+will not be correct for the application ticket elements, and the field will
+be ignored by the application server.
+
+This element and the elements it encapulates may be safely ignored by
+applications, application servers, and KDCs that do not implement this
+element.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+B.5. And-Or
+
+AD-AND-OR SEQUENCE {
+ condition-count[0] INTEGER,
+ elements[1] AuthorizationData
+}
+
+When restrictive AD elements encapsulated within the and-or element are
+encountered, only the number specified in condition-count of the
+encapsulated conditions must be met in order to satisfy this element. This
+element may be used to implement an "or" operation by setting the
+condition-count field to 1, and it may specify an "and" operation by setting
+the condition count to the number of embedded elements. Application servers
+that do not implement this element must reject tickets that contain
+authorization data elements of this type.
+
+B.6. Mandatory ticket extensions
+
+AD-Mandatory-Ticket-Extensions Checksum
+
+An authorization data element of type mandatory-ticket-extensions specifies
+a collision-proof checksum using the same hash algorithm used to protect the
+integrity of the ticket itself. This checksum will be calculated over an
+individual extension field. If there are more than one extension, multiple
+Mandatory-Ticket-Extensions authorization data elements may be present, each
+with a checksum for a different extension field. This restriction indicates
+that the ticket should not be accepted if a ticket extension is not present
+in the ticket for which the checksum does not match that checksum specified
+in the authorization data element. Application servers that do not implement
+this element must reject tickets that contain authorization data elements of
+this type.
+
+B.7. Authorization Data in ticket extensions
+
+AD-IN-Ticket-Extensions Checksum
+
+An authorization data element of type in-ticket-extensions specifies a
+collision-proof checksum using the same hash algorithm used to protect the
+integrity of the ticket itself. This checksum is calculated over a separate
+external AuthorizationData field carried in the ticket extensions.
+Application servers that do not implement this element must reject tickets
+that contain authorization data elements of this type. Application servers
+that do implement this element will search the ticket extensions for
+authorization data fields, calculate the specified checksum over each
+authorization data field and look for one matching the checksum in this
+in-ticket-extensions element. If not found, then the ticket must be
+rejected. If found, the corresponding authorization data elements will be
+interpreted in the same manner as if they were contained in the top level
+authorization data field.
+
+Note that if multiple external authorization data fields are present in a
+ticket, each will have a corresponding element of type in-ticket-extensions
+in the top level authorization data field, and the external entries will be
+linked to the corresponding element by their checksums.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+C. Definition of common ticket extensions
+
+This appendix contains the definitions of common ticket extensions. Support
+for these extensions is optional. However, certain extensions have
+associated authorization data elements that may require rejection of a
+ticket containing an extension by application servers that do not implement
+the particular extension. Other extensions have been defined beyond those
+described in this specification. Such extensions are described elswhere and
+for some of those extensions the reserved number may be found in the list of
+constants.
+
+It is known that older versions of Kerberos did not support this field, and
+that some clients will strip this field from a ticket when they parse and
+then reassemble a ticket as it is passed to the application servers. The
+presence of the extension will not break such clients, but any functionaly
+dependent on the extensions will not work when such tickets are handled by
+old clients. In such situations, some implementation may use alternate
+methods to transmit the information in the extensions field.
+
+C.1. Null ticket extension
+
+TE-NullExtension OctetString -- The empty Octet String
+
+The te-data field in the null ticket extension is an octet string of lenght
+zero. This extension may be included in a ticket granting ticket so that the
+KDC can determine on presentation of the ticket granting ticket whether the
+client software will strip the extensions field.
+
+C.2. External Authorization Data
+
+TE-ExternalAuthorizationData AuthorizationData
+
+The te-data field in the external authorization data ticket extension is
+field of type AuthorizationData containing one or more authorization data
+elements. If present, a corresponding authorization data element will be
+present in the primary authorization data for the ticket and that element
+will contain a checksum of the external authorization data ticket extension.
+ ------------------------------------------------------------------------
+[TM] Project Athena, Athena, and Kerberos are trademarks of the
+Massachusetts Institute of Technology (MIT). No commercial use of these
+trademarks may be made without prior written permission of MIT.
+
+[1] Note, however, that many applications use Kerberos' functions only upon
+the initiation of a stream-based network connection. Unless an application
+subsequently provides integrity protection for the data stream, the identity
+verification applies only to the initiation of the connection, and does not
+guarantee that subsequent messages on the connection originate from the same
+principal.
+
+[2] Secret and private are often used interchangeably in the literature. In
+our usage, it takes two (or more) to share a secret, thus a shared DES key
+is a secret key. Something is only private when no one but its owner knows
+it. Thus, in public key cryptosystems, one has a public and a private key.
+
+[3] Of course, with appropriate permission the client could arrange
+registration of a separately-named prin- cipal in a remote realm, and engage
+in normal exchanges with that realm's services. However, for even small
+numbers of clients this becomes cumbersome, and more automatic methods as
+described here are necessary.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+[4] Though it is permissible to request or issue tick- ets with no network
+addresses specified.
+
+[5] The password-changing request must not be honored unless the requester
+can provide the old password (the user's current secret key). Otherwise, it
+would be possible for someone to walk up to an unattended ses- sion and
+change another user's password.
+
+[6] To authenticate a user logging on to a local system, the credentials
+obtained in the AS exchange may first be used in a TGS exchange to obtain
+credentials for a local server. Those credentials must then be verified by a
+local server through successful completion of the Client/Server exchange.
+
+[7] "Random" means that, among other things, it should be impossible to
+guess the next session key based on knowledge of past session keys. This can
+only be achieved in a pseudo-random number generator if it is based on
+cryptographic principles. It is more desirable to use a truly random number
+generator, such as one based on measurements of random physical phenomena.
+
+[8] Tickets contain both an encrypted and unencrypted portion, so cleartext
+here refers to the entire unit, which can be copied from one message and
+replayed in another without any cryptographic skill.
+
+[9] Note that this can make applications based on unreliable transports
+difficult to code correctly. If the transport might deliver duplicated
+messages, either a new authenticator must be generated for each retry, or
+the application server must match requests and replies and replay the first
+reply in response to a detected duplicate.
+
+[10] This is used for user-to-user authentication as described in [8].
+
+[11] Note that the rejection here is restricted to authenticators from the
+same principal to the same server. Other client principals communicating
+with the same server principal should not be have their authenticators
+rejected if the time and microsecond fields happen to match some other
+client's authenticator.
+
+[12] In the Kerberos version 4 protocol, the timestamp in the reply was the
+client's timestamp plus one. This is not necessary in version 5 because
+version 5 messages are formatted in such a way that it is not possible to
+create the reply by judicious message surgery (even in encrypted form)
+without knowledge of the appropriate encryption keys.
+
+[13] Note that for encrypting the KRB_AP_REP message, the sub-session key is
+not used, even if present in the Authenticator.
+
+[14] Implementations of the protocol may wish to provide routines to choose
+subkeys based on session keys and random numbers and to generate a
+negotiated key to be returned in the KRB_AP_REP message.
+
+[15]This can be accomplished in several ways. It might be known beforehand
+(since the realm is part of the principal identifier), it might be stored in
+a nameserver, or it might be obtained from a configura- tion file. If the
+realm to be used is obtained from a nameserver, there is a danger of being
+spoofed if the nameservice providing the realm name is not authenti- cated.
+This might result in the use of a realm which has been compromised, and
+would result in an attacker's ability to compromise the authentication of
+the application server to the client.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+[16] If the client selects a sub-session key, care must be taken to ensure
+the randomness of the selected sub- session key. One approach would be to
+generate a random number and XOR it with the session key from the
+ticket-granting ticket.
+
+[17] This allows easy implementation of user-to-user authentication [8],
+which uses ticket-granting ticket session keys in lieu of secret server keys
+in situa- tions where such secret keys could be easily comprom- ised.
+
+[18] For the purpose of appending, the realm preceding the first listed
+realm is considered to be the null realm ("").
+
+[19] For the purpose of interpreting null subfields, the client's realm is
+considered to precede those in the transited field, and the server's realm
+is considered to follow them.
+
+[20] This means that a client and server running on the same host and
+communicating with one another using the KRB_SAFE messages should not share
+a common replay cache to detect KRB_SAFE replays.
+
+[21] The implementation of the Kerberos server need not combine the database
+and the server on the same machine; it is feasible to store the principal
+database in, say, a network name service, as long as the entries stored
+therein are protected from disclosure to and modification by unauthorized
+parties. However, we recommend against such strategies, as they can make
+system management and threat analysis quite complex.
+
+[22] See the discussion of the padata field in section 5.4.2 for details on
+why this can be useful.
+
+[23] Warning for implementations that unpack and repack data structures
+during the generation and verification of embedded checksums: Because any
+checksums applied to data structures must be checked against the original
+data the length of bit strings must be preserved within a data structure
+between the time that a checksum is generated through transmission to the
+time that the checksum is verified.
+
+[24] It is NOT recommended that this time value be used to adjust the
+workstation's clock since the workstation cannot reliably determine that
+such a KRB_AS_REP actually came from the proper KDC in a timely manner.
+
+[25] Note, however, that if the time is used as the nonce, one must make
+sure that the workstation time is monotonically increasing. If the time is
+ever reset backwards, there is a small, but finite, probability that a nonce
+will be reused.
+
+[27] An application code in the encrypted part of a message provides an
+additional check that the message was decrypted properly.
+
+[29] An application code in the encrypted part of a message provides an
+additional check that the message was decrypted properly.
+
+[31] An application code in the encrypted part of a message provides an
+additional check that the message was decrypted properly.
+
+
+Neuman, Ts'o, Kohl Expires: 25 December,
+1999
+
+INTERNET-DRAFT draft-ietf-cat-kerberos-revisions-04 June 25,
+1999
+
+[32] If supported by the encryption method in use, an initialization vector
+may be passed to the encryption procedure, in order to achieve proper cipher
+chaining. The initialization vector might come from the last block of the
+ciphertext from the previous KRB_PRIV message, but it is the application's
+choice whether or not to use such an initialization vector. If left out, the
+default initialization vector for the encryption algorithm will be used.
+
+[33] This prevents an attacker who generates an incorrect AS request from
+obtaining verifiable plaintext for use in an off-line password guessing
+attack.
+
+[35] In the above specification, UNTAGGED OCTET STRING(length) is the
+notation for an octet string with its tag and length removed. It is not a
+valid ASN.1 type. The tag bits and length must be removed from the
+confounder since the purpose of the confounder is so that the message starts
+with random data, but the tag and its length are fixed. For other fields,
+the length and tag would be redundant if they were included because they are
+specified by the encryption type. [36] The ordering of the fields in the
+CipherText is important. Additionally, messages encoded in this format must
+include a length as part of the msg-seq field. This allows the recipient to
+verify that the message has not been truncated. Without a length, an
+attacker could use a chosen plaintext attack to generate a message which
+could be truncated, while leaving the checksum intact. Note that if the
+msg-seq is an encoding of an ASN.1 SEQUENCE or OCTET STRING, then the length
+is part of that encoding.
+
+[37] In some cases, it may be necessary to use a different "mix-in" string
+for compatibility reasons; see the discussion of padata in section 5.4.2.
+
+[38] In some cases, it may be necessary to use a different "mix-in" string
+for compatibility reasons; see the discussion of padata in section 5.4.2.
+
+[39] A variant of the key is used to limit the use of a key to a particular
+function, separating the functions of generating a checksum from other
+encryption performed using the session key. The constant F0F0F0F0F0F0F0F0
+was chosen because it maintains key parity. The properties of DES precluded
+the use of the complement. The same constant is used for similar purpose in
+the Message Integrity Check in the Privacy Enhanced Mail standard.
+
+[40] This error carries additional information in the e- data field. The
+contents of the e-data field for this message is described in section 5.9.1.
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-cat-krb-dns-locate-00.txt b/crypto/heimdal/doc/standardisation/draft-ietf-cat-krb-dns-locate-00.txt
new file mode 100644
index 000000000000..e76a0e402ad1
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-cat-krb-dns-locate-00.txt
@@ -0,0 +1,250 @@
+INTERNET-DRAFT Ken Hornstein
+<draft-ietf-cat-krb-dns-locate-00.txt> NRL
+June 21, 1999 Jeffrey Altman
+Expires: December 21, 1999 Columbia University
+
+ Distributing Kerberos KDC and Realm Information with DNS
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of RFC2026.
+
+ Internet-Drafts are working documents of the Internet Engineering
+ Task Force (IETF), its areas, and its working groups. Note that
+ other groups may also distribute working documents as Internet-
+ Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet- Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html.
+
+ Distribution of this memo is unlimited. It is filed as <draft-ietf-
+ cat-krb-dns-locate-00.txt>, and expires on December 21, 1999. Please
+ send comments to the authors.
+
+Abstract
+
+ Neither the Kerberos V5 protocol [RFC1510] nor the Kerberos V4 proto-
+ col [RFC????] describe any mechanism for clients to learn critical
+ configuration information necessary for proper operation of the pro-
+ tocol. Such information includes the location of Kerberos key dis-
+ tribution centers or a mapping between DNS domains and Kerberos
+ realms.
+
+ Current Kerberos implementations generally store such configuration
+ information in a file on each client machine. Experience has shown
+ this method of storing configuration information presents problems
+ with out-of-date information and scaling problems, especially when
+
+Hornstein, Altman [Page 1]
+
+RFC DRAFT June 21, 1999
+
+ using cross-realm authentication.
+
+ This memo describes a method for using the Domain Name System
+ [RFC1035] for storing such configuration information. Specifically,
+ methods for storing KDC location and hostname/domain name to realm
+ mapping information are discussed.
+
+Overview - KDC location information
+
+ KDC location information is to be stored using the DNS SRV RR [RFC
+ 2052]. The format of this RR is as follows:
+
+ Service.Proto.Realm TTL Class SRV Priority Weight Port Target
+
+ The Service name for Kerberos is always "_kerberos".
+
+ The Proto can be either "_udp" or "_tcp". If these records are to be
+ used, a "_udp" record MUST be included. If the Kerberos implementa-
+ tion supports TCP transport, a "_tcp" record SHOULD be included.
+
+ The Realm is the Kerberos realm that this record corresponds to.
+
+ TTL, Class, SRV, Priority, Weight, Port, and Target have the standard
+ meaning as defined in RFC 2052.
+
+Example - KDC location information
+
+ These are DNS records for a Kerberos realm ASDF.COM. It has two Ker-
+ beros servers, kdc1.asdf.com and kdc2.asdf.com. Queries should be
+ directed to kdc1.asdf.com first as per the specified priority.
+ Weights are not used in these records.
+
+ _kerberos._udp.ASDF.COM. IN SRV 0 0 88 kdc1.asdf.com.
+ _kerberos._udp.ASDF.COM. IN SRV 1 0 88 kdc2.asdf.com.
+
+Overview - KAdmin location information
+
+ Kadmin location information is to be stored using the DNS SRV RR [RFC
+ 2052]. The format of this RR is as follows:
+
+ Service.Proto.Realm TTL Class SRV Priority Weight Port Target
+
+ The Service name for Kadmin is always "_kadmin".
+
+ The Proto can be either "_udp" or "_tcp". If these records are to be
+ used, a "_tcp" record MUST be included. If the Kadmin implementation
+ supports UDP transport, a "_udp" record SHOULD be included.
+
+Hornstein, Altman [Page 2]
+
+RFC DRAFT June 21, 1999
+
+ The Realm is the Kerberos realm that this record corresponds to.
+
+ TTL, Class, SRV, Priority, Weight, Port, and Target have the standard
+ meaning as defined in RFC 2052.
+
+Example - Kadmin location information
+
+ These are DNS records for a Kerberos realm ASDF.COM. It has one Kad-
+ min server, kdc1.asdf.com.
+
+ _kadmin._tcp.ASDF.COM. IN SRV 0 0 88 kdc1.asdf.com.
+
+Overview - Hostname/domain name to Kerberos realm mapping
+
+ Information on the mapping of DNS hostnames and domain names to Ker-
+ beros realms is stored using DNS TXT records [RFC 1035]. These
+ records have the following format.
+
+ Service.Name TTL Class TXT Realm
+
+ The Service field is always "_kerberos", and prefixes all entries of
+ this type.
+
+ The Name is a DNS hostname or domain name. This is explained in
+ greater detail below.
+
+ TTL, Class, and TXT have the standard DNS meaning as defined in RFC
+ 1035.
+
+ The Realm is the data for the TXT RR, and consists simply of the Ker-
+ beros realm that corresponds to the Name specified.
+
+ When a Kerberos client wishes to utilize a host-specific service, it
+ will perform a DNS TXT query, using the hostname in the Name field of
+ the DNS query. If the record is not found, the first label of the
+ name is stripped and the query is retried.
+
+ Compliant implementations MUST query the full hostname and the most
+ specific domain name (the hostname with the first label removed).
+ Compliant implementations SHOULD try stripping all subsequent labels
+ until a match is found or the Name field is empty.
+
+Example - Hostname/domain name to Kerberos realm mapping
+
+ For the previously mentioned ASDF.COM realm and domain, some sample
+ records might be as follows:
+
+ _kerberos.asdf.com. IN TXT "ASDF.COM"
+
+Hornstein, Altman [Page 3]
+
+RFC DRAFT June 21, 1999
+
+ _kerberos.mrkserver.asdf.com. IN TXT "MARKETING.ASDF.COM"
+ _kerberos.salesserver.asdf.com. IN TXT "SALES.ASDF.COM"
+
+ Let us suppose that in this case, a Kerberos client wishes to use a
+ Kerberized service on the host foo.asdf.com. It would first query:
+
+ _kerberos.foo.asdf.com. IN TXT
+
+ Finding no match, it would then query:
+
+ _kerberos.asdf.com. IN TXT
+
+ And find an answer of ASDF.COM. This would be the realm that
+ foo.asdf.com resides in.
+
+ If another Kerberos client wishes to use a Kerberized service on the
+ host salesserver.asdf.com, it would query:
+
+ _kerberos.salesserver.asdf.com IN TXT
+
+ And find an answer of SALES.ASDF.COM.
+
+Security considerations
+
+ As DNS is deployed today, it is an unsecure service. Thus the infor-
+ mation returned by it cannot be trusted. However, the use of DNS to
+ store this configuration information does not introduce any new secu-
+ rity risks to the Kerberos protocol.
+
+ Current practice is to use hostnames to indicate KDC hosts (stored in
+ some implementation-dependent location, but generally a local config
+ file). These hostnames are vulnerable to the standard set of DNS
+ attacks (denial of service, spoofed entries, etc). The design of the
+ Kerberos protocol limits attacks of this sort to denial of service.
+ However, the use of SRV records does not change this attack in any
+ way. They have the same vulnerabilities that already exist in the
+ common practice of using hostnames for KDC locations.
+
+ The same holds true for the TXT records used to indicate the domain
+ name to realm mapping. Current practice is to configure these map-
+ pings locally. But this again is vulnerable to spoofing via CNAME
+ records that point to hosts in other domains. This has the same
+ effect as a spoofed TXT record.
+
+ While the described protocol does not introduce any new security
+ risks to the best of our knowledge, implementations SHOULD provide a
+ way of specifying this information locally without the use of DNS.
+ However, to make this feature worthwhile a lack of any configuration
+
+Hornstein, Altman [Page 4]
+
+RFC DRAFT June 21, 1999
+
+ information on a client should be interpretted as permission to use
+ DNS.
+
+Expiration
+
+ This Internet-Draft expires on December 21, 1999.
+
+References
+
+ [RFC1510]
+ The Kerberos Network Authentication System; Kohl, Newman; Sep-
+ tember 1993.
+
+ [RFC1035]
+ Domain Names - Implementation and Specification; Mockapetris;
+ November 1987
+
+ [RFC2052]
+ A DNS RR for specifying the location of services (DNS SRV); Gul-
+ brandsen, Vixie; October 1996
+
+Authors' Addresses
+
+ Ken Hornstein
+ US Naval Research Laboratory
+ Bldg A-49, Room 2
+ 4555 Overlook Avenue
+ Washington DC 20375 USA
+
+ Phone: +1 (202) 404-4765
+ EMail: kenh@cmf.nrl.navy.mil
+
+ Jeffrey Altman
+ The Kermit Project
+ Columbia University
+ 612 West 115th Street #716
+ New York NY 10025-7799 USA
+
+ Phone: +1 (212) 854-1344
+ EMail: jaltman@columbia.edu
+
+Hornstein, Altman [Page 5]
diff --git a/crypto/heimdal/doc/standardisation/draft-ietf-ftpext-mlst-08.txt b/crypto/heimdal/doc/standardisation/draft-ietf-ftpext-mlst-08.txt
new file mode 100644
index 000000000000..885cf4967679
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/draft-ietf-ftpext-mlst-08.txt
@@ -0,0 +1,3415 @@
+FTPEXT Working Group R. Elz
+Internet Draft University of Melbourne
+Expiration Date: April 2000
+ P. Hethmon
+ Hethmon Brothers
+
+ October 1999
+
+
+ Extensions to FTP
+
+
+ draft-ietf-ftpext-mlst-08.txt
+
+Status of this Memo
+
+ This document is an Internet-Draft and is NOT offered in accordance
+ with Section 10 of RFC2026, and the author does not provide the IETF
+ with any rights other than to publish as an Internet-Draft.
+
+ Internet-Drafts are working documents of the Internet Engineering
+ Task Force (IETF), its areas, and its working groups. Note that
+ other groups may also distribute working documents as Internet-
+ Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt.
+
+ To view the list Internet-Draft Shadow Directories, see
+ http://www.ietf.org/shadow.html.
+
+ This entire section has been prepended to this document automatically
+ during formatting without any direct involvement by the author(s) of
+ this draft.
+
+
+
+
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 1]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+Abstract
+
+ In order to overcome the problems caused by the undefined format of
+ the current FTP LIST command output, a new command is needed to
+ transfer standardized listing information from Server-FTP to User-
+ FTP. Commands to enable this are defined in this document.
+
+ In order to allow consenting clients and servers to interact more
+ freely, a quite basic, and optional, virtual file store structure is
+ defined.
+
+ This proposal also extends the FTP protocol to allow character sets
+ other than US-ASCII[1] by allowing the transmission of 8-bit
+ characters and the recommended use of UTF-8[2] encoding.
+
+ Much implemented, but long undocumented, mechanisms to permit
+ restarts of interrupted data transfers in STREAM mode, are also
+ included here.
+
+ Lastly, the HOST command has been added to allow a style of "virtual
+ site" to be constructed.
+
+ Changed in this version of this document: Minor corrections as
+ discussed on the mailing list, including fixing many typographical
+ errors; Additional examples. This paragraph will be deleted from the
+ final version of this document.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 2]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+
+
+Table of Contents
+
+ Abstract ................................................ 2
+ 1 Introduction ............................................ 4
+ 2 Document Conventions .................................... 4
+ 2.1 Basic Tokens ............................................ 5
+ 2.2 Pathnames ............................................... 5
+ 2.3 Times ................................................... 7
+ 2.4 Server Replies .......................................... 8
+ 3 File Modification Time (MDTM) ........................... 8
+ 3.1 Syntax .................................................. 9
+ 3.2 Error responses ......................................... 9
+ 3.3 FEAT response for MDTM .................................. 9
+ 3.4 MDTM Examples ........................................... 10
+ 4 File SIZE ............................................... 11
+ 4.1 Syntax .................................................. 11
+ 4.2 Error responses ......................................... 11
+ 4.3 FEAT response for SIZE .................................. 12
+ 4.4 Size Examples ........................................... 12
+ 5 Restart of Interrupted Transfer (REST) .................. 13
+ 5.1 Restarting in STREAM Mode ............................... 13
+ 5.2 Error Recovery and Restart .............................. 14
+ 5.3 Syntax .................................................. 14
+ 5.4 FEAT response for REST .................................. 16
+ 5.5 REST Example ............................................ 16
+ 6 Virtual FTP servers ..................................... 16
+ 6.1 The HOST command ........................................ 18
+ 6.2 Syntax of the HOST command .............................. 18
+ 6.3 HOST command semantics .................................. 19
+ 6.4 HOST command errors ..................................... 21
+ 6.5 FEAT response for HOST command .......................... 22
+ 7 A Trivial Virtual File Store (TVFS) ..................... 23
+ 7.1 TVFS File Names ......................................... 23
+ 7.2 TVFS Path Names ......................................... 24
+ 7.3 FEAT Response for TVFS .................................. 25
+ 7.4 OPTS for TVFS ........................................... 26
+ 7.5 TVFS Examples ........................................... 26
+ 8 Listings for Machine Processing (MLST and MLSD) ......... 28
+ 8.1 Format of MLSx Requests ................................. 29
+ 8.2 Format of MLSx Response ................................. 29
+ 8.3 Filename encoding ....................................... 32
+ 8.4 Format of Facts ......................................... 33
+ 8.5 Standard Facts .......................................... 33
+ 8.6 System Dependent and Local Facts ........................ 41
+ 8.7 MLSx Examples ........................................... 42
+ 8.8 FEAT response for MLSx .................................. 50
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 3]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ 8.9 OPTS parameters for MLST ................................ 51
+ 9 Impact On Other FTP Commands ............................ 55
+ 10 Character sets and Internationalization ................. 56
+ 11 IANA Considerations ..................................... 56
+ 11.1 The OS specific fact registry ........................... 56
+ 11.2 The OS specific filetype registry ....................... 57
+ 12 Security Considerations ................................. 57
+ 13 References .............................................. 58
+ Acknowledgments ......................................... 59
+ Copyright ............................................... 60
+ Editors' Addresses ...................................... 60
+
+
+
+
+1. Introduction
+
+ This document amends the File Transfer Protocol (FTP) [3]. Five new
+ commands are added: "SIZE", "HOST", "MDTM", "MLST", and "MLSD". The
+ existing command "REST" is modified. Of those, the "SIZE" and "MDTM"
+ commands, and the modifications to "REST" have been in wide use for
+ many years. The others are new.
+
+ These commands allow a client to restart an interrupted transfer in
+ transfer modes not previously supported in any documented way, to
+ support the notion of virtual hosts, and to obtain a directory
+ listing in a machine friendly, predictable, format.
+
+ An optional structure for the server's file store (NVFS) is also
+ defined, allowing servers that support such a structure to convey
+ that information to clients in a standard way, thus allowing clients
+ more certainty in constructing and interpreting path names.
+
+2. Document Conventions
+
+ This document makes use of the document conventions defined in BCP14
+ [4]. That provides the interpretation of capitalized imperative
+ words like MUST, SHOULD, etc.
+
+ This document also uses notation defined in STD 9 [3]. In
+ particular, the terms "reply", "user", "NVFS", "file", "pathname",
+ "FTP commands", "DTP", "user-FTP process", "user-PI", "user-DTP",
+ "server-FTP process", "server-PI", "server-DTP", "mode", "type",
+ "NVT", "control connection", "data connection", and "ASCII", are all
+ used here as defined there.
+
+ Syntax required is defined using the Augmented BNF defined in [5].
+ Some general ABNF definitions are required throughout the document,
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 4]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ those will be defined later in this section. At first reading, it
+ may be wise to simply recall that these definitions exist here, and
+ skip to the next section.
+
+2.1. Basic Tokens
+
+ This document imports the core definitions given in Appendix A of
+ [5]. There definitions will be found for basic ABNF elements like
+ ALPHA, DIGIT, SP, etc. To that, the following terms are added for
+ use in this document.
+
+ TCHAR = VCHAR / SP / HTAB ; visible plus white space
+ RCHAR = ALPHA / DIGIT / "," / "." / ":" / "!" /
+ "@" / "#" / "$" / "%" / "^" /
+ "&" / "(" / ")" / "-" / "_" /
+ "+" / "?" / "/" / "\" / "'" /
+ DQUOTE ; <"> -- double quote character (%x22)
+
+ The VCHAR (from [5]), TCHAR, and RCHAR types give basic character
+ types from varying sub-sets of the ASCII character set for use in
+ various commands and responses.
+
+ token = 1*RCHAR
+
+ A "token" is a string whose precise meaning depends upon the context
+ in which it is used. In some cases it will be a value from a set of
+ possible values maintained elsewhere. In others it might be a string
+ invented by one party to an FTP conversation from whatever sources it
+ finds relevant.
+
+ Note that in ABNF, string literals are case insensitive. That
+ convention is preserved in this document, and implies that FTP
+ commands added by this specification have names that can be
+ represented in any case. That is, "MDTM" is the same as "mdtm",
+ "Mdtm" and "MdTm" etc. However note that ALPHA, in particular, is
+ case sensitive. That implies that a "token" is a case sensitive
+ value. That implication is correct.
+
+2.2. Pathnames
+
+ Various FTP commands take pathnames as arguments, or return pathnames
+ in responses. When the MLST command is supported, as indicated in
+ the response to the FEAT command [6], pathnames are to be transferred
+ in one of the following two formats.
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 5]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ pathname = utf-8-name / raw
+ utf-8-name = <a UTF-8 encoded Unicode string>
+ raw = <any string not being a valid UTF-8 encoding>
+
+ Which format is used is at the option of the user-PI or server-PI
+ sending the pathname. UTF-8 encodings [2] contain enough internal
+ structure that it is always, in practice, possible to determine
+ whether a UTF-8 or raw encoding has been used, in those cases where
+ it matters. While it is useful for the user-PI to be able to
+ correctly display a pathname received from the server-PI to the user,
+ it is far more important for the user-PI to be able to retain and
+ retransmit the identical pathname when required. Implementations are
+ advised against converting a UTF-8 pathname to a local encoding, and
+ then attempting to invert the encoding later. Note that ASCII is a
+ subset of UTF-8.
+
+ Unless otherwise specified, the pathname is terminated by the CRLF
+ that terminates the FTP command, or by the CRLF that ends a reply.
+ Any trailing spaces preceding that CRLF form part of the name.
+ Exactly one space will precede the pathname and serve as a separator
+ from the preceding syntax element. Any additional spaces form part
+ of the pathname. See [7] for a fuller explanation of the character
+ encoding issues. All implementations supporting MLST MUST support
+ [7].
+
+ Implementations should also beware that the control connection uses
+ Telnet NVT conventions [8], and that the Telnet IAC character, if
+ part of a pathname sent over the control connection, MUST be
+ correctly escaped as defined by the Telnet protocol.
+
+ Implementors should also be aware that although Telnet NVT
+ conventions are used over the control connections, Telnet option
+ negotiation MUST NOT be attempted. See section 4.1.2.12 of [9].
+
+2.2.1. Pathname Syntax
+
+ Except where TVFS is supported (see section 7) this specification
+ imposes no syntax upon pathnames. Nor does it restrict the character
+ set from which pathnames are created. This does not imply that the
+ NVFS is required to make sense of all possible pathnames. Server-PIs
+ may restrict the syntax of valid pathnames in their NVFS in any
+ manner appropriate to their implementation or underlying file system.
+ Similarly, a server-PI may parse the pathname, and assign meaning to
+ the components detected.
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 6]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+2.2.2. Wildcarding
+
+ For the commands defined in this specification, all pathnames are to
+ be treated literally. That is, for a pathname given as a parameter
+ to a command, the file whose name is identical to the pathname given
+ is implied. No characters from the pathname may be treated as
+ special or "magic", thus no pattern matching (other than for exact
+ equality) between the pathname given and the files present in the
+ NVFS of the Server-FTP is permitted.
+
+ Clients that desire some form of pattern matching functionality must
+ obtain a listing of the relevant directory, or directories, and
+ implement their own filename selection procedures.
+
+2.3. Times
+
+ The syntax of a time value is:
+
+ time-val = 14DIGIT [ "." 1*DIGIT ]
+
+ The leading, mandatory, fourteen digits are to be interpreted as, in
+ order from the leftmost, four digits giving the year, with a range of
+ 1000-9999, two digits giving the month of the year, with a range of
+ 01-12, two digits giving the day of the month, with a range of 01-31,
+ two digits giving the hour of the day, with a range of 00-23, two
+ digits giving minutes past the hour, with a range of 00-59, and
+ finally, two digits giving seconds past the minute, with a range of
+ 00-60 (with 60 being used only at a leap second). Years in the tenth
+ century, and earlier, cannot be expressed. This is not considered a
+ serious defect of the protocol.
+
+ The optional digits, which are preceded by a period, give decimal
+ fractions of a second. These may be given to whatever precision is
+ appropriate to the circumstance, however implementations MUST NOT add
+ precision to time-vals where that precision does not exist in the
+ underlying value being transmitted.
+
+ Symbolically, a time-val may be viewed as
+
+ YYYYMMDDHHMMSS.sss
+
+ The "." and subsequent digits ("sss") are optional. However the "."
+ MUST NOT appear unless at least one following digit also appears.
+
+ Time values are always represented in UTC (GMT), and in the Gregorian
+ calendar regardless of what calendar may have been in use at the date
+ and time indicated at the location of the server-PI.
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 7]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ The technical differences between GMT, TAI, UTC, UT1, UT2, etc, are
+ not considered here. A server-FTP process should always use the same
+ time reference, so the times it returns will be consistent. Clients
+ are not expected to be time synchronized with the server, so the
+ possible difference in times that might be reported by the different
+ time standards is not considered important.
+
+2.4. Server Replies
+
+ Section 4.2 of [3] defines the format and meaning of replies by the
+ server-PI to FTP commands from the user-PI. Those reply conventions
+ are used here without change.
+
+ error-response = error-code SP *TCHAR CRLF
+ error-code = ("4" / "5") 2DIGIT
+
+ Implementors should note that the ABNF syntax (which was not used in
+ [3]) used in this document, and other FTP related documents,
+ sometimes shows replies using the one line format. Unless otherwise
+ explicitly stated, that is not intended to imply that multi-line
+ responses are not permitted. Implementors should assume that, unless
+ stated to the contrary, any reply to any FTP command (including QUIT)
+ may be of the multi-line format described in [3].
+
+ Throughout this document, replies will be identified by the three
+ digit code that is their first element. Thus the term "500 reply"
+ means a reply from the server-PI using the three digit code "500".
+
+3. File Modification Time (MDTM)
+
+ The FTP command, MODIFICATION TIME (MDTM), can be used to determine
+ when a file in the server NVFS was last modified. This command has
+ existed in many FTP servers for many years, as an adjunct to the REST
+ command for STREAM mode, thus is widely available. However, where
+ supported, the "modify" fact which can be provided in the result from
+ the new MLST command is recommended as a superior alternative.
+
+ When attempting to restart a RETRieve, if the User-FTP makes use of
+ the MDTM command, or "modify" fact, it can check and see if the
+ modification time of the source file is more recent than the
+ modification time of the partially transferred file. If it is, then
+ most likely the source file has changed and it would be unsafe to
+ restart the previously incomplete file transfer.
+
+ When attempting to restart a STORe, the User FTP can use the MDTM
+ command to discover the modification time of the partially
+ transferred file. If it is older than the modification time of the
+ file that is about to be STORed, then most likely the source file has
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 8]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ changed and it would be unsafe to restart the file transfer.
+
+ Note that using MLST (described below) where available, can provide
+ this information, and much more, thus giving an even better
+ indication that a file has changed, and that restarting a transfer
+ would not give valid results.
+
+ Note that this is applicable to any RESTart attempt, regardless of
+ the mode of the file transfer.
+
+3.1. Syntax
+
+ The syntax for the MDTM command is:
+
+ mdtm = "MdTm" SP pathname CRLF
+
+ As with all FTP commands, the "MDTM" command label is interpreted in
+ a case insensitive manner.
+
+ The "pathname" specifies an object in the NVFS which may be the
+ object of a RETR command. Attempts to query the modification time of
+ files that are unable to be retrieved generate undefined responses.
+
+ The server-PI will respond to the MDTM command with a 213 reply
+ giving the last modification time of the file whose pathname was
+ supplied, or a 550 reply if the file does not exist, the modification
+ time is unavailable, or some other error has occurred.
+
+ mdtm-response = "213" SP time-val CRLF /
+ error-response
+
+3.2. Error responses
+
+ Where the command is correctly parsed, but the modification time is
+ not available, either because the pathname identifies no existing
+ entity, or because the information is not available for the entity
+ named, then a 550 reply should be sent. Where the command cannot be
+ correctly parsed, a 500 or 501 reply should be sent, as specified in
+ [3].
+
+3.3. FEAT response for MDTM
+
+ When replying to the FEAT command [6], an FTP server process that
+ supports the MDTM command MUST include a line containing the single
+ word "MDTM". This MAY be sent in upper or lower case, or a mixture
+ of both (it is case insensitive) but SHOULD be transmitted in upper
+ case only. That is, the response SHOULD be
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 9]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ C> Feat
+ S> 211- <any descriptive text>
+ S> ...
+ S> MDTM
+ S> ...
+ S> 211 End
+
+ The ellipses indicate place holders where other features may be
+ included, and are not required. The one space indentation of the
+ feature lines is mandatory [6].
+
+3.4. MDTM Examples
+
+ If we assume the existence of three files, A B and C, and a directory
+ D, and no other files at all, then the MTDM command may behave as
+ indicated. The "C>" lines are commands from user-PI to server-PI,
+ the "S>" lines are server-PI replies.
+
+ C> MDTM A
+ S> 213 19980615100045.014
+ C> MDTM B
+ S> 213 19980615100045.014
+ C> MDTM C
+ S> 213 19980705132316
+ C> MDTM D
+ S> 550 D is not retrievable
+ C> MDTM E
+ S> 550 No file named "E"
+ C> mdtm file6
+ S> 213 19990929003355
+ C> MdTm 19990929043300 File6
+ S> 213 19991005213102
+ C> MdTm 19990929043300 file6
+ S> 550 19990929043300 file6: No such file or directory.
+
+ From that we can conclude that both A and B were last modified at the
+ same time (to the nearest millisecond), and that C was modified 21
+ days and several hours later.
+
+ The times are in GMT, so file A was modified on the 15th of June,
+ 1998, at approximately 11am in London (summer time was then in
+ effect), or perhaps at 8pm in Melbourne, Australia, or at 6am in New
+ York. All of those represent the same absolute time of course. The
+ location where the file was modified, and consequently the local wall
+ clock time at that location, is not available.
+
+ There is no file named "E" in the current directory, but there are
+ files named both "file6" and "19990929043300 File6". The
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 10]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ modification times of those files were obtained. There is no file
+ named "19990929043300 file6".
+
+4. File SIZE
+
+ The FTP command, SIZE OF FILE (SIZE), is used to obtain the transfer
+ size of a file from the server-FTP process. That is, the exact
+ number of octets (8 bit bytes) which would be transmitted over the
+ data connection should that file be transmitted. This value will
+ change depending on the current STRUcture, MODE and TYPE of the data
+ connection, or a data connection which would be created were one
+ created now. Thus, the result of the SIZE command is dependent on
+ the currently established STRU, MODE and TYPE parameters.
+
+ The SIZE command returns how many octets would be transferred if the
+ file were to be transferred using the current transfer structure,
+ mode and type. This command is normally used in conjunction with the
+ RESTART (REST) command. The server-PI might need to read the
+ partially transferred file, do any appropriate conversion, and count
+ the number of octets that would be generated when sending the file in
+ order to correctly respond to this command. Estimates of the file
+ transfer size MUST NOT be returned, only precise information is
+ acceptable.
+
+4.1. Syntax
+
+ The syntax of the SIZE command is:
+
+ size = "Size" SP pathname CRLF
+
+ The server-PI will respond to the SIZE command with a 213 reply
+ giving the transfer size of the file whose pathname was supplied, or
+ an error response if the file does not exist, the size is
+ unavailable, or some other error has occurred. The value returned is
+ in a format suitable for use with the RESTART (REST) command for mode
+ STREAM, provided the transfer mode and type are not altered.
+
+ size-response = "213" SP 1*DIGIT CRLF /
+ error-response
+
+4.2. Error responses
+
+ Where the command is correctly parsed, but the size is not available,
+ either because the pathname identifies no existing entity, or because
+ the entity named cannot be transferred in the current MODE and TYPE
+ (or at all), then a 550 reply should be sent. Where the command
+ cannot be correctly parsed, a 500 or 501 reply should be sent, as
+ specified in [3].
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 11]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+4.3. FEAT response for SIZE
+
+ When replying to the FEAT command [6], an FTP server process that
+ supports the SIZE command MUST include a line containing the single
+ word "SIZE". This word is case insensitive, and MAY be sent in any
+ mixture of upper or lower case, however it SHOULD be sent in upper
+ case. That is, the response SHOULD be
+
+ C> FEAT
+ S> 211- <any descriptive text>
+ S> ...
+ S> SIZE
+ S> ...
+ S> 211 END
+
+ The ellipses indicate place holders where other features may be
+ included, and are not required. The one space indentation of the
+ feature lines is mandatory [6].
+
+4.4. Size Examples
+
+ Consider a text file "Example" stored on a Unix(TM) server where each
+ end of line is represented by a single octet. Assume the file
+ contains 112 lines, and 1830 octets total. Then the SIZE command
+ would produce:
+
+ C> TYPE I
+ S> 200 Type set to I.
+ C> size Example
+ S> 213 1830
+ C> TYPE A
+ S> 200 Type set to A.
+ C> Size Example
+ S> 213 1942
+
+ Notice that with TYPE=A the SIZE command reports an extra 112 octets.
+ Those are the extra octets that need to be inserted, one at the end
+ of each line, to provide correct end of line semantics for a transfer
+ using TYPE=A. Other systems might need to make other changes to the
+ transfer format of files when converting between TYPEs and MODEs.
+ The SIZE command takes all of that into account.
+
+ Since calculating the size of a file with this degree of precision
+ may take considerable effort on the part of the server-PI, user-PIs
+ should not used this command unless this precision is essential (such
+ as when about to restart an interrupted transfer). For other uses,
+ the "Size" fact of the MLST command (see section 8.5.7) ought be
+ requested.
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 12]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+5. Restart of Interrupted Transfer (REST)
+
+ To avoid having to resend the entire file if the file is only
+ partially transferred, both sides need some way to be able to agree
+ on where in the data stream to restart the data transfer.
+
+ The FTP specification [3] includes three modes of data transfer,
+ Stream, Block and Compressed. In Block and Compressed modes, the
+ data stream that is transferred over the data connection is
+ formatted, allowing the embedding of restart markers into the stream.
+ The sending DTP can include a restart marker with whatever
+ information it needs to be able to restart a file transfer at that
+ point. The receiving DTP can keep a list of these restart markers,
+ and correlate them with how the file is being saved. To restart the
+ file transfer, the receiver just sends back that last restart marker,
+ and both sides know how to resume the data transfer. Note that there
+ are some flaws in the description of the restart mechanism in RFC 959
+ [3]. See section 4.1.3.4 of RFC 1123 [9] for the corrections.
+
+5.1. Restarting in STREAM Mode
+
+ In Stream mode, the data connection contains just a stream of
+ unformatted octets of data. Explicit restart markers thus cannot be
+ inserted into the data stream, they would be indistinguishable from
+ data. For this reason, the FTP specification [3] did not provide the
+ ability to do restarts in stream mode. However, there is not really
+ a need to have explicit restart markers in this case, as restart
+ markers can be implied by the octet offset into the data stream.
+
+ Because the data stream defines the file in STREAM mode, a different
+ data stream would represent a different file. Thus, an offset will
+ always represent the same position within a file. On the other hand,
+ in other modes than STREAM, the same file can be transferred using
+ quite different octet sequences, and yet be reconstructed into the
+ one identical file. Thus an offset into the data stream in transfer
+ modes other than STREAM would not give an unambiguous restart point.
+
+ If the data representation TYPE is IMAGE, and the STRUcture is File,
+ for many systems the file will be stored exactly in the same format
+ as it is sent across the data connection. It is then usually very
+ easy for the receiver to determine how much data was previously
+ received, and notify the sender of the offset where the transfer
+ should be restarted. In other representation types and structures
+ more effort will be required, but it remains always possible to
+ determine the offset with finite, but perhaps non-negligible, effort.
+ In the worst case an FTP process may need to open a data connection
+ to itself, set the appropriate transfer type and structure, and
+ actually transmit the file, counting the transmitted octets.
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 13]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ If the user-FTP process is intending to restart a retrieve, it will
+ directly calculate the restart marker, and send that information in
+ the RESTart command. However, if the user-FTP process is intending
+ to restart sending the file, it needs to be able to determine how
+ much data was previously sent, and correctly received and saved. A
+ new FTP command is needed to get this information. This is the
+ purpose of the SIZE command, as documented in section 4.
+
+5.2. Error Recovery and Restart
+
+ STREAM MODE transfers with FILE STRUcture may be restarted even
+ though no restart marker has been transferred in addition to the data
+ itself. This is done by using the SIZE command, if needed, in
+ combination with the RESTART (REST) command, and one of the standard
+ file transfer commands.
+
+ When using TYPE ASCII or IMAGE, the SIZE command will return the
+ number of octets that would actually be transferred if the file were
+ to be sent between the two systems. I.e. with type IMAGE, the SIZE
+ normally would be the number of octets in the file. With type ASCII,
+ the SIZE would be the number of octets in the file including any
+ modifications required to satisfy the TYPE ASCII CR-LF end of line
+ convention.
+
+5.3. Syntax
+
+ The syntax for the REST command when the current transfer mode is
+ STREAM is:
+
+ rest = "Rest" SP 1*DIGIT CRLF
+
+ The numeric value gives the number of octets of the immediately
+ following transfer to not actually send, effectively causing the
+ transmission to be restarted at a later point. A value of zero
+ effectively disables restart, causing the entire file to be
+ transmitted. The server-PI will respond to the REST command with a
+ 350 reply, indicating that the REST parameter has been saved, and
+ that another command, which should be either RETR or STOR, should
+ then follow to complete the restart.
+
+ rest-response = "350" SP *TCHAR CRLF /
+ error-response
+
+ Server-FTP processes may permit transfer commands other than RETR and
+ STOR, such as APPE and STOU, to complete a restart, however, this is
+ not recommended. STOU (store unique) is undefined in this usage, as
+ storing the remainder of a file into a unique filename is rarely
+ going to be useful. If APPE (append) is permitted, it MUST act
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 14]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ identically to STOR when a restart marker has been set. That is, in
+ both cases, octets from the data connection are placed into the file
+ at the location indicated by the restart marker value.
+
+ The REST command is intended to complete a failed transfer. Use with
+ RETR is comparatively well defined in all cases, as the client bears
+ the responsibility of merging the retrieved data with the partially
+ retrieved file. If it chooses to use the data obtained other than to
+ complete an earlier transfer, or if it chooses to re-retrieve data
+ that had been retrieved before, that is its choice. With STOR,
+ however, the server must insert the data into the file named. The
+ results are undefined if a client uses REST to do other than restart
+ to complete a transfer of a file which had previously failed to
+ completely transfer. In particular, if the restart marker set with a
+ REST command is not at the end of the data currently stored at the
+ server, as reported by the server, or if insufficient data are
+ provided in a STOR that follows a REST to extend the destination file
+ to at least its previous size, then the effects are undefined.
+
+ The REST command must be the last command issued before the data
+ transfer command which is to cause a restarted rather than complete
+ file transfer. The effect of issuing a REST command at any other
+ time is undefined. The server-PI may react to a badly positioned
+ REST command by issuing an error response to the following command,
+ not being a restartable data transfer command, or it may save the
+ restart value and apply it to the next data transfer command, or it
+ may silently ignore the inappropriate restart attempt. Because of
+ this, a user-PI that has issued a REST command, but which has not
+ successfully transmitted the following data transfer command for any
+ reason, should send another REST command before the next data
+ transfer command. If that transfer is not to be restarted, then
+ "REST 0" should be issued.
+
+ An error-response will follow a REST command only when the server
+ does not implement the command, or the restart marker value is
+ syntactically invalid for the current transfer mode. That is, in
+ STREAM mode, if something other than one or more digits appears in
+ the parameter to the REST command. Any other errors, including such
+ problems as restart marker out of range, should be reported when the
+ following transfer command is issued. Such errors will cause that
+ transfer request to be rejected with an error indicating the invalid
+ restart attempt.
+
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 15]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+5.4. FEAT response for REST
+
+ Where a server-FTP process supports RESTart in STREAM mode, as
+ specified here, it MUST include in the response to the FEAT command
+ [6], a line containing exactly the string "REST STREAM". This string
+ is not case sensitive, but SHOULD be transmitted in upper case.
+ Where REST is not supported at all, or supported only in block or
+ compressed modes, the REST line MUST NOT be included in the FEAT
+ response. Where required, the response SHOULD be
+
+ C> feat
+ S> 211- <any descriptive text>
+ S> ...
+ S> REST STREAM
+ S> ...
+ S> 211 end
+
+ The ellipses indicate place holders where other features may be
+ included, and are not required. The one space indentation of the
+ feature lines is mandatory [6].
+
+5.5. REST Example
+
+ Assume that the transfer of a largish file has previously been
+ interrupted after 802816 octets had been received, that the previous
+ transfer was with TYPE=I, and that it has been verified that the file
+ on the server has not since changed.
+
+ C> TYPE I
+ S> 200 Type set to I.
+ C> PORT 127,0,0,1,15,107
+ S> 200 PORT command successful.
+ C> REST 802816
+ S> 350 Restarting at 802816. Send STORE or RETRIEVE
+ C> RETR cap60.pl198.tar
+ S> 150 Opening BINARY mode data connection
+ [...]
+ S> 226 Transfer complete.
+
+6. Virtual FTP servers
+
+ It has become common in the Internet for many domain names to be
+ allocated to a single IP address. This has introduced the concept of
+ a "virtual host", where a host appears to exist as an independent
+ entity, but in reality shares all of its resources with one, or more,
+ other such hosts.
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 16]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ Such an arrangement presents some problems for FTP Servers, as all
+ the FTP Server can detect is an incoming FTP connection to a
+ particular IP address. That is, all domain names which share the IP
+ address also share the FTP server, and more importantly, its NVFS.
+ This means that the various virtual hosts cannot offer different
+ virtual file systems to clients, nor can they offer different
+ authentication systems.
+
+ No scheme can overcome this without modifications of some kind to the
+ user-PI and the user-FTP process. That process is the only entity
+ that knows which virtual host is required. It has performed the
+ domain name to IP address translation, and thus has the original
+ domain name available.
+
+ One method which could be used to allow a style of virtual host would
+ be for the client to simply send a "CWD" command after connecting,
+ using the virtual host name as the argument to the CWD command. This
+ would allow the server-FTP process to implement the file stores of
+ the virtual hosts as sub-directories in its NVFS. This is simple,
+ and supported by essentially all server-FTP implementations without
+ requiring any code changes.
+
+ While that method is simple to describe, and to implement, it suffers
+ from several drawbacks. First, the "CWD" command is available only
+ after the user-PI has authenticated itself to the server-FTP process.
+ Thus, all virtual hosts would be required to share a common
+ authentication scheme. Second, either the server-FTP process needs
+ to be modified to understand the special nature of this first CWD
+ command, negating most of the advantage of this scheme, or all users
+ must see the same identical NVFS view upon connecting (they must
+ connect in the same initial directory) or the NVFS must implement the
+ full set of virtual host directories at each possible initial
+ directory for any possible user, or the virtual host will not be
+ truly transparent. Third, and again unless the server is specially
+ modified, a user connecting this way to a virtual host would be able
+ to trivially move to any other virtual host supported at the same
+ server-FTP process, exposing the nature of the virtual host.
+
+ Other schemes overloading other existing FTP commands have also been
+ proposed. None of those have sufficient merit to be worth
+ discussion.
+
+ The conclusion from the examination of the possibilities seems to be
+ that to obtain an adequate emulation of "real" FTP servers, server
+ modifications to support virtual hosts are required. A new command
+ seems most likely to provide the support required.
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 17]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+6.1. The HOST command
+
+ A new command "HOST" is added to the FTP command set to allow
+ server-FTP process to determine to which of possibly many virtual
+ hosts the client wishes to connect. This command is intended to be
+ issued before the user is authenticated, allowing the authentication
+ scheme, and set of legal users, to be dependent upon the virtual host
+ chosen. Server-FTP processes may, if they desire, permit the HOST
+ command to be issued after the user has been authenticated, or may
+ treat that as an erroneous sequence of commands. The behavior of the
+ server-FTP process which does allow late HOST commands is undefined.
+ One reasonable interpretation would be for the user-PI to be returned
+ to the state that existed after the TCP connection was first
+ established, before user authentication.
+
+ Servers should note that the response to the HOST command is a
+ sensible time to send their "welcome" message. This allows the
+ message to be personalized for any virtual hosts that are supported,
+ and also allows the client to have determined supported languages, or
+ representations, for the message, and other messages, via the FEAT
+ response, and selected an appropriate one via the LANG command. See
+ [7] for more information.
+
+6.2. Syntax of the HOST command
+
+ The HOST command is defined as follows.
+
+ host-command = "Host" SP hostname CRLF
+ hostname = 1*DNCHAR 1*( "." 1*DNCHAR ) [ "." ]
+ DNCHAR = ALPHA / DIGIT / "-" / "_" / "$" /
+ "!" / "%" / "[" / "]" / ":"
+ host-response = host-ok / error-response
+ host-ok = "220" [ SP *TCHAR ] CRLF
+
+ As with all FTP commands, the "host" command word is case
+ independent, and may be specified in any character case desired.
+
+ The "hostname" given as a parameter specifies the virtual host to
+ which access is desired. It should normally be the same name that
+ was used to obtain the IP address to which the FTP control connection
+ was made, after any client conversions to convert an abbreviated or
+ local alias to a complete (fully qualified) domain name, but before
+ resolving a DNS alias (owner of a CNAME resource record) to its
+ canonical name.
+
+ If the client was given a network literal address, and consequently
+ was not required to derive it from a hostname, it should send the
+ HOST command with the network address, as specified to it, enclosed
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 18]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ in brackets (after eliminating any syntax, which might also be
+ brackets, but is not required to be, from which the server deduced
+ that a literal address had been specified.) That is, for example
+
+ HOST [10.1.2.3]
+
+ should be sent if the client had been instructed to connect to
+ "10.1.2.3", or "[10.1.2.3]", or perhaps even IPv4:10.1.2.3. The
+ method of indicating to a client that a literal address is to be used
+ is beyond the scope of this specification.
+
+ The parameter is otherwise to be treated as a "complete domain name",
+ as that term is defined in section 3.1 of RFC 1034 [10]. That
+ implies that the name is to be treated as a case independent string,
+ in that upper case ASCII characters are to be treated as equivalent
+ to the corresponding lower case ASCII characters, but otherwise
+ preserved as given. It also implies some limits on the length of the
+ parameter and of the components that create its internal structure.
+ Those limits are not altered in any way here.
+
+ RFC 1034 imposes no other restrictions upon what kinds of names can
+ be stored in the DNS. Nor does RFC 1035. This specification,
+ however, allows only a restricted set of names for the purposes of
+ the HOST command. Those restrictions can be inferred from the ABNF
+ grammar given for the "hostname".
+
+6.3. HOST command semantics
+
+ Upon receiving the HOST command, before authenticating the user-PI, a
+ server-FTP process should validate that the hostname given represents
+ a valid virtual host for that server, and if so, establish the
+ appropriate environment for that virtual host. The meaning of that
+ is not specified here, and may range from doing nothing at all, or
+ performing a simple change of working directory, to much more
+ elaborate state changes, as required.
+
+ If the hostname specified is unknown at the server, or if the server
+ is otherwise unwilling to treat the particular connection as a
+ connection to the hostname specified, the server will respond with a
+ 504 reply.
+
+ Note: servers may require that the name specified is in some sense
+ equivalent to the particular network address that was used to reach
+ the server.
+
+ If the hostname specified would normally be acceptable, but for any
+ reason is temporarily unavailable, the server SHOULD reply to the
+ HOST command with a 434 reply.
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 19]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ The "220" reply code for the HOST command is the same as the code
+ used on the initial connection established "welcome" message. This
+ is done deliberately so as to allow the implementation to implement
+ the front end FTP server as a wrapper which simply waits for the HOST
+ command, and then invokes an older, RFC959 compliant, server in the
+ appropriate environment for the particular hostname received.
+
+6.3.1. The REIN command
+
+ As specified in [3], the REIN command returns the state of the
+ connection to that it was immediately after the transport connection
+ was opened. That is not changed here. The effect of a HOST command
+ will be lost if a REIN command is performed, a new HOST command must
+ be issued.
+
+ Implementors of user-FTP should be aware that server-FTP
+ implementations which implement the HOST command as a wrapper around
+ older implementations will be unable to correctly implement the REIN
+ command. In such an implementation, REIN will typically return the
+ server-FTP to the state that existed immediately after the HOST
+ command was issued, instead of to the state immediately after the
+ connection was opened.
+
+6.3.2. User-PI usage of HOST
+
+ A user-PI that conforms to this specification, MUST send the HOST
+ command after opening the transport connection, or after any REIN
+ command, before attempting to authenticate the user with the USER
+ command.
+
+ The following state diagram shows a typical sequence of flow of
+ control, where the "B" (begin) state is assumed to occur after the
+ transport connection has opened, or a REIN command has succeeded.
+ Other commands (such as FEAT [6]) which require no authentication may
+ have intervened. This diagram is modeled upon (and largely borrowed
+ from) the similar diagram in section 6 of [3].
+
+ In this diagram, a three digit reply indicates that precise server
+ reply code, a single digit on a reply path indicates any server reply
+ beginning with that digit, other than any three digit replies that
+ might take another path.
+
+
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 20]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+
+ +---+ HOST +---+ 1,3,5
+ | B |---------->| W |-----------------
+ +---+ +---+ |
+ | | |
+ 2,500,502 | | 4,501,503,504 |
+ -------------- ------------- |
+ | | |
+ V 1 | V
+ +---+ USER +---+-------------->+---+
+ | |---------->| W | 2 ----->| E |
+ +---+ +---+------ | --->+---+
+ | | | | | |
+ 3 | | 4,5 | | | |
+ -------------- ----- | | | |
+ | | | | | |
+ | | | | | |
+ | --------- | |
+ | 1| | | | |
+ V | | | | |
+ +---+ PASS +---+ 2 | ------->+---+
+ | |---------->| W |-------------->| S |
+ +---+ +---+ ----------->+---+
+ | | | | | |
+ 3 | |4,5| | | |
+ -------------- -------- | |
+ | | | | | ----
+ | | | | | |
+ | ----------- |
+ | 1,3| | | | |
+ V | 2| | | V
+ +---+ ACCT +---+-- | ------>+---+
+ | |---------->| W | 4,5 --------->| F |
+ +---+ +---+-------------->+---+
+
+6.4. HOST command errors
+
+ The server-PI shall reply with a 500 or 502 reply if the HOST command
+ is unrecognized or unimplemented. A 503 reply may be sent if the
+ HOST command is given after a previous HOST command, or after a user
+ has been authenticated. Alternately, the server may accept the
+ command at such a time, with server defined behavior. A 501 reply
+ should be sent if the hostname given is syntactically invalid, and a
+ 504 reply if a syntactically valid hostname is not a valid virtual
+ host name for the server.
+
+ In all such cases the server-FTP process should act as if no HOST
+ command had been given.
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 21]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ A user-PI receiving a 500 or 502 reply should assume that the
+ server-PI does not implement the HOST command style virtual server.
+ It may then proceed to login as if the HOST command had succeeded,
+ and perhaps, attempt a CWD command to the hostname after
+ authenticating the user.
+
+ A user-PI receiving some other error reply should assume that the
+ virtual HOST is unavailable, and terminate communications.
+
+ A server-PI that receives a USER command, beginning the
+ authentication sequence, without having received a HOST command
+ SHOULD NOT reject the USER command. Clients conforming to earlier
+ FTP specifications do not send HOST commands. In this case the
+ server may act as if some default virtual host had been explicitly
+ selected, or may enter an environment different from that of all
+ supported virtual hosts, perhaps one in which a union of all
+ available accounts exists, and which presents a NVFS which appears to
+ contain sub-directories containing the NVFS for all virtual hosts
+ supported.
+
+6.5. FEAT response for HOST command
+
+ A server-FTP process that supports the host command, and virtual FTP
+ servers, MUST include in the response to the FEAT command [6], a
+ feature line indicating that the HOST command is supported. This
+ line should contain the single word "HOST". This MAY be sent in
+ upper or lower case, or a mixture of both (it is case insensitive)
+ but SHOULD be transmitted in upper case only. That is, the response
+ SHOULD be
+
+ C> Feat
+ S> 211- <any descriptive text>
+ S> ...
+ S> HOST
+ S> ...
+ S> 211 End
+
+ The ellipses indicate place holders where other features may be
+ included, and are not required. The one space indentation of the
+ feature lines is mandatory [6].
+
+
+
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 22]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+7. A Trivial Virtual File Store (TVFS)
+
+ Traditionally, FTP has placed almost no constraints upon the file
+ store (NVFS) provided by a server. This specification does not alter
+ that. However, it has become common for servers to attempt to
+ provide at least file system naming conventions modeled loosely upon
+ those of the UNIX(TM) file system. That is, a tree structured file
+ system, built of directories, each of which can contain other
+ directories, or other kinds of files, or both. Each file and
+ directory has a file name relative to the directory that contains it,
+ except for the directory at the root of the tree, which is contained
+ in no other directory, and hence has no name of its own.
+
+ That which has so far been described is perfectly consistent with the
+ standard FTP NVFS and access mechanisms. The "CWD" command is used
+ to move from one directory to an embedded directory. "CDUP" may be
+ provided to return to the parent directory, and the various file
+ manipulation commands ("RETR", "STOR", the rename commands, etc) are
+ used to manipulate files within the current directory.
+
+ However, it is often useful to be able to reference files other than
+ by changing directories, especially as FTP provides no guaranteed
+ mechanism to return to a previous directory. The Trivial Virtual
+ File Store (TVFS), if implemented, provides that mechanism.
+
+7.1. TVFS File Names
+
+ Where a server implements the TVFS, no elementary filename shall
+ contain the character "/". Where the underlying natural file store
+ permits files, or directories, to contain the "/" character in their
+ names, a server-PI implementing TVFS must encode that character in
+ some manner whenever file or directory names are being returned to
+ the user-PI, and reverse that encoding whenever such names are being
+ accepted from the user-PI.
+
+ The encoding method to be used is not specified here. Where some
+ other character is illegal in file and directory names in the
+ underlying file store, a simple transliteration may be sufficient.
+ Where there is no suitable substitute character a more complex
+ encoding scheme, possibly using an escape character, is likely to be
+ required.
+
+ With the one exception of the unnamed root directory, a TVFS file
+ name may not be empty. That is, all other file names contain at
+ least one character.
+
+ With the sole exception of the "/" character, any valid IS10646
+ character [11] may be used in a TVFS filename. When transmitted,
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 23]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ file name characters are encoded using the UTF-8 encoding [2].
+
+7.2. TVFS Path Names
+
+ A TVFS "Path Name" combines the file or directory name of a target
+ file or directory, with the directory names of zero or more enclosing
+ directories, so as to allow the target file or directory to be
+ referenced other than when the server's "current working directory"
+ is the directory directly containing the target file or directory.
+
+ By definition, every TVFS file or directory name is also a TVFS path
+ name. Such a path name is valid to reference the file from the
+ directory containing the name, that is, when that directory is the
+ server-FTP's current working directory.
+
+ Other TVFS path names are constructed by prefixing a path name by a
+ name of a directory from which the path is valid, and separating the
+ two with the "/" character. Such a path name is valid to reference
+ the file or directory from the directory containing the newly added
+ directory name.
+
+ Where a path name has been extended to the point where the directory
+ added is the unnamed root directory, the path name will begin with
+ the "/" character. Such a path is known as a fully qualified path
+ name. Fully qualified paths may, obviously, not be further extended,
+ as, by definition, no directory contains the root directory. Being
+ unnamed, it cannot be represented in any other directory. A fully
+ qualified path name is valid to reference the named file or directory
+ from any location (that is, regardless of what the current working
+ directory may be) in the virtual file store.
+
+ Any path name which is not a fully qualified path name may be
+ referred to as a "relative path name" and will only correctly
+ reference the intended file when the current working directory of the
+ server-FTP is a directory from which the relative path name is valid.
+
+ As a special case, the path name "/" is defined to be a fully
+ qualified path name referring to the root directory. That is, the
+ root directory does not have a directory (or file) name, but does
+ have a path name. This special path name may be used only as is as a
+ reference to the root directory. It may not be combined with other
+ path names using the rules above, as doing so would lead to a path
+ name containing two consecutive "/" characters, which is an undefined
+ sequence.
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 24]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+7.2.1. Notes
+
+ + It is not required, or expected, that there be only one fully
+ qualified path name that will reference any particular file or
+ directory.
+ + As a caveat, though the TVFS file store is basically tree
+ structured, there is no requirement that any file or directory
+ have only one parent directory.
+ + As defined, no TVFS path name will ever contain two consecutive
+ "/" characters. Such a name is not illegal however, and may be
+ defined by the server for any purpose that suits it. Clients
+ implementing this specification should not assume any semantics
+ at all for such names.
+ + Similarly, other than the special case path that refers to the
+ root directory, no TVFS path name constructed as defined here
+ will ever end with the "/" character. Such names are also not
+ illegal, but are undefined.
+ + While any legal IS10646 character is permitted to occur in a TVFS
+ file or directory name, other than "/", server FTP
+ implementations are not required to support all possible IS10646
+ characters. The subset supported is entirely at the discretion
+ of the server. The case (where it exists) of the characters that
+ make up file, directory, and path names may be significant.
+ Unless determined otherwise by means unspecified here, clients
+ should assume that all such names are comprised of characters
+ whose case is significant. Servers are free to treat case (or
+ any other attribute) of a name as irrelevant, and hence map two
+ names which appear to be distinct onto the same underlying file.
+ + There are no defined "magic" names, like ".", ".." or "C:".
+ Servers may implement such names, with any semantics they choose,
+ but are not required to do so.
+ + TVFS imposes no particular semantics or properties upon files,
+ guarantees no access control schemes, or any of the other common
+ properties of a file store. Only the naming scheme is defined.
+
+7.3. FEAT Response for TVFS
+
+ In response to the FEAT command [6] a server that wishes to indicate
+ support for the TVFS as defined here will include a line that begins
+ with the four characters "TVFS" (in any case, or mixture of cases,
+ upper case is not required). Servers SHOULD send upper case.
+
+ Such a response to the FEAT command MUST NOT be returned unless the
+ server implements TVFS as defined here.
+
+ Later specifications may add to the TVFS definition. Such additions
+ should be notified by means of additional text appended to the TVFS
+ feature line. Such specifications, if any, will define the extra
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 25]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ text.
+
+ Until such a specification is defined, servers should not include
+ anything after "TVFS" in the TVFS feature line. Clients, however,
+ should be prepared to deal with arbitrary text following the four
+ defined characters, and simply ignore it if unrecognized.
+
+ A typical response to the FEAT command issued by a server
+ implementing only this specification would be:
+
+ C> feat
+ S> 211- <any descriptive text>
+ S> ...
+ S> TVFS
+ S> ...
+ S> 211 end
+
+ The ellipses indicate place holders where other features may be
+ included, and are not required. The one space indentation of the
+ feature lines is mandatory [6], and is not counted as one of the
+ first four characters for the purposes of this feature listing.
+
+ The TVFS feature adds no new commands to the FTP command repertoire.
+
+7.4. OPTS for TVFS
+
+ There are no options in this TVFS specification, and hence there is
+ no OPTS command defined.
+
+7.5. TVFS Examples
+
+ Assume a TVFS file store is comprised of a root directory, which
+ contains two directories (A and B) and two non-directory files (X and
+ Y). The A directory contains two directories (C and D) and one other
+ file (Z). The B directory contains just two non-directory files (P
+ and Q) and the C directory also two non-directory files (also named P
+ and Q, by chance). The D directory is empty, that is, contains no
+ files or directories.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 26]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ This structure may depicted graphically as...
+
+ (unnamed root)
+ / | \ \
+ / | \ \
+ A X B Y
+ /|\ / \
+ / | \ / \
+ C D Z P Q
+ / \
+ / \
+ P Q
+
+ Given this structure, the following fully qualified path names exist.
+
+ /
+ /A
+ /B
+ /X
+ /Y
+ /A/C
+ /A/D
+ /A/Z
+ /A/C/P
+ /A/C/Q
+ /B/P
+ /B/Q
+
+ It is clear that none of the paths / /A /B or /A/D refer to the same
+ directory, as the contents of each is different. Nor do any of / /A
+ /A/C or /A/D. However /A/C and /B might be the same directory, there
+ is insufficient information given to tell. Any of the other path
+ names (/X /Y /A/Z /A/C/P /A/C/Q /B/P and /B/Q) may refer to the same
+ underlying files, in almost any combination.
+
+ If the current working directory of the server-FTP is /A then the
+ following path names, in addition to all the fully qualified path
+ names, are valid
+
+ C
+ D
+ Z
+ C/P
+ C/Q
+
+ These all refer to the same files or directories as the corresponding
+ fully qualified path with "/A/" prepended.
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 27]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ That those path names all exist does not imply that the TVFS sever
+ will necessarily grant any kind of access rights to the named paths,
+ or that access to the same file via different path names will
+ necessarily be granted equal rights.
+
+ None of the following relative paths are valid when the current
+ directory is /A
+
+ A
+ B
+ X
+ Y
+ B/P
+ B/Q
+ P
+ Q
+
+ Any of those could be made valid by changing the server-FTP's current
+ working directory to the appropriate directory. Note that the paths
+ "P" and "Q" might refer to different files depending upon which
+ directory is selected to cause those to become valid TVFS relative
+ paths.
+
+8. Listings for Machine Processing (MLST and MLSD)
+
+ The MLST and MLSD commands are intended to standardize the file and
+ directory information returned by the Server-FTP process. These
+ commands differ from the LIST command in that the format of the
+ replies is strictly defined although extensible.
+
+ Two commands are defined, MLST which provides data about exactly the
+ object named on its command line, and no others. MLSD on the other
+ hand will list the contents of a directory if a directory is named,
+ otherwise a 501 reply will be returned. In either case, if no object
+ is named, the current directory is assumed. That will cause MLST to
+ send a one line response, describing the current directory itself,
+ and MLSD to list the contents of the current directory.
+
+ In the following, the term MLSx will be used wherever either MLST or
+ MLSD may be inserted.
+
+ The MLST and MLSD commands also extend the FTP protocol as presented
+ in RFC 959 [3] and RFC 1123 [9] to allow that transmission of 8-bit
+ data over the control connection. Note this is not specifying
+ character sets which are 8-bit, but specifying that FTP
+ implementations are to specifically allow the transmission and
+ reception of 8-bit bytes, with all bits significant, over the control
+ connection. That is, all 256 possible octet values are permitted.
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 28]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ The MLSx command allows both UTF-8/Unicode and "raw" forms as
+ arguments, and in responses both to the MLST and MLSD commands, and
+ all other FTP commands which take pathnames as arguments.
+
+8.1. Format of MLSx Requests
+
+ The MLST and MLSD commands each allow a single optional argument.
+ This argument may be either a directory name or, for MLST only, a
+ filename. For these purposes, a "filename" is the name of any entity
+ in the server NVFS which is not a directory. Where TVFS is
+ supported, any TVFS relative path name valid in the current working
+ directory, or any TVFS fully qualified path name, may be given. If a
+ directory name is given then MLSD must return a listing of the
+ contents of the named directory, otherwise it issues a 501 reply, and
+ does not open a data connection. In all cases for MLST, a single set
+ of fact lines (usually a single fact line) containing the information
+ about the named file or directory shall be returned over the control
+ connection, without opening a data connection.
+
+ If no argument is given then MLSD must return a listing of the
+ contents of the current working directory, and MLST must return a
+ listing giving information about the current working directory
+ itself. For these purposes, the contents of a directory are whatever
+ filenames (not pathnames) the server-PI will allow to be referenced
+ when the current working directory is the directory named, and which
+ the server-PI desires to reveal to the user-PI.
+
+ No title, header, or summary, lines, or any other formatting, other
+ than as is specified below, is ever returned in the output of an MLST
+ or MLSD command.
+
+ If the Client-FTP sends an invalid argument, the Server-FTP MUST
+ reply with an error code of 501.
+
+ The syntax for the MLSx command is:
+
+ mlst = "MLst" [ SP pathname ] CRLF
+ mlsd = "MLsD" [ SP pathname ] CRLF
+
+8.2. Format of MLSx Response
+
+ The format of a response to an MLSx command is as follows:
+
+ mlst-response = control-response / error-response
+ mlsd-response = ( initial-response final-response ) /
+ error-response
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 29]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ control-response = "250-" [ response-message ] CRLF
+ 1*( SP entry CRLF )
+ "250" [ SP response-message ] CRLF
+
+ initial-response = "150" [ SP response-message ] CRLF
+ final-response = "226" SP response-message CRLF
+
+ response-message = *TCHAR
+
+ data-response = *( entry CRLF )
+
+ entry = [ facts ] SP pathname
+ facts = 1*( fact ";" )
+ fact = factname "=" value
+ factname = "Size" / "Modify" / "Create" /
+ "Type" / "Unique" / "Perm" /
+ "Lang" / "Media-Type" / "CharSet" /
+ os-depend-fact / local-fact
+ os-depend-fact = <IANA assigned OS name> "." token
+ local-fact = "X." token
+ value = *RCHAR
+
+ Upon receipt of a MLSx command, the server will verify the parameter,
+ and if invalid return an error-response. For this purpose, the
+ parameter should be considered to be invalid if the client issuing
+ the command does not have permission to perform the request
+ operation.
+
+ If valid, then for an MLST command, the server-PI will send the first
+ (leading) line of the control response, the entry for the pathname
+ given, or the current directory if no pathname was provided, and the
+ terminating line. Normally exactly one entry would be returned, more
+ entries are permitted only when required to represent a file that is
+ to have multiple "Type" facts returned.
+
+ Note that for MLST the fact set is preceded by a space. That is
+ provided to guarantee that the fact set cannot be accidentally
+ interpreted as the terminating line of the control response, but is
+ required even when that would not be possible. Exactly one space
+ exists between the set of facts and the pathname. Where no facts are
+ present, there will be exactly two leading spaces before the
+ pathname. No spaces are permitted in the facts, any other spaces in
+ the response are to be treated as being a part of the pathname.
+
+ If the command was an MLSD command, the server will open a data
+ connection as indicated in section 3.2 of RFC959 [3]. If that fails,
+ the server will return an error-response. If all is OK, the server
+ will return the initial-response, send the appropriate data-response
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 30]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ over the new data connection, close that connection, and then send
+ the final-response over the control connection. The grammar above
+ defines the format for the data-response, which defines the format of
+ the data returned over the data connection established.
+
+ The data connection opened for a MLSD response shall be a connection
+ as if the "TYPE L 8", "MODE S", and "STRU F" commands had been given,
+ whatever FTP transfer type, mode and structure had actually been set,
+ and without causing those settings to be altered for future commands.
+ That is, this transfer type shall be set for the duration of the data
+ connection established for this command only. While the content of
+ the data sent can be viewed as a series of lines, implementations
+ should note that there is no maximum line length defined.
+ Implementations should be prepared to deal with arbitrarily long
+ lines.
+
+ The facts part of the specification would contain a series of "file
+ facts" about the file or directory named on the same line. Typical
+ information to be presented would include file size, last
+ modification time, creation time, a unique identifier, and a
+ file/directory flag.
+
+ The complete format for a successful reply to the MLSD command would
+ be:
+
+ facts SP pathname CRLF
+ facts SP pathname CRLF
+ facts SP pathname CRLF
+ ...
+
+ Note that the format is intended for machine processing, not human
+ viewing, and as such the format is very rigid. Implementations MUST
+ NOT vary the format by, for example, inserting extra spaces for
+ readability, replacing spaces by tabs, including header or title
+ lines, or inserting blank lines, or in any other way alter this
+ format. Exactly one space is always required after the set of facts
+ (which may be empty). More spaces may be present on a line if, and
+ only if, the file name presented contains significant spaces. The
+ set of facts must not contain any spaces anywhere inside it. Facts
+ should be provided in each output line only if they both provide
+ relevant information about the file named on the same line, and they
+ are in the set requested by the user-PI. There is no requirement
+ that the same set of facts be provided for each file, or that the
+ facts presented occur in the same order for each file.
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 31]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+8.3. Filename encoding
+
+ An FTP implementation supporting the MLSx commands must be 8-bit
+ clean. This is necessary in order to transmit UTF-8 encoded
+ filenames. This specification recommends the use of UTF-8 encoded
+ filenames. FTP implementations SHOULD use UTF-8 whenever possible to
+ encourage the maximum interoperability.
+
+ Filenames are not restricted to UTF-8, however treatment of arbitrary
+ character encodings is not specified by this standard. Applications
+ are encouraged to treat non-UTF-8 encodings of filenames as octet
+ sequences.
+
+ Note that this encoding is unrelated to that of the contents of the
+ file, even if the file contains character data.
+
+ Further information about filename encoding for FTP may be found in
+ "Internationalization of the File Transfer Protocol" [7].
+
+8.3.1. Notes about the Filename
+
+ The filename returned in the MLST response should be the same name as
+ was specified in the MLST command, or, where TVFS is supported, a
+ fully qualified TVFS path naming the same file. Where no argument
+ was given to the MLST command, the server-PI may either include an
+ empty filename in the response, or it may supply a name that refers
+ to the current directory, if such a name is available. Where TVFS is
+ supported, a fully qualified path name of the current directory
+ SHOULD be returned.
+
+ Filenames returned in the output from an MLSD command SHOULD be
+ unqualified names within the directory named, or the current
+ directory if no argument was given. That is, the directory named in
+ the MLSD command SHOULD NOT appear as a component of the filenames
+ returned.
+
+ If the server-FTP process is able, and the "type" fact is being
+ returned, it MAY return in the MLSD response, an entry whose type is
+ "cdir", which names the directory from which the contents of the
+ listing were obtained. Where TVFS is supported, the name MAY be the
+ fully qualified path name of the directory, or MAY be any other path
+ name which is valid to refer to that directory from the current
+ working directory of the server-FTP. Where more than one name
+ exists, multiple of these entries may be returned. In a sense, the
+ "cdir" entry can be viewed as a heading for the MLSD output.
+ However, it is not required to be the first entry returned, and may
+ occur anywhere within the listing.
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 32]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ When TVFS is supported, a user-PI can refer to any file or directory
+ in the listing by combining a type "cdir" name, with the appropriate
+ name from the directory listing using the procedure defined in
+ section 7.2.
+
+ Alternatively, whether TVFS is supported or not, the user-PI can
+ issue a CWD command ([3]) giving a name of type "cdir" from the
+ listing returned, and from that point reference the files returned in
+ the MLSD response from which the cdir was obtained by using the
+ filename components of the listing.
+
+8.4. Format of Facts
+
+ The "facts" for a file in a reply to a MLSx command consist of
+ information about that file. The facts are a series of keyword=value
+ pairs each followed by semi-colon (";") characters. An individual
+ fact may not contain a semi-colon in its name or value. The complete
+ series of facts may not contain the space character. See the
+ definition or "RCHAR" in section 2.1 for a list of the characters
+ that can occur in a fact value. Not all are applicable to all facts.
+
+ A sample of a typical series of facts would be: (spread over two
+ lines for presentation here only)
+
+ size=4161;lang=en-US;modify=19970214165800;create=19961001124534;
+ type=file;x.myfact=foo,bar;
+
+8.5. Standard Facts
+
+ This document defines a standard set of facts as follows:
+
+ size -- Size in octets
+ modify -- Last modification time
+ create -- Creation time
+ type -- Entry type
+ unique -- Unique id of file/directory
+ perm -- File permissions, whether read, write, execute is
+ allowed for the login id.
+ lang -- Language of the filename per IANA[12] registry.
+ media-type -- MIME media-type of file contents per IANA registry.
+ charset -- Character set per IANA registry (if not UTF-8)
+
+ Fact names are case-insensitive. Size, size, SIZE, and SiZe are the
+ same fact.
+
+ Further operating system specific keywords could be specified by
+ using the IANA operating system name as a prefix (examples only):
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 33]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ OS/2.ea -- OS/2 extended attributes
+ MACOS.rf -- MacIntosh resource forks
+ UNIX.mode -- Unix file modes (permissions)
+
+ Implementations may define keywords for experimental, or private use.
+ All such keywords MUST begin with the two character sequence "x.".
+ As type names are case independent, "x." and "X." are equivalent.
+ For example:
+
+ x.ver -- Version information
+ x.desc -- File description
+ x.type -- File type
+
+8.5.1. The type Fact
+
+ The type fact needs a special description. Part of the problem with
+ current practices is deciding when a file is a directory. If it is a
+ directory, is it the current directory, a regular directory, or a
+ parent directory? The MLST specification makes this unambiguous
+ using the type fact. The type fact given specifies information about
+ the object listed on the same line of the MLST response.
+
+ Five values are possible for the type fact:
+
+ file -- a file entry
+ cdir -- the listed directory
+ pdir -- a parent directory
+ dir -- a directory or sub-directory
+ OS.name=type -- an OS or file system dependent file type
+
+ The syntax is defined to be:
+
+ type-fact = type-label "=" type-val
+ type-label = "Type"
+ type-val = "File" / "cdir" / "pdir" / "dir" /
+ os-type
+
+8.5.1.1. type=file
+
+ The presence of the type=file fact indicates the listed entry is a
+ file containing non-system data. That is, it may be transferred from
+ one system to another of quite different characteristics, and perhaps
+ still be meaningful.
+
+8.5.1.2. type=cdir
+
+ The type=cdir fact indicates the listed entry contains a pathname of
+ the directory whose contents are listed. An entry of this type will
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 34]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ only be returned as a part of the result of an MLSD command when the
+ type fact is included, and provides a name for the listed directory,
+ and facts about that directory. In a sense, it can be viewed as
+ representing the title of the listing, in a machine friendly format.
+ It may appear at any point of the listing, it is not restricted to
+ appearing at the start, though frequently may do so, and may occur
+ multiple times. It MUST NOT be included if the type fact is not
+ included, or there would be no way for the user-PI to distinguish the
+ name of the directory from an entry in the directory.
+
+ Where TVFS is supported by the server-FTP, this name may be used to
+ construct path names with which to refer to the files and directories
+ returned in the same MLSD output (see section 7.2). These path names
+ are only expected to work when the server-PI's position in the NVFS
+ file tree is the same as its position when the MLSD command was
+ issued, unless a fully qualified path name results.
+
+ Where TVFS is not supported, the only defined semantics associated
+ with a "type=cdir" entry are that, provided the current working
+ directory of the server-PI has not been changed, a pathname of type
+ "cdir" may be used as an argument to a CWD command, which will cause
+ the current directory of the server-PI to change so that the
+ directory which was listed in its current working directory.
+
+8.5.1.3. type=dir
+
+ If present, the type=dir entry gives the name of a directory. Such
+ an entry typically cannot be transferred from one system to another
+ using RETR, etc, but should (permissions permitting) be able to be
+ the object of an MLSD command.
+
+8.5.1.4. type=pdir
+
+ If present, which will occur only in the response to a MLSD command
+ when the type fact is included, the type=pdir entry represents a
+ pathname of the parent directory of the listed directory. As well as
+ having the properties of a type=dir, a CWD command that uses the
+ pathname from this entry should change the user to a parent directory
+ of the listed directory. If the listed directory is the current
+ directory, a CDUP command may also have the effect of changing to the
+ named directory. User-FTP processes should note not all responses
+ will include this information, and that some systems may provide
+ multiple type=pdir responses.
+
+ Where TVFS is supported, a "type=pdir" name may be a relative path
+ name, or a fully qualified path name. A relative path name will be
+ relative to the directory being listed, not to the current directory
+ of the server-PI at the time.
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 35]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ For the purposes of this type value, a "parent directory" is any
+ directory in which there is an entry of type=dir which refers to the
+ directory in which the type=pdir entity was found. Thus it is not
+ required that all entities with type=pdir refer to the same
+ directory. The "unique" fact (if supported) can be used to determine
+ whether there is a relationship between the type=pdir entries or not.
+
+8.5.1.5. System defined types
+
+ Files types that are specific to a specific operating system, or file
+ system, can be encoded using the "OS." type names. The format is:
+
+ os-type = "OS." os-name "=" os-type
+ os-name = <an IANA registered operating system name>
+ os-type = token
+
+ The "os-name" indicates the specific system type which supports the
+ particular localtype. OS specific types are registered by the IANA
+ using the procedures specified in section 11. The "os-type" provides
+ the system dependent information as to the type of the file listed.
+ The os-name and os-type strings in an os-type are case independent.
+ "OS.unix=block" and "OS.Unix=BLOCK" represent the same type (or
+ would, if such a type were registered.)
+
+ Note: Where the underlying system supports a file type which is
+ essentially an indirect pointer to another file, the NVFS
+ representation of that type should normally be to represent the file
+ which the reference indicates. That is, the underlying basic file
+ will appear more than once in the NVFS, each time with the "unique"
+ fact (see immediately following section) containing the same value,
+ indicating that the same file is represented by all such names.
+ User-PIs transferring the file need then transfer it only once, and
+ then insert their own form of indirect reference to construct
+ alternate names where desired, or perhaps even copy the local file if
+ that is the only way to provide two names with the same content. A
+ file which would be a reference to another file, if only the other
+ file actually existed, may be represented in any OS dependent manner
+ appropriate, or not represented at all.
+
+8.5.1.6. Multiple types
+
+ Where a file is such that it may validly, and sensibly, treated by
+ the server-PI as being of more than one of the above types, then
+ multiple entries should be returned, each with its own "Type" fact of
+ the appropriate type, and each containing the same pathname. This
+ may occur, for example, with a structured file, which may contain
+ sub-files, and where the server-PI permits the structured file to be
+ treated as a unit, or treated as a directory allowing the sub-files
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 36]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ within it to be referenced.
+
+8.5.2. The unique Fact
+
+ The unique fact is used to present a unique identifier for a file or
+ directory in the NVFS accessed via a server-FTP process. The value
+ of this fact should be the same for any number of pathnames that
+ refer to the same underlying file. The fact should have different
+ values for names which reference distinct files. The mapping between
+ files, and unique fact tokens should be maintained, and remain
+ consistent, for at least the lifetime of the control connection from
+ user-PI to server-PI.
+
+ unique-fact = "Unique" "=" token
+
+ This fact would be expected to be used by Server-FTPs whose host
+ system allows things such as symbolic links so that the same file may
+ be represented in more than one directory on the server. The only
+ conclusion that should be drawn is that if two different names each
+ have the same value for the unique fact, they refer to the same
+ underlying object. The value of the unique fact (the token) should
+ be considered an opaque string for comparison purposes, and is a case
+ dependent value. The tokens "A" and "a" do not represent the same
+ underlying object.
+
+8.5.3. The modify Fact
+
+ The modify fact is used to determine the last time the content of the
+ file (or directory) indicated was modified. Any change of substance
+ to the file should cause this value to alter. That is, if a change
+ is made to a file such that the results of a RETR command would
+ differ, then the value of the modify fact should alter. User-PIs
+ should not assume that a different modify fact value indicates that
+ the file contents are necessarily different than when last retrieved.
+ Some systems may alter the value of the modify fact for other
+ reasons, though this is discouraged wherever possible. Also a file
+ may alter, and then be returned to its previous content, which would
+ often be indicated as two incremental alterations to the value of the
+ modify fact.
+
+ For directories, this value should alter whenever a change occurs to
+ the directory such that different filenames would (or might) be
+ included in MLSD output of that directory.
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 37]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ modify-fact = "Modify" "=" time-val
+
+8.5.4. The create Fact
+
+ The create fact indicates when a file, or directory, was first
+ created. Exactly what "creation" is for this purpose is not
+ specified here, and may vary from server to server. About all that
+ can be said about the value returned is that it can never indicate a
+ later time than the modify fact.
+
+ create-fact = "Create" "=" time-val
+
+ Implementation Note: Implementors of this fact on UNIX(TM) systems
+ should note that the unix "stat" "st_ctime" field does not give
+ creation time, and that unix file systems do not record creation
+ time at all. Unix (and POSIX) implementations will normally not
+ include this fact.
+
+8.5.5. The perm Fact
+
+ The perm fact is used to indicate access rights the current FTP user
+ has over the object listed. Its value is always an unordered
+ sequence of alphabetic characters.
+
+ perm-fact = "Perm" "=" *pvals
+ pvals = "a" / "c" / "d" / "e" / "f" /
+ "l" / "m" / "p" / "r" / "w"
+
+ There are ten permission indicators currently defined. Many are
+ meaningful only when used with a particular type of object. The
+ indicators are case independent, "d" and "D" are the same indicator.
+
+ The "a" permission applies to objects of type=file, and indicates
+ that the APPE (append) command may be applied to the file named.
+
+ The "c" permission applies to objects of type=dir (and type=pdir,
+ type=cdir). It indicates that files may be created in the directory
+ named. That is, that a STOU command is likely to succeed, and that
+ STOR and APPE commands might succeed if the file named did not
+ previously exist, but is to be created in the directory object that
+ has the "c" permission. It also indicates that the RNTO command is
+ likely to succeed for names in the directory.
+
+ The "d" permission applies to all types. It indicates that the
+ object named may be deleted, that is, that the RMD command may be
+ applied to it if it is a directory, and otherwise that the DELE
+ command may be applied to it.
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 38]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ The "e" permission applies to the directory types. When set on an
+ object of type=dir, type=cdir, or type=pdir it indicates that a CWD
+ command naming the object should succeed, and the user should be able
+ to enter the directory named. For type=pdir it also indicates that
+ the CDUP command may succeed (if this particular pathname is the one
+ to which a CDUP would apply.)
+
+ The "f" permission for objects indicates that the object named may be
+ renamed - that is, may be the object of an RNFR command.
+
+ The "l" permission applies to the directory file types, and indicates
+ that the listing commands, LIST, NLST, and MLSD may be applied to the
+ directory in question.
+
+ The "m" permission applies to directory types, and indicates that the
+ MKD command may be used to create a new directory within the
+ directory under consideration.
+
+ The "p" permission applies to directory types, and indicates that
+ objects in the directory may be deleted, or (stretching naming a
+ little) that the directory may be purged. Note: it does not indicate
+ that the RMD command may be used to remove the directory named
+ itself, the "d" permission indicator indicates that.
+
+ The "r" permission applies to type=file objects, and for some
+ systems, perhaps to other types of objects, and indicates that the
+ RETR command may be applied to that object.
+
+ The "w" permission applies to type=file objects, and for some
+ systems, perhaps to other types of objects, and indicates that the
+ STOR command may be applied to the object named.
+
+ Note: That a permission indicator is set can never imply that the
+ appropriate command is guaranteed to work - just that it might.
+ Other system specific limitations, such as limitations on
+ available space for storing files, may cause an operation to
+ fail, where the permission flags may have indicated that it was
+ likely to succeed. The permissions are a guide only.
+
+ Implementation note: The permissions are described here as they apply
+ to FTP commands. They may not map easily into particular
+ permissions available on the server's operating system. Servers
+ are expected to synthesize these permission bits from the
+ permission information available from operating system. For
+ example, to correctly determine whether the "D" permission bit
+ should be set on a directory for a server running on the
+ UNIX(TM) operating system, the server should check that the
+ directory named is empty, and that the user has write permission
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 39]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ on both the directory under consideration, and its parent
+ directory.
+
+ Some systems may have more specific permissions than those
+ listed here, such systems should map those to the flags defined
+ as best they are able. Other systems may have only more broad
+ access controls. They will generally have just a few possible
+ permutations of permission flags, however they should attempt to
+ correctly represent what is permitted.
+
+8.5.6. The lang Fact
+
+ The lang fact describes the natural language of the filename for use
+ in display purposes. Values used here should be taken from the
+ language registry of the IANA. See [13] for the syntax, and
+ procedures, related to language tags.
+
+ lang-fact = "Lang" "=" token
+
+ Server-FTP implementations MUST NOT guess language values. Language
+ values must be determined in an unambiguous way such as file system
+ tagging of language or by user configuration. Note that the lang
+ fact provides no information at all about the content of a file, only
+ about the encoding of its name.
+
+8.5.7. The size Fact
+
+ The size fact applies to non-directory file types and should always
+ reflect the approximate size of the file. This should be as accurate
+ as the server can make it, without going to extraordinary lengths,
+ such as reading the entire file. The size is expressed in units of
+ octets of data in the file.
+
+ Given limitations in some systems, Client-FTP implementations must
+ understand this size may not be precise and may change between the
+ time of a MLST and RETR operation.
+
+ Clients that need highly accurate size information for some
+ particular reason should use the SIZE command as defined in section
+ 4. The most common need for this accuracy is likely to be in
+ conjunction with the REST command described in section 5. The size
+ fact, on the other hand, should be used for purposes such as
+ indicating to a human user the approximate size of the file to be
+ transferred, and perhaps to give an idea of expected transfer
+ completion time.
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 40]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ size-fact = "Size" "=" 1*DIGIT
+
+8.5.8. The media-type Fact
+
+ The media-type fact represents the IANA media type of the file named,
+ and applies only to non-directory types. The list of values used
+ must follow the guidelines set by the IANA registry.
+
+ media-type = "Media-Type" "=" <per IANA guidelines>
+
+ Server-FTP implementations MUST NOT guess media type values. Media
+ type values must be determined in an unambiguous way such as file
+ system tagging of media-type or by user configuration. This fact
+ gives information about the content of the file named. Both the
+ primary media type, and any appropriate subtype should be given,
+ separated by a slash "/" as is traditional.
+
+8.5.9. The charset Fact
+
+ The charset fact provides the IANA character set name, or alias, for
+ the encoded pathnames in a MLSx response. The default character set
+ is UTF-8 unless specified otherwise. FTP implementations SHOULD use
+ UTF-8 if possible to encourage maximum interoperability. The value
+ of this fact applies to the pathname only, and provides no
+ information about the contents of the file.
+
+ charset-type = "Charset" "=" token
+
+8.5.10. Required facts
+
+ Servers are not required to support any particular set of the
+ available facts. However, servers SHOULD, if conceivably possible,
+ support at least the type, perm, size, unique, and modify facts.
+
+8.6. System Dependent and Local Facts
+
+ By using an system dependent fact, or a local fact, a server-PI may
+ communicate to the user-PI information about the file named which is
+ peculiar to the underlying file system.
+
+8.6.1. System Dependent Facts
+
+ System dependent fact names are labeled by prefixing a label
+ identifying the specific information returned by the name of the
+ appropriate operating system from the IANA maintained list of
+ operating system names.
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 41]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ The value of an OS dependent fact may be whatever is appropriate to
+ convey the information available. It must be encoded as a "token" as
+ defined in section 2.1 however.
+
+ In order to allow reliable interoperation between users of system
+ dependent facts, the IANA will maintain a registry of system
+ dependent fact names, their syntax, and the interpretation to be
+ given to their values. Registrations of system dependent facts are
+ to be accomplished according to the procedures of section 11.
+
+8.6.2. Local Facts
+
+ Implementations may also make available other facts of their own
+ choosing. As the method of interpretation of such information will
+ generally not be widely understood, server-PIs should be aware that
+ clients will typically ignore any local facts provided. As there is
+ no registration of locally defined facts, it is entirely possible
+ that different servers will use the same local fact name to provide
+ vastly different information. Hence user-PIs should be hesitant
+ about making any use of any information in a locally defined fact
+ without some other specific assurance that the particular fact is one
+ that they do comprehend.
+
+ Local fact names all begin with the sequence "X.". The rest of the
+ name is a "token" (see section 2.1). The value of a local fact can
+ be anything at all, provided it can be encoded as a "token".
+
+8.7. MLSx Examples
+
+ The following examples are all taken from dialogues between existing
+ FTP clients and servers. Because of this, not all possible
+ variations of possible response formats are shown in the examples.
+ This should not be taken as limiting the options of other server
+ implementors. Where the examples show OS dependent information, that
+ is to be treated as being purely for the purposes of demonstration of
+ some possible OS specific information that could be defined. As at
+ the time of the writing of this document, no OS specific facts or
+ file types have been defined, the examples shown here should not be
+ treated as in any way to be preferred over other possible similar
+ definitions. Consult the IANA registries to determine what types and
+ facts have been defined.
+
+ In the examples shown, only relevant commands and responses have been
+ included. This is not to imply that other commands (including
+ authentication, directory modification, PORT or PASV commands, or
+ similar) would not be present in an actual connection, or were not,
+ in fact, actually used in the examples before editing. Note also
+ that the formats shown are those that are transmitted between client
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 42]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ and server, not formats which would normally ever be reported to the
+ user of the client.
+
+ In the examples, lines that begin "C> " were sent over the control
+ connection from the client to the server, lines that begin "S> " were
+ sent over the control connection from the server to the client, and
+ lines that begin "D> " were sent from the server to the client over a
+ data connection created just to send those lines and closed
+ immediately after. No examples here show data transferred over a
+ data connection from the client to the server. In all cases, the
+ prefixes shown above, including the one space, have been added for
+ the purposes of this document, and are not a part of the data
+ exchanged between client and server.
+
+8.7.1. Simple MLST
+
+ C> PWD
+ S> 257 "/tmp" is current directory.
+ C> MLst cap60.pl198.tar.gz
+ S> 250- Listing cap60.pl198.tar.gz
+ S> Type=file;Size=1024990;Perm=r; /tmp/cap60.pl198.tar.gz
+ S> 250 End
+
+ The client first asked to be told the current directory of the
+ server. This was purely for the purposes of clarity of this example.
+ The client then requested facts about a specific file. The server
+ returned the "250-" first control-response line, followed by a single
+ line of facts about the file, followed by the terminating "250 "
+ line. The text on the control-response line and the terminating line
+ can be anything the server decides to send. Notice that the fact
+ line is indented by a single space. Notice also that there are no
+ spaces in the set of facts returned, until the single space before
+ the filename. The filename returned on the fact line is a fully
+ qualified pathname of the file listed. The facts returned show that
+ the line refers to a file, that file contains approximately 1024990
+ bytes, though more or less than that may be transferred if the file
+ is retrieved, and a different number may be required to store the
+ file at the client's file store, and the connected user has
+ permission to retrieve the file but not to do anything else
+ particularly interesting.
+
+8.7.2. MLST of a directory
+
+ C> PWD
+ S> 257 "/" is current directory.
+ C> MLst tmp
+ S> 250- Listing tmp
+ S> Type=dir;Modify=19981107085215;Perm=el; /tmp
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 43]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ S> 250 End
+
+ Again the PWD is just for the purposes of demonstration for the
+ example. The MLST fact line this time shows that the file listed is
+ a directory, that it was last modified at 08:52:15 on the 7th of
+ November, 1998 UTC, and that the user has permission to enter the
+ directory, and to list its contents, but not to modify it in any way.
+ Again, the fully qualified path name of the directory listed is
+ given.
+
+8.7.3. MLSD of a directory
+
+ C> MLSD tmp
+ S> 150 BINARY connection open for MLSD tmp
+ D> Type=cdir;Modify=19981107085215;Perm=el; tmp
+ D> Type=cdir;Modify=19981107085215;Perm=el; /tmp
+ D> Type=pdir;Modify=19990112030508;Perm=el; ..
+ D> Type=file;Size=25730;Modify=19940728095854;Perm=; capmux.tar.z
+ D> Type=file;Size=1830;Modify=19940916055648;Perm=r; hatch.c
+ D> Type=file;Size=25624;Modify=19951003165342;Perm=r; MacIP-02.txt
+ D> Type=file;Size=2154;Modify=19950501105033;Perm=r; uar.netbsd.patch
+ D> Type=file;Size=54757;Modify=19951105101754;Perm=r; iptnnladev.1.0.sit.hqx
+ D> Type=file;Size=226546;Modify=19970515023901;Perm=r; melbcs.tif
+ D> Type=file;Size=12927;Modify=19961025135602;Perm=r; tardis.1.6.sit.hqx
+ D> Type=file;Size=17867;Modify=19961025135602;Perm=r; timelord.1.4.sit.hqx
+ D> Type=file;Size=224907;Modify=19980615100045;Perm=r; uar.1.2.3.sit.hqx
+ D> Type=file;Size=1024990;Modify=19980130010322;Perm=r; cap60.pl198.tar.gz
+ S> 226 MLSD completed
+
+ In this example notice that there is no leading space on the fact
+ lines returned over the data connection. Also notice that two lines
+ of "type=cdir" have been given. These show two alternate names for
+ the directory listed, one a fully qualified pathname, and the other a
+ local name relative to the servers current directory when the MLSD
+ was performed. Note that all other filenames in the output are
+ relative to the directory listed, though the server could, if it
+ chose, give a fully qualified path name for the "type=pdir" line.
+ This server has chosen not to. The other files listed present a
+ fairly boring set of files that are present in the listed directory.
+ Note that there is no particular order in which they are listed.
+ They are not sorted by filename, by size, or by modify time. Note
+ also that the "perm" fact has an empty value for the file
+ "capmux.tar.z" indicating that the connected user has no permissions
+ at all for that file. This server has chosen to present the "cdir"
+ and "pdir" lines before the lines showing the content of the
+ directory, it is not required to do so. The "size" fact does not
+ provide any meaningful information for a directory, so is not
+ included in the fact lines for the directory types shown.
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 44]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+8.7.4. A more complex example
+
+ C> MLst test
+ S> 250- Listing test
+ S> Type=dir;Perm=el;Unique=keVO1+ZF4 test
+ S> 250 End
+ C> MLSD test
+ S> 150 BINARY connection open for MLSD test
+ D> Type=cdir;Perm=el;Unique=keVO1+ZF4; test
+ D> Type=pdir;Perm=e;Unique=keVO1+d?3; ..
+ D> Type=OS.unix=slink:/foobar;Perm=;Unique=keVO1+4G4; foobar
+ D> Type=OS.unix=chr-13/29;Perm=;Unique=keVO1+5G4; device
+ D> Type=OS.unix=blk-11/108;Perm=;Unique=keVO1+6G4; block
+ D> Type=file;Perm=awr;Unique=keVO1+8G4; writable
+ D> Type=dir;Perm=cpmel;Unique=keVO1+7G4; promiscuous
+ D> Type=dir;Perm=;Unique=keVO1+1t2; no-exec
+ D> Type=file;Perm=r;Unique=keVO1+EG4; two words
+ D> Type=file;Perm=r;Unique=keVO1+IH4; leading space
+ D> Type=file;Perm=r;Unique=keVO1+1G4; file1
+ D> Type=dir;Perm=cpmel;Unique=keVO1+7G4; incoming
+ D> Type=file;Perm=r;Unique=keVO1+1G4; file2
+ D> Type=file;Perm=r;Unique=keVO1+1G4; file3
+ D> Type=file;Perm=r;Unique=keVO1+1G4; file4
+ S> 226 MLSD completed
+ C> MLSD test/incoming
+ S> 150 BINARY connection open for MLSD test/incoming
+ D> Type=cdir;Perm=cpmel;Unique=keVO1+7G4; test/incoming
+ D> Type=pdir;Perm=el;Unique=keVO1+ZF4; ..
+ D> Type=file;Perm=awdrf;Unique=keVO1+EH4; bar
+ D> Type=file;Perm=awdrf;Unique=keVO1+LH4;
+ D> Type=file;Perm=rf;Unique=keVO1+1G4; file5
+ D> Type=file;Perm=rf;Unique=keVO1+1G4; file6
+ D> Type=dir;Perm=cpmdelf;Unique=keVO1+!s2; empty
+ S> 226 MLSD completed
+
+ For the purposes of this example the fact set requested has been
+ modified to delete the "size" and "modify" facts, and add the
+ "unique" fact. First, facts about a filename have been obtained via
+ MLST. Note that no fully qualified path name was given this time.
+ That was because the server was unable to determine that information.
+ Then having determined that the filename represents a directory, that
+ directory has been listed. That listing also shows no fully
+ qualified path name, for the same reason, thus has but a single
+ "type=cdir" line. This directory (which was created especially for
+ the purpose) contains several interesting files. There are some with
+ OS dependent file types, several sub-directories, and several
+ ordinary files.
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 45]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ Not much can be said here about the OS dependent file types, as none
+ of the information shown there should be treated as any more than
+ possibilities. It can be seen that the OS type of the server is
+ "unix" though, which is one of the OS types in the IANA registry of
+ Operating System names.
+
+ Of the three directories listed, "no-exec" has no permission granted
+ to this user to access at all. From the "Unique" fact values, it can
+ be determined that "promiscuous" and "incoming" in fact represent the
+ same directory. Its permissions show that the connected user has
+ permission to do essentially anything other than to delete the
+ directory. That directory was later listed. It happens that the
+ directory can not be deleted because it is not empty.
+
+ Of the normal files listed, two contain spaces in their names. The
+ file called " leading space" actually contains two spaces in its
+ name, one before the "l" and one between the "g" and the "s". The
+ two spaces that separate the facts from the visible part of the path
+ name make that clear. The file "writable" has the "a" and "w"
+ permission bits set, and consequently the connected user should be
+ able to STOR or APPE to that file.
+
+ The other four file names, "file1", "file2", "file3", and "file4" all
+ represent the same underlying file, as can be seen from the values of
+ the "unique" facts of each. It happens that "file1" and "file2" are
+ Unix "hard" links, and that "file3" and "file4" are "soft" or
+ "symbolic" links to the first two. None of that information is
+ available via standard MLST facts, it is sufficient for the purposes
+ of FTP to note that all represent the same file, and that the same
+ data would be fetched no matter which of them was retrieved, and that
+ all would be simultaneously modified were data stored in any.
+
+ Finally, the sub-directory "incoming" is listed. Since "promiscuous"
+ is the same directory there would be no point listing it as well. In
+ that directory, the files "file5" and "file6" represent still more
+ names for the "file1" file we have seen before. Notice the entry
+ between that for "bar" and "file5". Though it is not possible to
+ easily represent it in this document, that shows a file with a name
+ comprising exactly three spaces (" "). A client will have no
+ difficulty determining that name from the output presented to it
+ however. The directory "empty" is, as its name implies, empty,
+ though that is not shown here. It can, however, be deleted, as can
+ file "bar" and the file whose name is three spaces. All the files
+ that reside in this directory can be renamed. This is a consequence
+ of the UNIX semantics of the directory that contains them being
+ modifiable.
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 46]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+8.7.5. More accurate time information
+
+ C> MLst file1
+ S> 250- Listing file1
+ S> Type=file;Modify=19990929003355.237; file1
+ S> 250 End
+
+ In this example, the server-FTP is indicating that "file1" was last
+ modified 237 milliseconds after 00:33:55 UTC on the 29th of
+ September, 1999.
+
+8.7.6. A different server
+
+ C> MLST
+ S> 250-Begin
+ S> type=dir;unique=AQkAAAAAAAABCAAA; /
+ S> 250 End.
+ C> MLSD .
+ S> 150 Opening ASCII mode data connection for MLS.
+ D> type=cdir;unique=AQkAAAAAAAABCAAA; /
+ D> type=dir;unique=AQkAAAAAAAABEAAA; bin
+ D> type=dir;unique=AQkAAAAAAAABGAAA; etc
+ D> type=dir;unique=AQkAAAAAAAAB8AwA; halflife
+ D> type=dir;unique=AQkAAAAAAAABoAAA; incoming
+ D> type=dir;unique=AQkAAAAAAAABIAAA; lib
+ D> type=dir;unique=AQkAAAAAAAABWAEA; linux
+ D> type=dir;unique=AQkAAAAAAAABKAEA; ncftpd
+ D> type=dir;unique=AQkAAAAAAAABGAEA; outbox
+ D> type=dir;unique=AQkAAAAAAAABuAAA; quake2
+ D> type=dir;unique=AQkAAAAAAAABQAEA; winstuff
+ S> 226 Listing completed.
+ C> MLSD linux
+ S> 150 Opening ASCII mode data connection for MLS.
+ D> type=cdir;unique=AQkAAAAAAAABWAEA; /linux
+ D> type=pdir;unique=AQkAAAAAAAABCAAA; /
+ D> type=dir;unique=AQkAAAAAAAABeAEA; firewall
+ D> type=file;size=12;unique=AQkAAAAAAAACWAEA; helo_world
+ D> type=dir;unique=AQkAAAAAAAABYAEA; kernel
+ D> type=dir;unique=AQkAAAAAAAABmAEA; scripts
+ D> type=dir;unique=AQkAAAAAAAABkAEA; security
+ S> 226 Listing completed.
+ C> MLSD linux/kernel
+ S> 150 Opening ASCII mode data connection for MLS.
+ D> type=cdir;unique=AQkAAAAAAAABYAEA; /linux/kernel
+ D> type=pdir;unique=AQkAAAAAAAABWAEA; /linux
+ D> type=file;size=6704;unique=AQkAAAAAAAADYAEA; k.config
+ D> type=file;size=7269221;unique=AQkAAAAAAAACYAEA; linux-2.0.36.tar.gz
+ D> type=file;size=12514594;unique=AQkAAAAAAAAEYAEA; linux-2.1.130.tar.gz
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 47]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ S> 226 Listing completed.
+
+ Note that this server returns its "unique" fact value in quite a
+ different format. It also returns fully qualified path names for the
+ "pdir" entry.
+
+8.7.7. Some IANA files
+
+ C> MLSD .
+ S> 150 BINARY connection open for MLSD .
+ D> Type=cdir;Modify=19990219183438; /iana/assignments
+ D> Type=pdir;Modify=19990112030453; ..
+ D> Type=dir;Modify=19990219073522; media-types
+ D> Type=dir;Modify=19990112033515; character-set-info
+ D> Type=dir;Modify=19990112033529; languages
+ D> Type=file;Size=44242;Modify=19990217230400; character-sets
+ D> Type=file;Size=1947;Modify=19990209215600; operating-system-names
+ S> 226 MLSD completed
+ C> MLSD media-types
+ S> 150 BINARY connection open for MLSD media-types
+ D> Type=cdir;Modify=19990219073522; media-types
+ D> Type=cdir;Modify=19990219073522; /iana/assignments/media-types
+ D> Type=pdir;Modify=19990219183438; ..
+ D> Type=dir;Modify=19990112033045; text
+ D> Type=dir;Modify=19990219183442; image
+ D> Type=dir;Modify=19990112033216; multipart
+ D> Type=dir;Modify=19990112033254; video
+ D> Type=file;Size=30249;Modify=19990218032700; media-types
+ S> 226 MLSD completed
+ C> MLSD character-set-info
+ S> 150 BINARY connection open for MLSD character-set-info
+ D> Type=cdir;Modify=19990112033515; character-set-info
+ D> Type=cdir;Modify=19990112033515; /iana/assignments/character-set-info
+ D> Type=pdir;Modify=19990219183438; ..
+ D> Type=file;Size=1234;Modify=19980903020400; windows-1251
+ D> Type=file;Size=4557;Modify=19980922001400; tis-620
+ D> Type=file;Size=801;Modify=19970324130000; ibm775
+ D> Type=file;Size=552;Modify=19970320130000; ibm866
+ D> Type=file;Size=922;Modify=19960505140000; windows-1258
+ S> 226 MLSD completed
+ C> MLSD languages
+ S> 150 BINARY connection open for MLSD languages
+ D> Type=cdir;Modify=19990112033529; languages
+ D> Type=cdir;Modify=19990112033529; /iana/assignments/languages
+ D> Type=pdir;Modify=19990219183438; ..
+ D> Type=file;Size=2391;Modify=19980309130000; default
+ D> Type=file;Size=943;Modify=19980309130000; tags
+ D> Type=file;Size=870;Modify=19971026130000; navajo
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 48]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ D> Type=file;Size=699;Modify=19950911140000; no-bok
+ S> 226 MLSD completed
+ C> PWD
+ S> 257 "/iana/assignments" is current directory.
+
+ This example shows some of the IANA maintained files that are
+ relevant for this specification in MLSD format. Note that these
+ listings have been edited by deleting many entries, the actual
+ listings are much longer.
+
+8.7.8. A stress test of case (in)dependence
+
+ The following example is intended to make clear some cases where case
+ dependent strings are permitted in the MLSx commands, and where case
+ independent strings are required.
+
+ C> MlsD .
+ S> 150 BINARY connection open for MLSD .
+ D> Type=pdir;Modify=19990929011228;Perm=el;Unique=keVO1+ZF4; ..
+ D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+Bd8; FILE2
+ D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+aG8; file3
+ D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+ag8; FILE3
+ D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+bD8; file1
+ D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+bD8; file2
+ D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+Ag8; File3
+ D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+bD8; File1
+ D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+Bd8; File2
+ D> Type=file;Size=4096;Modify=19990929011440;Perm=r;Unique=keVO1+bd8; FILE1
+ S> 226 MLSD completed
+
+ Note first that the "MLSD" command, shown here as "MlsD" is case
+ independent. Clients may issue this command in any case, or
+ combination of cases, they desire. This is the case for all FTP
+ commands.
+
+ Next, notice the labels of the facts. These are also case
+ independent strings, Server-FTP is permitted to return them in any
+ case they desire. User-FTP must be prepared to deal with any case,
+ though it may do this by mapping the labels to a common case if
+ desired.
+
+ Then, notice that there are nine objects of "type" file returned. In
+ a case independent NVFS these would represent three different file
+ names, "file1", "file2", and "file3". With a case dependent NVFS all
+ nine represent different file names. Either is possible, server-FTPs
+ may implement a case dependent or a case independent NVFS. User-FTPs
+ must allow for case dependent selection of files to manipulate on the
+ server.
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 49]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ Lastly, notice that the value of the "unique" fact is case dependent.
+ In the example shown, "file1", "File1", and "file2" all have the same
+ "unique" fact value "keVO1+bD8", and thus all represent the same
+ underlying file. On the other hand, "FILE1" has a different "unique"
+ fact value ("keVO1+bd8") and hence represents a different file.
+ Similarly, "FILE2" and "File2" are two names for the same underlying
+ file, whereas "file3", "File3" and "FILE3" all represent different
+ underlying files.
+
+ That the approximate sizes ("size" fact) and last modification times
+ ("modify" fact) are the same in all cases might be no more than a
+ coincidence.
+
+ It is not suggested that the operators of server-FTPs create NVFS
+ which stress the protocols to this extent, however both user and
+ server implementations must be prepared to deal with such extreme
+ examples.
+
+8.8. FEAT response for MLSx
+
+ When responding to the FEAT command, a server-FTP process that
+ supports MLST, and MLSD, plus internationalization of pathnames, MUST
+ indicate that this support exists. It does this by including a MLST
+ feature line. As well as indicating the basic support, the MLST
+ feature line indicates which MLST facts are available from the
+ server, and which of those will be returned if no subsequent "OPTS
+ MLST" command is sent.
+
+ mlst-feat = SP "MLST" [SP factlist] CRLF
+ factlist = 1*( factname ["*"] ";" )
+
+ The initial space shown in the mlst-feat response is that required by
+ the FEAT command, two spaces are not permitted. If no factlist is
+ given, then the server-FTP process is indicating that it supports
+ MLST, but implements no facts. Only pathnames can be returned. This
+ would be a minimal MLST implementation, and useless for most
+ practical purposes. Where the factlist is present, the factnames
+ included indicate the facts supported by the server. Where the
+ optional asterisk appears after a factname, that fact will be
+ included in MLST format responses, until an "OPTS MLST" is given to
+ alter the list of facts returned. After that, subsequent FEAT
+ commands will return the asterisk to show the facts selected by the
+ most recent "OPTS MLST".
+
+ Note that there is no distinct FEAT output for MLSD. The presence of
+ the MLST feature indicates that both MLST and MLSD are supported.
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 50]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+8.8.1. Examples
+
+ C> Feat
+ S> 211- Features supported
+ S> REST STREAM
+ S> MDTM
+ S> SIZE
+ S> TVFS
+ S> UTF8
+ S> MLST Type*;Size*;Modify*;Perm*;Unique*;UNIX.mode;UNIX.chgd;X.hidden;
+ S> 211 End
+
+ Aside from some features irrelevant here, this server indicates that
+ it supports MLST including several, but not all, standard facts, all
+ of which it will send by default. It also supports two OS dependent
+ facts, and one locally defined fact. The latter three must be
+ requested expressly by the client for this server to supply them.
+
+ C> Feat
+ S> 211-Extensions supported:
+ S> CLNT
+ S> MDTM
+ S> MLST type*;size*;modify*;UNIX.mode*;UNIX.owner;UNIX.group;unique;
+ S> PASV
+ S> REST STREAM
+ S> SIZE
+ S> TVFS
+ S> Compliance Level: 19981201 (IETF mlst-05)
+ S> 211 End.
+
+ Again, in addition to some irrelevant features here, this server
+ indicates that it supports MLST, four of the standard facts, one of
+ which ("unique") is not enabled by default, and several OS dependent
+ facts, one of which is provided by the server by default. This
+ server actually supported more OS dependent facts. Others were
+ deleted for the purposes of this document to comply with document
+ formatting restrictions.
+
+8.9. OPTS parameters for MLST
+
+ For the MLSx commands, the Client-FTP may specify a list of facts it
+ wishes to be returned in all subsequent MLSx commands until another
+ OPTS MLST command is sent. The format is specified by:
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 51]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ mlst-opts = "OPTS" SP "MLST"
+ [ SP 1*( factname ";" ) ]
+
+ By sending the "OPTS MLST" command, the client requests the server to
+ include only the facts listed as arguments to the command in
+ subsequent output from MLSx commands. Facts not included in the
+ "OPTS MLST" command MUST NOT be returned by the server. Facts that
+ are included should be returned for each entry returned from the MLSx
+ command where they meaningfully apply. Facts requested that are not
+ supported, or which are inappropriate to the file or directory being
+ listed should simply be omitted from the MLSx output. This is not an
+ error. Note that where no factname arguments are present, the client
+ is requesting that only the file names be returned. In this case,
+ and in any other case where no facts are included in the result, the
+ space that separates the fact names and their values from the file
+ name is still required. That is, the first character of the output
+ line will be a space, (or two characters will be spaces when the line
+ is returned over the control connection,) and the file name will
+ start immediately thereafter.
+
+ Clients should note that generating values for some facts can be
+ possible, but very expensive, for some servers. It is generally
+ acceptable to retrieve any of the facts that the server offers as its
+ default set before any "OPTS MLST" command has been given, however
+ clients should use particular caution before requesting any facts not
+ in that set. That is, while other facts may be available from the
+ server, clients should refrain from requesting such facts unless
+ there is a particular operational requirement for that particular
+ information, which ought be more significant than perhaps simply
+ improving the information displayed to an end user.
+
+ Note, there is no "OPTS MLSD" command, the fact names set with the
+ "OPTS MLST" command apply to both MLST and MLSD commands.
+
+ Servers are not required to accept "OPTS MLST" commands before
+ authentication of the user-PI, but may choose to permit them.
+
+8.9.1. OPTS MLST Response
+
+ The "response-message" from [6] to a successful OPTS MLST command has
+ the following syntax.
+
+ mlst-opt-resp = "MLST OPTS" [ SP 1*( factname ";" ) ]
+
+ This defines the "response-message" as used in the "opts-good"
+ message in RFC2389 [6].
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 52]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ The facts named in the response are those which the server will now
+ include in MLST (and MLSD) response, after the processing of the
+ "OPTS MLST" command. Any facts from the request not supported by the
+ server will be omitted from this response message. If no facts will
+ be included, the list of facts will be empty. Note that the list of
+ facts returned will be the same as those marked by a trailing
+ asterisk ("*") in a subsequent FEAT command response. There is no
+ requirement that the order of the facts returned be the same as that
+ in which they were requested, or that in which they will be listed in
+ a FEAT command response, or that in which facts are returned in MLST
+ responses. The fixed string "MLST OPTS" in the response may be
+ returned in any case, or mixture of cases.
+
+8.9.2. Examples
+
+ C> Feat
+ S> 211- Features supported
+ S> MLST Type*;Size;Modify*;Perm;Unique;UNIX.mode;UNIX.chgd;X.hidden;
+ S> 211 End
+ C> OptS Mlst Type;UNIX.mode;Perm;
+ S> 201 MLST OPTS Type;Perm;UNIX.mode;
+ C> Feat
+ S> 211- Features supported
+ S> MLST Type*;Size;Modify;Perm*;Unique;UNIX.mode*;UNIX.chgd;X.hidden;
+ S> 211 End
+ C> opts MLst lang;type;charset;create;
+ S> 201 MLST OPTS Type;
+ C> Feat
+ S> 211- Features supported
+ S> MLST Type*;Size;Modify;Perm;Unique;UNIX.mode;UNIX.chgd;X.hidden;
+ S> 211 End
+ C> OPTS mlst size;frogs;
+ S> 201 MLST OPTS Size;
+ C> Feat
+ S> 211- Features supported
+ S> MLST Type;Size*;Modify;Perm;Unique;UNIX.mode;UNIX.chgd;X.hidden;
+ S> 211 End
+ C> opts MLst unique type;
+ S> 501 Invalid MLST options
+ C> Feat
+ S> 211- Features supported
+ S> MLST Type;Size*;Modify;Perm;Unique;UNIX.mode;UNIX.chgd;X.hidden;
+ S> 211 End
+
+ For the purposes of this example, features other than MLST have been
+ deleted from the output to avoid clutter. The example shows the
+ initial default feature output for MLST. The facts requested are
+ then changed by the client. The first change shows facts that are
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 53]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ available from the server being selected. Subsequent FEAT output
+ shows the altered features as being returned. The client then
+ attempts to select some standard features which the server does not
+ support. This is not an error, however the server simply ignores the
+ requests for unsupported features, as the FEAT output that follows
+ shows. Then, the client attempts to request a non-standard, and
+ unsupported, feature. The server ignores that, and selects only the
+ supported features requested. Lastly, the client sends a request
+ containing a syntax error (spaces cannot appear in the factlist.) The
+ server-FTP sends an error response and completely ignores the
+ request, leaving the fact set selected as it had been previously.
+
+ Note that in all cases, except the error response, the response lists
+ the facts that have been selected.
+
+ C> Feat
+ S> 211- Features supported
+ S> MLST Type*;Size*;Modify*;Perm*;Unique*;UNIX.mode;UNIX.chgd;X.hidden;
+ S> 211 End
+ C> Opts MLST
+ S> 201 MLST OPTS
+ C> Feat
+ S> 211- Features supported
+ S> MLST Type;Size;Modify;Perm;Unique;UNIX.mode;UNIX.chgd;X.hidden;
+ S> 211 End
+ C> MLst tmp
+ S> 250- Listing tmp
+ S> /tmp
+ S> 250 End
+ C> OPTS mlst unique;size;
+ S> 201 MLST OPTS Size;Unique;
+ C> MLst tmp
+ S> 250- Listing tmp
+ S> Unique=keVO1+YZ5; /tmp
+ S> 250 End
+ C> OPTS mlst unique;type;modify;
+ S> 201 MLST OPTS Type;Modify;Unique;
+ C> MLst tmp
+ S> 250- Listing tmp
+ S> Type=dir;Modify=19990930152225;Unique=keVO1+YZ5; /tmp
+ S> 250 End
+ C> OPTS mlst fish;cakes;
+ S> 201 MLST OPTS
+ C> MLst tmp
+ S> 250- Listing tmp
+ S> /tmp
+ S> 250 End
+ C> OptS Mlst Modify;Unique;
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 54]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ S> 201 MLST OPTS Modify;Unique;
+ C> MLst tmp
+ S> 250- Listing tmp
+ S> Modify=19990930152225;Unique=keVO1+YZ5; /tmp
+ S> 250 End
+ C> opts MLst fish cakes;
+ S> 501 Invalid MLST options
+ C> MLst tmp
+ S> 250- Listing tmp
+ S> Modify=19990930152225;Unique=keVO1+YZ5; /tmp
+ S> 250 End
+
+ This example shows the effect of changing the facts requested upon
+ subsequent MLST commands. Notice that a syntax error leaves the set
+ of selected facts unchanged. Also notice exactly two spaces
+ preceding the pathname when no facts were selected, either
+ deliberately, or because none of the facts requested were available.
+
+9. Impact On Other FTP Commands
+
+ Along with the introduction of MLST, traditional FTP commands must be
+ extended to allow for the use of more than US-ASCII or EBCDIC
+ character sets. In general, the support of MLST requires support for
+ arbitrary character sets wherever filenames and directory names are
+ allowed. This applies equally to both arguments given to the
+ following commands and to the replies from them, as appropriate.
+
+ CWD
+ RETR
+ STOR
+ STOU
+ APPE
+ RNFR
+ RNTO
+ DELE
+ RMD
+ MKD
+ PWD
+ STAT
+
+ The arguments to all of these commands should be processed the same
+ way that MLST commands and responses are processed with respect to
+ handling embedded spaces, CRs and NULs. See section 2.2.
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 55]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+10. Character sets and Internationalization
+
+ FTP commands are protocol elements, and are always expressed in
+ ASCII. FTP responses are composed of the numeric code, which is a
+ protocol element, and a message, which is often expected to convey
+ information to the user. It is not expected that users normally
+ interact directly with the protocol elements, rather the user FTP-
+ process constructs the commands, and interprets the results, in the
+ manner best suited for the particular user. Explanatory text in
+ responses generally has no particular meaning to the protocol. The
+ numeric codes provide all necessary information. Server-PIs are free
+ to provide the text in any language that can be adequately
+ represented in ASCII, or where an alternative language and
+ representation has been negotiated (see [7]) in that language and
+ representation.
+
+ Pathnames are expected to be encoded in UTF-8 allowing essentially
+ any character to be represented in a pathname. Meaningful pathnames
+ are defined by the server NVFS.
+
+ No restrictions at all are placed upon the contents of files
+ transferred using the FTP protocols. Unless the "media-type" fact is
+ provided in a MLSx response nor is any advice given here which would
+ allow determining the content type. That information is assumed to
+ be obtained via other means.
+
+11. IANA Considerations
+
+ This specification makes use of some lists of values currently
+ maintained by the IANA, and creates two new lists for the IANA to
+ maintain. It does not add any values to any existing registries.
+
+ The existing IANA registries used by this specification are modified
+ using mechanisms specified elsewhere.
+
+11.1. The OS specific fact registry
+
+ A registry of OS specific fact names shall be maintained by the IANA.
+ The OS names for the OS portion of the fact name must be taken from
+ the IANA's list of registered OS names. To add a fact name to this
+ OS specific registry of OS specific facts, an applicant must send to
+ the IANA a request, in which is specified the OS name, the OS
+ specific fact name, a definition of the syntax of the fact value,
+ which must conform to the syntax of a token as given in this
+ document, and a specification of the semantics to be associated with
+ the particular fact and its values. Upon receipt of such an
+ application, and if the combination of OS name and OS specific fact
+ name has not been previously defined, the IANA will add the
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 56]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ specification to the registry.
+
+ Any examples of OS specific facts found in this document are to be
+ treated as examples of possible OS specific facts, and do not form a
+ part of the IANA's registry merely because of being included in this
+ document.
+
+11.2. The OS specific filetype registry
+
+ A registry of OS specific file types shall be maintained by the IANA.
+ The OS names for the OS portion of the fact name must be taken from
+ the IANA's list of registered OS names. To add a file type to this
+ OS specific registry of OS specific file types, an applicant must
+ send to the IANA a request, in which is specified the OS name, the OS
+ specific file type, a definition of the syntax of the fact value,
+ which must conform to the syntax of a token as given in this
+ document, and a specification of the semantics to be associated with
+ the particular fact and its values. Upon receipt of such an
+ application, and if the combination of OS name and OS specific file
+ type has not been previously defined, the IANA will add the
+ specification to the registry.
+
+ Any examples of OS specific file types found in this document are to
+ be treated as potential OS specific file types only, and do not form
+ a part of the IANA's registry merely because of being included in
+ this document.
+
+12. Security Considerations
+
+ This memo does not directly concern security. It is not believed
+ that any of the mechanisms documented here impact in any particular
+ way upon the security of FTP.
+
+ Implementing the SIZE command, and perhaps some of the facts of the
+ MDLx commands, may impose a considerable load on the server, which
+ could lead to denial of service attacks. Servers have, however,
+ implemented this for many years, without significant reported
+ difficulties.
+
+ With the introduction of virtual hosts to FTP, and the possible
+ accompanying multiple authentication environments, server
+ implementors will need to take some care to ensure that integrity is
+ maintained.
+
+ The FEAT and OPTS commands may be issued before the FTP
+ authentication has occurred [6]. This allows unauthenticated clients
+ to determine which of the features defined here are supported, and to
+ negotiate the fact list for MLSx output. No actual MLSx commands may
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 57]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ be issued however, and no problems with permitting the selection of
+ the format prior to authentication are foreseen.
+
+ A general discussion of issues related to the security of FTP can be
+ found in [14].
+
+13. References
+
+ [1] Coded Character Set--7-bit American Standard Code for Information
+ Interchange, ANSI X3.4-1986.
+
+ [2] Yergeau, F., "UTF-8, a transformation format of Unicode and ISO
+ 10646", RFC 2044, October 1996.
+
+ [3] Postel, J., Reynolds, J., "File Transfer Protocol (FTP)",
+ STD 9, RFC 959, October 1985
+
+ [4] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997
+
+ [5] Crocker, D., Overell, P., "Augmented BNF for Syntax
+ Specifications: ABNF", RFC 2234, November 1997
+
+ [6] Hethmon, P., Elz, R., "Feature negotiation mechanism for the
+ File Transfer Protocol", RFC 2389, August 1998
+
+ [7] Curtin, W., "Internationalization of the File Transfer Protocol",
+ RFC 2640, July 1999
+
+ [8] Postel, J., Reynolds, J., "Telnet protocol Specification"
+ STD 8, RFC 854, May 1983
+
+ [9] Braden, R,. "Requirements for Internet Hosts -- Application
+ and Support", STD 3, RFC 1123, October 1989
+
+ [10] Mockapetris, P., "Domain Names - Concepts and Facilities"
+ STD 13, RFC 1034, November 1987
+
+ [11] ISO/IEC 10646-1:1993 "Universal multiple-octet coded character set
+ (UCS) -- Part 1: Architecture and basic multilingual plane",
+ International Standard -- Information Technology, 1993
+
+ [12] Internet Assigned Numbers Authority. http://www.iana.org
+ Email: iana@iana.org.
+
+ [13] Alvestrand, H., "Tags for the Identification of Languages"
+ RFC 1766, March 1995
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 58]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+ [14] Allman, M., Ostermann, S., "FTP Security Considerations"
+ RFC 2577, May 1999
+
+Acknowledgments
+
+ This document is a product of the FTPEXT working group of the IETF.
+
+ The following people are among those who have contributed to this
+ document:
+
+ Alex Belits
+ D. J. Bernstein
+ Dave Cridland
+ Martin J. Duerst
+ Mike Gleason
+ Mark Harris
+ Alun Jones
+ James Matthews
+ Luke Mewburn
+ Jan Mikkelsen
+ Keith Moore
+ Buz Owen
+ Mark Symons
+ Stephen Tihor
+ and the entire FTPEXT working group of the IETF.
+
+ Apologies are offered to any inadvertently omitted.
+
+ Bernhard Rosenkraenzer suggested the HOST command, and initially
+ described it.
+
+ The description of the modifications to the REST command and the MDTM
+ and SIZE commands comes from a set of modifications suggested for
+ RFC959 by Rick Adams in 1989. A draft containing just those
+ commands, edited by David Borman, has been merged with this document.
+
+ Mike Gleason provided access to the FTP server used in some of the
+ examples.
+
+ All of the examples in this document are taken from actual
+ client/server exchanges, though some have been edited for brevity, or
+ to meet document formatting requirements.
+
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 59]
+
+
+Internet Draft draft-ietf-ftpext-mlst-08.txt October 1999
+
+
+Copyright
+
+ This document is in the public domain. Any and all copyright
+ protection that might apply in any jurisdiction is expressly
+ disclaimed.
+
+Editors' Addresses
+
+ Robert Elz
+ University of Melbourne
+ Department of Computer Science
+ Parkville, Vic 3052
+ Australia
+
+ Email: kre@munnari.OZ.AU
+
+
+ Paul Hethmon
+ Hethmon Brothers
+ 2305 Chukar Road
+ Knoxville, TN 37923 USA
+
+ Phone: +1 423 690 8990
+ Email: phethmon@hethmon.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Elz & Hethmon [Expires April 2000] [Page 60]
diff --git a/crypto/heimdal/doc/standardisation/rfc1508.txt b/crypto/heimdal/doc/standardisation/rfc1508.txt
new file mode 100644
index 000000000000..132b855e05e6
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/rfc1508.txt
@@ -0,0 +1,2747 @@
+
+
+
+
+
+
+Network Working Group J. Linn
+Request for Comments: 1508 Geer Zolot Associates
+ September 1993
+
+
+ Generic Security Service Application Program Interface
+
+Status of this Memo
+
+ This RFC specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" for the standardization state and status
+ of this protocol. Distribution of this memo is unlimited.
+
+Abstract
+
+ This Generic Security Service Application Program Interface (GSS-API)
+ definition provides security services to callers in a generic
+ fashion, supportable with a range of underlying mechanisms and
+ technologies and hence allowing source-level portability of
+ applications to different environments. This specification defines
+ GSS-API services and primitives at a level independent of underlying
+ mechanism and programming language environment, and is to be
+ complemented by other, related specifications:
+
+ documents defining specific parameter bindings for particular
+ language environments
+
+ documents defining token formats, protocols, and procedures to
+ be implemented in order to realize GSS-API services atop
+ particular security mechanisms
+
+Table of Contents
+
+ 1. GSS-API Characteristics and Concepts ....................... 2
+ 1.1. GSS-API Constructs ....................................... 5
+ 1.1.1. Credentials ........................................... 5
+ 1.1.2. Tokens ................................................ 6
+ 1.1.3. Security Contexts ..................................... 7
+ 1.1.4. Mechanism Types ....................................... 8
+ 1.1.5. Naming ................................................ 9
+ 1.1.6. Channel Bindings ...................................... 10
+ 1.2. GSS-API Features and Issues ............................. 11
+ 1.2.1. Status Reporting ...................................... 11
+ 1.2.2. Per-Message Security Service Availability ............. 12
+ 1.2.3. Per-Message Replay Detection and Sequencing ........... 13
+ 1.2.4. Quality of Protection ................................. 15
+
+
+
+Linn [Page 1]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ 2. Interface Descriptions ..................................... 15
+ 2.1. Credential management calls ............................. 17
+ 2.1.1. GSS_Acquire_cred call ................................. 17
+ 2.1.2. GSS_Release_cred call ................................. 19
+ 2.1.3. GSS_Inquire_cred call ................................. 20
+ 2.2. Context-level calls ..................................... 21
+ 2.2.1. GSS_Init_sec_context call ............................. 21
+ 2.2.2. GSS_Accept_sec_context call ........................... 26
+ 2.2.3. GSS_Delete_sec_context call ........................... 29
+ 2.2.4. GSS_Process_context_token call ........................ 30
+ 2.2.5. GSS_Context_time call ................................. 31
+ 2.3. Per-message calls ....................................... 32
+ 2.3.1. GSS_Sign call ......................................... 32
+ 2.3.2. GSS_Verify call ....................................... 33
+ 2.3.3. GSS_Seal call ......................................... 35
+ 2.3.4. GSS_Unseal call ....................................... 36
+ 2.4. Support calls ........................................... 37
+ 2.4.1. GSS_Display_status call ............................... 37
+ 2.4.2. GSS_Indicate_mechs call ............................... 38
+ 2.4.3. GSS_Compare_name call ................................. 38
+ 2.4.4. GSS_Display_name call ................................. 39
+ 2.4.5. GSS_Import_name call .................................. 40
+ 2.4.6. GSS_Release_name call ................................. 41
+ 2.4.7. GSS_Release_buffer call ............................... 41
+ 2.4.8. GSS_Release_oid_set call .............................. 42
+ 3. Mechanism-Specific Example Scenarios ....................... 42
+ 3.1. Kerberos V5, single-TGT ................................. 43
+ 3.2. Kerberos V5, double-TGT ................................. 43
+ 3.3. X.509 Authentication Framework .......................... 44
+ 4. Related Activities ......................................... 45
+ 5. Acknowledgments ............................................ 46
+ 6. Security Considerations .................................... 46
+ 7. Author's Address ........................................... 46
+ Appendix A .................................................... 47
+ Appendix B .................................................... 48
+ Appendix C .................................................... 49
+
+1. GSS-API Characteristics and Concepts
+
+ The operational paradigm in which GSS-API operates is as follows. A
+ typical GSS-API caller is itself a communications protocol, calling
+ on GSS-API in order to protect its communications with
+ authentication, integrity, and/or confidentiality security services.
+ A GSS-API caller accepts tokens provided to it by its local GSS-API
+ implementation and transfers the tokens to a peer on a remote system;
+ that peer passes the received tokens to its local GSS-API
+ implementation for processing. The security services available
+ through GSS-API in this fashion are implementable (and have been
+
+
+
+Linn [Page 2]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ implemented) over a range of underlying mechanisms based on secret-
+ key and public-key cryptographic technologies.
+
+ The GSS-API separates the operations of initializing a security
+ context between peers, achieving peer entity authentication (This
+ security service definition, and other definitions used in this
+ document, corresponds to that provided in International Standard ISO
+ 7498-2-1988(E), Security Architecture.) (GSS_Init_sec_context() and
+ GSS_Accept_sec_context() calls), from the operations of providing
+ per-message data origin authentication and data integrity protection
+ (GSS_Sign() and GSS_Verify() calls) for messages subsequently
+ transferred in conjunction with that context. Per-message GSS_Seal()
+ and GSS_Unseal() calls provide the data origin authentication and
+ data integrity services which GSS_Sign() and GSS_Verify() offer, and
+ also support selection of confidentiality services as a caller
+ option. Additional calls provide supportive functions to the GSS-
+ API's users.
+
+ The following paragraphs provide an example illustrating the
+ dataflows involved in use of the GSS-API by a client and server in a
+ mechanism-independent fashion, establishing a security context and
+ transferring a protected message. The example assumes that credential
+ acquisition has already been completed. The example assumes that the
+ underlying authentication technology is capable of authenticating a
+ client to a server using elements carried within a single token, and
+ of authenticating the server to the client (mutual authentication)
+ with a single returned token; this assumption holds for presently-
+ documented CAT mechanisms but is not necessarily true for other
+ cryptographic technologies and associated protocols.
+
+ The client calls GSS_Init_sec_context() to establish a security
+ context to the server identified by targ_name, and elects to set the
+ mutual_req_flag so that mutual authentication is performed in the
+ course of context establishment. GSS_Init_sec_context() returns an
+ output_token to be passed to the server, and indicates
+ GSS_CONTINUE_NEEDED status pending completion of the mutual
+ authentication sequence. Had mutual_req_flag not been set, the
+ initial call to GSS_Init_sec_context() would have returned
+ GSS_COMPLETE status. The client sends the output_token to the server.
+
+ The server passes the received token as the input_token parameter to
+ GSS_Accept_sec_context(). GSS_Accept_sec_context indicates
+ GSS_COMPLETE status, provides the client's authenticated identity in
+ the src_name result, and provides an output_token to be passed to the
+ client. The server sends the output_token to the client.
+
+ The client passes the received token as the input_token parameter to
+ a successor call to GSS_Init_sec_context(), which processes data
+
+
+
+Linn [Page 3]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ included in the token in order to achieve mutual authentication from
+ the client's viewpoint. This call to GSS_Init_sec_context() returns
+ GSS_COMPLETE status, indicating successful mutual authentication and
+ the completion of context establishment for this example.
+
+ The client generates a data message and passes it to GSS_Seal().
+ GSS_Seal() performs data origin authentication, data integrity, and
+ (optionally) confidentiality processing on the message and
+ encapsulates the result into output_message, indicating GSS_COMPLETE
+ status. The client sends the output_message to the server.
+
+ The server passes the received message to GSS_Unseal(). GSS_Unseal
+ inverts the encapsulation performed by GSS_Seal(), deciphers the
+ message if the optional confidentiality feature was applied, and
+ validates the data origin authentication and data integrity checking
+ quantities. GSS_Unseal() indicates successful validation by
+ returning GSS_COMPLETE status along with the resultant
+ output_message.
+
+ For purposes of this example, we assume that the server knows by
+ out-of-band means that this context will have no further use after
+ one protected message is transferred from client to server. Given
+ this premise, the server now calls GSS_Delete_sec_context() to flush
+ context-level information. GSS_Delete_sec_context() returns a
+ context_token for the server to pass to the client.
+
+ The client passes the returned context_token to
+ GSS_Process_context_token(), which returns GSS_COMPLETE status after
+ deleting context-level information at the client system.
+
+ The GSS-API design assumes and addresses several basic goals,
+ including:
+
+ Mechanism independence: The GSS-API defines an interface to
+ cryptographically implemented strong authentication and other
+ security services at a generic level which is independent of
+ particular underlying mechanisms. For example, GSS-API-provided
+ services can be implemented by secret-key technologies (e.g.,
+ Kerberos) or public-key approaches (e.g., X.509).
+
+ Protocol environment independence: The GSS-API is independent of
+ the communications protocol suites with which it is employed,
+ permitting use in a broad range of protocol environments. In
+ appropriate environments, an intermediate implementation "veneer"
+ which is oriented to a particular communication protocol (e.g.,
+ Remote Procedure Call (RPC)) may be interposed between
+ applications which call that protocol and the GSS-API, thereby
+ invoking GSS-API facilities in conjunction with that protocol's
+
+
+
+Linn [Page 4]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ communications invocations.
+
+ Protocol association independence: The GSS-API's security context
+ construct is independent of communications protocol association
+ constructs. This characteristic allows a single GSS-API
+ implementation to be utilized by a variety of invoking protocol
+ modules on behalf of those modules' calling applications. GSS-API
+ services can also be invoked directly by applications, wholly
+ independent of protocol associations.
+
+ Suitability to a range of implementation placements: GSS-API
+ clients are not constrained to reside within any Trusted Computing
+ Base (TCB) perimeter defined on a system where the GSS-API is
+ implemented; security services are specified in a manner suitable
+ to both intra-TCB and extra-TCB callers.
+
+1.1. GSS-API Constructs
+
+ This section describes the basic elements comprising the GSS-API.
+
+1.1.1. Credentials
+
+ Credentials structures provide the prerequisites enabling peers to
+ establish security contexts with each other. A caller may designate
+ that its default credential be used for context establishment calls
+ without presenting an explicit handle to that credential.
+ Alternately, those GSS-API callers which need to make explicit
+ selection of particular credentials structures may make references to
+ those credentials through GSS-API-provided credential handles
+ ("cred_handles").
+
+ A single credential structure may be used for initiation of outbound
+ contexts and acceptance of inbound contexts. Callers needing to
+ operate in only one of these modes may designate this fact when
+ credentials are acquired for use, allowing underlying mechanisms to
+ optimize their processing and storage requirements. The credential
+ elements defined by a particular mechanism may contain multiple
+ cryptographic keys, e.g., to enable authentication and message
+ encryption to be performed with different algorithms.
+
+ A single credential structure may accommodate credential information
+ associated with multiple underlying mechanisms (mech_types); a
+ credential structure's contents will vary depending on the set of
+ mech_types supported by a particular GSS-API implementation.
+ Commonly, a single mech_type will be used for all security contexts
+ established by a particular initiator to a particular target; the
+ primary motivation for supporting credential sets representing
+ multiple mech_types is to allow initiators on systems which are
+
+
+
+Linn [Page 5]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ equipped to handle multiple types to initiate contexts to targets on
+ other systems which can accommodate only a subset of the set
+ supported at the initiator's system.
+
+ It is the responsibility of underlying system-specific mechanisms and
+ OS functions below the GSS-API to ensure that the ability to acquire
+ and use credentials associated with a given identity is constrained
+ to appropriate processes within a system. This responsibility should
+ be taken seriously by implementors, as the ability for an entity to
+ utilize a principal's credentials is equivalent to the entity's
+ ability to successfully assert that principal's identity.
+
+ Once a set of GSS-API credentials is established, the transferability
+ of that credentials set to other processes or analogous constructs
+ within a system is a local matter, not defined by the GSS-API. An
+ example local policy would be one in which any credentials received
+ as a result of login to a given user account, or of delegation of
+ rights to that account, are accessible by, or transferable to,
+ processes running under that account.
+
+ The credential establishment process (particularly when performed on
+ behalf of users rather than server processes) is likely to require
+ access to passwords or other quantities which should be protected
+ locally and exposed for the shortest time possible. As a result, it
+ will often be appropriate for preliminary credential establishment to
+ be performed through local means at user login time, with the
+ result(s) cached for subsequent reference. These preliminary
+ credentials would be set aside (in a system-specific fashion) for
+ subsequent use, either:
+
+ to be accessed by an invocation of the GSS-API GSS_Acquire_cred()
+ call, returning an explicit handle to reference that credential
+
+ as the default credentials installed on behalf of a process
+
+1.1.2. Tokens
+
+ Tokens are data elements transferred between GSS-API callers, and are
+ divided into two classes. Context-level tokens are exchanged in order
+ to establish and manage a security context between peers. Per-message
+ tokens are exchanged in conjunction with an established context to
+ provide protective security services for corresponding data messages.
+ The internal contents of both classes of tokens are specific to the
+ particular underlying mechanism used to support the GSS-API; Appendix
+ B of this document provides a uniform recommendation for designers of
+ GSS-API support mechanisms, encapsulating mechanism-specific
+ information along with a globally-interpretable mechanism identifier.
+
+
+
+
+Linn [Page 6]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ Tokens are opaque from the viewpoint of GSS-API callers. They are
+ generated within the GSS-API implementation at an end system,
+ provided to a GSS-API caller to be transferred to the peer GSS-API
+ caller at a remote end system, and processed by the GSS-API
+ implementation at that remote end system. Tokens may be output by
+ GSS-API primitives (and are to be transferred to GSS-API peers)
+ independent of the status indications which those primitives
+ indicate. Token transfer may take place in an in-band manner,
+ integrated into the same protocol stream used by the GSS-API callers
+ for other data transfers, or in an out-of-band manner across a
+ logically separate channel.
+
+ Development of GSS-API support primitives based on a particular
+ underlying cryptographic technique and protocol does not necessarily
+ imply that GSS-API callers invoking that GSS-API mechanism type will
+ be able to interoperate with peers invoking the same technique and
+ protocol outside the GSS-API paradigm. For example, the format of
+ GSS-API tokens defined in conjunction with a particular mechanism,
+ and the techniques used to integrate those tokens into callers'
+ protocols, may not be the same as those used by non-GSS-API callers
+ of the same underlying technique.
+
+1.1.3. Security Contexts
+
+ Security contexts are established between peers, using credentials
+ established locally in conjunction with each peer or received by
+ peers via delegation. Multiple contexts may exist simultaneously
+ between a pair of peers, using the same or different sets of
+ credentials. Coexistence of multiple contexts using different
+ credentials allows graceful rollover when credentials expire.
+ Distinction among multiple contexts based on the same credentials
+ serves applications by distinguishing different message streams in a
+ security sense.
+
+ The GSS-API is independent of underlying protocols and addressing
+ structure, and depends on its callers to transport GSS-API-provided
+ data elements. As a result of these factors, it is a caller
+ responsibility to parse communicated messages, separating GSS-API-
+ related data elements from caller-provided data. The GSS-API is
+ independent of connection vs. connectionless orientation of the
+ underlying communications service.
+
+ No correlation between security context and communications protocol
+ association is dictated. (The optional channel binding facility,
+ discussed in Section 1.1.6 of this document, represents an
+ intentional exception to this rule, supporting additional protection
+ features within GSS-API supporting mechanisms.) This separation
+ allows the GSS-API to be used in a wide range of communications
+
+
+
+Linn [Page 7]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ environments, and also simplifies the calling sequences of the
+ individual calls. In many cases (depending on underlying security
+ protocol, associated mechanism, and availability of cached
+ information), the state information required for context setup can be
+ sent concurrently with initial signed user data, without interposing
+ additional message exchanges.
+
+1.1.4. Mechanism Types
+
+ In order to successfully establish a security context with a target
+ peer, it is necessary to identify an appropriate underlying mechanism
+ type (mech_type) which both initiator and target peers support. The
+ definition of a mechanism embodies not only the use of a particular
+ cryptographic technology (or a hybrid or choice among alternative
+ cryptographic technologies), but also definition of the syntax and
+ semantics of data element exchanges which that mechanism will employ
+ in order to support security services.
+
+ It is recommended that callers initiating contexts specify the
+ "default" mech_type value, allowing system-specific functions within
+ or invoked by the GSS-API implementation to select the appropriate
+ mech_type, but callers may direct that a particular mech_type be
+ employed when necessary.
+
+ The means for identifying a shared mech_type to establish a security
+ context with a peer will vary in different environments and
+ circumstances; examples include (but are not limited to):
+
+ use of a fixed mech_type, defined by configuration, within an
+ environment
+
+ syntactic convention on a target-specific basis, through
+ examination of a target's name
+
+ lookup of a target's name in a naming service or other database in
+ order to identify mech_types supported by that target
+
+ explicit negotiation between GSS-API callers in advance of
+ security context setup
+
+ When transferred between GSS-API peers, mech_type specifiers (per
+ Appendix B, represented as Object Identifiers (OIDs)) serve to
+ qualify the interpretation of associated tokens. (The structure and
+ encoding of Object Identifiers is defined in ISO/IEC 8824,
+ "Specification of Abstract Syntax Notation One (ASN.1)" and in
+ ISO/IEC 8825, "Specification of Basic Encoding Rules for Abstract
+ Syntax Notation One (ASN.1)".) Use of hierarchically structured OIDs
+ serves to preclude ambiguous interpretation of mech_type specifiers.
+
+
+
+Linn [Page 8]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ The OID representing the DASS MechType, for example, is
+ 1.3.12.2.1011.7.5.
+
+1.1.5. Naming
+
+ The GSS-API avoids prescription of naming structures, treating the
+ names transferred across the interface in order to initiate and
+ accept security contexts as opaque octet string quantities. This
+ approach supports the GSS-API's goal of implementability atop a range
+ of underlying security mechanisms, recognizing the fact that
+ different mechanisms process and authenticate names which are
+ presented in different forms. Generalized services offering
+ translation functions among arbitrary sets of naming environments are
+ outside the scope of the GSS-API; availability and use of local
+ conversion functions to translate among the naming formats supported
+ within a given end system is anticipated.
+
+ Two distinct classes of name representations are used in conjunction
+ with different GSS-API parameters:
+
+ a printable form (denoted by OCTET STRING), for acceptance from
+ and presentation to users; printable name forms are accompanied by
+ OID tags identifying the namespace to which they correspond
+
+ an internal form (denoted by INTERNAL NAME), opaque to callers and
+ defined by individual GSS-API implementations; GSS-API
+ implementations supporting multiple namespace types are
+ responsible for maintaining internal tags to disambiguate the
+ interpretation of particular names
+
+ Tagging of printable names allows GSS-API callers and underlying
+ GSS-API mechanisms to disambiguate name types and to determine
+ whether an associated name's type is one which they are capable of
+ processing, avoiding aliasing problems which could result from
+ misinterpreting a name of one type as a name of another type.
+
+ In addition to providing means for names to be tagged with types,
+ this specification defines primitives to support a level of naming
+ environment independence for certain calling applications. To provide
+ basic services oriented towards the requirements of callers which
+ need not themselves interpret the internal syntax and semantics of
+ names, GSS-API calls for name comparison (GSS_Compare_name()),
+ human-readable display (GSS_Display_name()), input conversion
+ (GSS_Import_name()), and internal name deallocation
+ (GSS_Release_name()) functions are defined. (It is anticipated that
+ these proposed GSS-API calls will be implemented in many end systems
+ based on system-specific name manipulation primitives already extant
+ within those end systems; inclusion within the GSS-API is intended to
+
+
+
+Linn [Page 9]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ offer GSS-API callers a portable means to perform specific
+ operations, supportive of authorization and audit requirements, on
+ authenticated names.)
+
+ GSS_Import_name() implementations can, where appropriate, support
+ more than one printable syntax corresponding to a given namespace
+ (e.g., alternative printable representations for X.500 Distinguished
+ Names), allowing flexibility for their callers to select among
+ alternative representations. GSS_Display_name() implementations
+ output a printable syntax selected as appropriate to their
+ operational environments; this selection is a local matter. Callers
+ desiring portability across alternative printable syntaxes should
+ refrain from implementing comparisons based on printable name forms
+ and should instead use the GSS_Compare_name() call to determine
+ whether or not one internal-format name matches another.
+
+1.1.6. Channel Bindings
+
+ The GSS-API accommodates the concept of caller-provided channel
+ binding ("chan_binding") information, used by GSS-API callers to bind
+ the establishment of a security context to relevant characteristics
+ (e.g., addresses, transformed representations of encryption keys) of
+ the underlying communications channel and of protection mechanisms
+ applied to that communications channel. Verification by one peer of
+ chan_binding information provided by the other peer to a context
+ serves to protect against various active attacks. The caller
+ initiating a security context must determine the chan_binding values
+ before making the GSS_Init_sec_context() call, and consistent values
+ must be provided by both peers to a context. Callers should not
+ assume that underlying mechanisms provide confidentiality protection
+ for channel binding information.
+
+ Use or non-use of the GSS-API channel binding facility is a caller
+ option, and GSS-API supporting mechanisms can support operation in an
+ environment where NULL channel bindings are presented. When non-NULL
+ channel bindings are used, certain mechanisms will offer enhanced
+ security value by interpreting the bindings' content (rather than
+ simply representing those bindings, or signatures computed on them,
+ within tokens) and will therefore depend on presentation of specific
+ data in a defined format. To this end, agreements among mechanism
+ implementors are defining conventional interpretations for the
+ contents of channel binding arguments, including address specifiers
+ (with content dependent on communications protocol environment) for
+ context initiators and acceptors. (These conventions are being
+ incorporated into related documents.) In order for GSS-API callers to
+ be portable across multiple mechanisms and achieve the full security
+ functionality available from each mechanism, it is strongly
+ recommended that GSS-API callers provide channel bindings consistent
+
+
+
+Linn [Page 10]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ with these conventions and those of the networking environment in
+ which they operate.
+
+1.2. GSS-API Features and Issues
+
+ This section describes aspects of GSS-API operations, of the security
+ services which the GSS-API provides, and provides commentary on
+ design issues.
+
+1.2.1. Status Reporting
+
+ Each GSS-API call provides two status return values. Major_status
+ values provide a mechanism-independent indication of call status
+ (e.g., GSS_COMPLETE, GSS_FAILURE, GSS_CONTINUE_NEEDED), sufficient to
+ drive normal control flow within the caller in a generic fashion.
+ Table 1 summarizes the defined major_status return codes in tabular
+ fashion.
+
+ Table 1: GSS-API Major Status Codes
+
+ FATAL ERROR CODES
+
+ GSS_BAD_BINDINGS channel binding mismatch
+ GSS_BAD_MECH unsupported mechanism requested
+ GSS_BAD_NAME invalid name provided
+ GSS_BAD_NAMETYPE name of unsupported type provided
+ GSS_BAD_STATUS invalid input status selector
+ GSS_BAD_SIG token had invalid signature
+ GSS_CONTEXT_EXPIRED specified security context expired
+ GSS_CREDENTIALS_EXPIRED expired credentials detected
+ GSS_DEFECTIVE_CREDENTIAL defective credential detected
+ GSS_DEFECTIVE_TOKEN defective token detected
+ GSS_FAILURE failure, unspecified at GSS-API
+ level
+ GSS_NO_CONTEXT no valid security context specified
+ GSS_NO_CRED no valid credentials provided
+
+ INFORMATORY STATUS CODES
+
+ GSS_COMPLETE normal completion
+ GSS_CONTINUE_NEEDED continuation call to routine
+ required
+ GSS_DUPLICATE_TOKEN duplicate per-message token
+ detected
+ GSS_OLD_TOKEN timed-out per-message token
+ detected
+ GSS_UNSEQ_TOKEN out-of-order per-message token
+ detected
+
+
+
+Linn [Page 11]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ Minor_status provides more detailed status information which may
+ include status codes specific to the underlying security mechanism.
+ Minor_status values are not specified in this document.
+
+ GSS_CONTINUE_NEEDED major_status returns, and optional message
+ outputs, are provided in GSS_Init_sec_context() and
+ GSS_Accept_sec_context() calls so that different mechanisms'
+ employment of different numbers of messages within their
+ authentication sequences need not be reflected in separate code paths
+ within calling applications. Instead, such cases are accomodated with
+ sequences of continuation calls to GSS_Init_sec_context() and
+ GSS_Accept_sec_context(). The same mechanism is used to encapsulate
+ mutual authentication within the GSS-API's context initiation calls.
+
+ For mech_types which require interactions with third-party servers in
+ order to establish a security context, GSS-API context establishment
+ calls may block pending completion of such third-party interactions.
+ On the other hand, no GSS-API calls pend on serialized interactions
+ with GSS-API peer entities. As a result, local GSS-API status
+ returns cannot reflect unpredictable or asynchronous exceptions
+ occurring at remote peers, and reflection of such status information
+ is a caller responsibility outside the GSS-API.
+
+1.2.2. Per-Message Security Service Availability
+
+ When a context is established, two flags are returned to indicate the
+ set of per-message protection security services which will be
+ available on the context:
+
+ the integ_avail flag indicates whether per-message integrity and
+ data origin authentication services are available
+
+ the conf_avail flag indicates whether per-message confidentiality
+ services are available, and will never be returned TRUE unless the
+ integ_avail flag is also returned TRUE
+
+ GSS-API callers desiring per-message security services should
+ check the values of these flags at context establishment time, and
+ must be aware that a returned FALSE value for integ_avail means
+ that invocation of GSS_Sign() or GSS_Seal() primitives on the
+ associated context will apply no cryptographic protection to user
+ data messages.
+
+ The GSS-API per-message protection service primitives, as the
+ category name implies, are oriented to operation at the granularity
+ of protocol data units. They perform cryptographic operations on the
+ data units, transfer cryptographic control information in tokens,
+ and, in the case of GSS_Seal(), encapsulate the protected data unit.
+
+
+
+Linn [Page 12]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ As such, these primitives are not oriented to efficient data
+ protection for stream-paradigm protocols (e.g., Telnet) if
+ cryptography must be applied on an octet-by-octet basis.
+
+1.2.3. Per-Message Replay Detection and Sequencing
+
+ Certain underlying mech_types are expected to offer support for
+ replay detection and/or sequencing of messages transferred on the
+ contexts they support. These optionally-selectable protection
+ features are distinct from replay detection and sequencing features
+ applied to the context establishment operation itself; the presence
+ or absence of context-level replay or sequencing features is wholly a
+ function of the underlying mech_type's capabilities, and is not
+ selected or omitted as a caller option.
+
+ The caller initiating a context provides flags (replay_det_req_flag
+ and sequence_req_flag) to specify whether the use of per-message
+ replay detection and sequencing features is desired on the context
+ being established. The GSS-API implementation at the initiator system
+ can determine whether these features are supported (and whether they
+ are optionally selectable) as a function of mech_type, without need
+ for bilateral negotiation with the target. When enabled, these
+ features provide recipients with indicators as a result of GSS-API
+ processing of incoming messages, identifying whether those messages
+ were detected as duplicates or out-of-sequence. Detection of such
+ events does not prevent a suspect message from being provided to a
+ recipient; the appropriate course of action on a suspect message is a
+ matter of caller policy.
+
+ The semantics of the replay detection and sequencing services applied
+ to received messages, as visible across the interface which the GSS-
+ API provides to its clients, are as follows:
+
+ When replay_det_state is TRUE, the possible major_status returns for
+ well-formed and correctly signed messages are as follows:
+
+ 1. GSS_COMPLETE indicates that the message was within the window
+ (of time or sequence space) allowing replay events to be detected,
+ and that the message was not a replay of a previously-processed
+ message within that window.
+
+ 2. GSS_DUPLICATE_TOKEN indicates that the signature on the
+ received message was correct, but that the message was recognized
+ as a duplicate of a previously-processed message.
+
+ 3. GSS_OLD_TOKEN indicates that the signature on the received
+ message was correct, but that the message is too old to be checked
+ for duplication.
+
+
+
+Linn [Page 13]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ When sequence_state is TRUE, the possible major_status returns for
+ well-formed and correctly signed messages are as follows:
+
+ 1. GSS_COMPLETE indicates that the message was within the window
+ (of time or sequence space) allowing replay events to be detected,
+ and that the message was not a replay of a previously-processed
+ message within that window.
+
+ 2. GSS_DUPLICATE_TOKEN indicates that the signature on the
+ received message was correct, but that the message was recognized
+ as a duplicate of a previously-processed message.
+
+ 3. GSS_OLD_TOKEN indicates that the signature on the received
+ message was correct, but that the token is too old to be checked
+ for duplication.
+
+ 4. GSS_UNSEQ_TOKEN indicates that the signature on the received
+ message was correct, but that it is earlier in a sequenced stream
+ than a message already processed on the context. [Note:
+ Mechanisms can be architected to provide a stricter form of
+ sequencing service, delivering particular messages to recipients
+ only after all predecessor messages in an ordered stream have been
+ delivered. This type of support is incompatible with the GSS-API
+ paradigm in which recipients receive all messages, whether in
+ order or not, and provide them (one at a time, without intra-GSS-
+ API message buffering) to GSS-API routines for validation. GSS-
+ API facilities provide supportive functions, aiding clients to
+ achieve strict message stream integrity in an efficient manner in
+ conjunction with sequencing provisions in communications
+ protocols, but the GSS-API does not offer this level of message
+ stream integrity service by itself.]
+
+ As the message stream integrity features (especially sequencing) may
+ interfere with certain applications' intended communications
+ paradigms, and since support for such features is likely to be
+ resource intensive, it is highly recommended that mech_types
+ supporting these features allow them to be activated selectively on
+ initiator request when a context is established. A context initiator
+ and target are provided with corresponding indicators
+ (replay_det_state and sequence_state), signifying whether these
+ features are active on a given context.
+
+ An example mech_type supporting per-message replay detection could
+ (when replay_det_state is TRUE) implement the feature as follows: The
+ underlying mechanism would insert timestamps in data elements output
+ by GSS_Sign() and GSS_Seal(), and would maintain (within a time-
+ limited window) a cache (qualified by originator-recipient pair)
+ identifying received data elements processed by GSS_Verify() and
+
+
+
+Linn [Page 14]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ GSS_Unseal(). When this feature is active, exception status returns
+ (GSS_DUPLICATE_TOKEN, GSS_ OLD_TOKEN) will be provided when
+ GSS_Verify() or GSS_Unseal() is presented with a message which is
+ either a detected duplicate of a prior message or which is too old to
+ validate against a cache of recently received messages.
+
+1.2.4. Quality of Protection
+
+ Some mech_types will provide their users with fine granularity
+ control over the means used to provide per-message protection,
+ allowing callers to trade off security processing overhead
+ dynamically against the protection requirements of particular
+ messages. A per-message quality-of-protection parameter (analogous to
+ quality-of-service, or QOS) selects among different QOP options
+ supported by that mechanism. On context establishment for a multi-QOP
+ mech_type, context-level data provides the prerequisite data for a
+ range of protection qualities.
+
+ It is expected that the majority of callers will not wish to exert
+ explicit mechanism-specific QOP control and will therefore request
+ selection of a default QOP. Definitions of, and choices among, non-
+ default QOP values are mechanism-specific, and no ordered sequences
+ of QOP values can be assumed equivalent across different mechanisms.
+ Meaningful use of non-default QOP values demands that callers be
+ familiar with the QOP definitions of an underlying mechanism or
+ mechanisms, and is therefore a non-portable construct.
+
+2. Interface Descriptions
+
+ This section describes the GSS-API's service interface, dividing the
+ set of calls offered into four groups. Credential management calls
+ are related to the acquisition and release of credentials by
+ principals. Context-level calls are related to the management of
+ security contexts between principals. Per-message calls are related
+ to the protection of individual messages on established security
+ contexts. Support calls provide ancillary functions useful to GSS-API
+ callers. Table 2 groups and summarizes the calls in tabular fashion.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Linn [Page 15]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ Table 2: GSS-API Calls
+
+ CREDENTIAL MANAGEMENT
+
+ GSS_Acquire_cred acquire credentials for use
+ GSS_Release_cred release credentials after use
+ GSS_Inquire_cred display information about
+ credentials
+
+ CONTEXT-LEVEL CALLS
+
+ GSS_Init_sec_context initiate outbound security context
+ GSS_Accept_sec_context accept inbound security context
+ GSS_Delete_sec_context flush context when no longer needed
+ GSS_Process_context_token process received control token on
+ context
+ GSS_Context_time indicate validity time remaining on
+ context
+
+ PER-MESSAGE CALLS
+
+ GSS_Sign apply signature, receive as token
+ separate from message
+ GSS_Verify validate signature token along with
+ message
+ GSS_Seal sign, optionally encrypt,
+ encapsulate
+ GSS_Unseal decapsulate, decrypt if needed,
+ validate signature
+
+ SUPPORT CALLS
+
+ GSS_Display_status translate status codes to printable
+ form
+ GSS_Indicate_mechs indicate mech_types supported on
+ local system
+ GSS_Compare_name compare two names for equality
+ GSS_Display_name translate name to printable form
+ GSS_Import_name convert printable name to
+ normalized form
+ GSS_Release_name free storage of normalized-form
+ name
+ GSS_Release_buffer free storage of printable name
+ GSS_Release_oid_set free storage of OID set object
+
+
+
+
+
+
+
+Linn [Page 16]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+2.1. Credential management calls
+
+ These GSS-API calls provide functions related to the management of
+ credentials. Their characterization with regard to whether or not
+ they may block pending exchanges with other network entities (e.g.,
+ directories or authentication servers) depends in part on OS-specific
+ (extra-GSS-API) issues, so is not specified in this document.
+
+ The GSS_Acquire_cred() call is defined within the GSS-API in support
+ of application portability, with a particular orientation towards
+ support of portable server applications. It is recognized that (for
+ certain systems and mechanisms) credentials for interactive users may
+ be managed differently from credentials for server processes; in such
+ environments, it is the GSS-API implementation's responsibility to
+ distinguish these cases and the procedures for making this
+ distinction are a local matter. The GSS_Release_cred() call provides
+ a means for callers to indicate to the GSS-API that use of a
+ credentials structure is no longer required. The GSS_Inquire_cred()
+ call allows callers to determine information about a credentials
+ structure.
+
+2.1.1. GSS_Acquire_cred call
+
+ Inputs:
+
+ o desired_name INTERNAL NAME, -NULL requests locally-determined
+ default
+
+ o lifetime_req INTEGER,-in seconds; 0 requests default
+
+ o desired_mechs SET OF OBJECT IDENTIFIER,-empty set requests
+ system-selected default
+
+ o cred_usage INTEGER-0=INITIATE-AND-ACCEPT, 1=INITIATE-ONLY,
+ 2=ACCEPT-ONLY
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_cred_handle OCTET STRING,
+
+ o actual_mechs SET OF OBJECT IDENTIFIER,
+
+ o lifetime_rec INTEGER -in seconds, or reserved value for
+ INDEFINITE
+
+
+
+Linn [Page 17]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that requested credentials were
+ successfully established, for the duration indicated in
+ lifetime_rec, suitable for the usage requested in cred_usage, for
+ the set of mech_types indicated in actual_mechs, and that those
+ credentials can be referenced for subsequent use with the handle
+ returned in output_cred_handle.
+
+ o GSS_BAD_MECH indicates that a mech_type unsupported by the GSS-API
+ implementation type was requested, causing the credential
+ establishment operation to fail.
+
+ o GSS_BAD_NAMETYPE indicates that the provided desired_name is
+ uninterpretable or of a type unsupported by the supporting GSS-API
+ implementation, so no credentials could be established for the
+ accompanying desired_name.
+
+ o GSS_BAD_NAME indicates that the provided desired_name is
+ inconsistent in terms of internally-incorporated type specifier
+ information, so no credentials could be established for the
+ accompanying desired_name.
+
+ o GSS_FAILURE indicates that credential establishment failed for
+ reasons unspecified at the GSS-API level, including lack of
+ authorization to establish and use credentials associated with the
+ identity named in the input desired_name argument.
+
+ GSS_Acquire_cred() is used to acquire credentials so that a
+ principal can (as a function of the input cred_usage parameter)
+ initiate and/or accept security contexts under the identity
+ represented by the desired_name input argument. On successful
+ completion, the returned output_cred_handle result provides a handle
+ for subsequent references to the acquired credentials. Typically,
+ single-user client processes using only default credentials for
+ context establishment purposes will have no need to invoke this call.
+
+ A caller may provide the value NULL for desired_name, signifying a
+ request for credentials corresponding to a default principal
+ identity. The procedures used by GSS-API implementations to select
+ the appropriate principal identity in response to this form of
+ request are local matters. It is possible that multiple pre-
+ established credentials may exist for the same principal identity
+ (for example, as a result of multiple user login sessions) when
+ GSS_Acquire_cred() is called; the means used in such cases to select
+ a specific credential are local matters. The input lifetime_req
+ argument to GSS_Acquire_cred() may provide useful information for
+ local GSS-API implementations to employ in making this disambiguation
+
+
+
+Linn [Page 18]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ in a manner which will best satisfy a caller's intent.
+
+ The lifetime_rec result indicates the length of time for which the
+ acquired credentials will be valid, as an offset from the present. A
+ mechanism may return a reserved value indicating INDEFINITE if no
+ constraints on credential lifetime are imposed. A caller of
+ GSS_Acquire_cred() can request a length of time for which acquired
+ credentials are to be valid (lifetime_req argument), beginning at the
+ present, or can request credentials with a default validity interval.
+ (Requests for postdated credentials are not supported within the
+ GSS-API.) Certain mechanisms and implementations may bind in
+ credential validity period specifiers at a point preliminary to
+ invocation of the GSS_Acquire_cred() call (e.g., in conjunction with
+ user login procedures). As a result, callers requesting non-default
+ values for lifetime_req must recognize that such requests cannot
+ always be honored and must be prepared to accommodate the use of
+ returned credentials with different lifetimes as indicated in
+ lifetime_rec.
+
+ The caller of GSS_Acquire_cred() can explicitly specify a set of
+ mech_types which are to be accommodated in the returned credentials
+ (desired_mechs argument), or can request credentials for a system-
+ defined default set of mech_types. Selection of the system-specified
+ default set is recommended in the interests of application
+ portability. The actual_mechs return value may be interrogated by the
+ caller to determine the set of mechanisms with which the returned
+ credentials may be used.
+
+2.1.2. GSS_Release_cred call
+
+ Input:
+
+ o cred_handle OCTET STRING-NULL specifies default credentials
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that the credentials referenced by the
+ input cred_handle were released for purposes of subsequent access
+ by the caller. The effect on other processes which may be
+ authorized shared access to such credentials is a local matter.
+
+
+
+
+
+Linn [Page 19]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o GSS_NO_CRED indicates that no release operation was performed,
+ either because the input cred_handle was invalid or because the
+ caller lacks authorization to access the referenced credentials.
+
+ o GSS_FAILURE indicates that the release operation failed for
+ reasons unspecified at the GSS-API level.
+
+ Provides a means for a caller to explicitly request that credentials
+ be released when their use is no longer required. Note that system-
+ specific credential management functions are also likely to exist,
+ for example to assure that credentials shared among processes are
+ properly deleted when all affected processes terminate, even if no
+ explicit release requests are issued by those processes. Given the
+ fact that multiple callers are not precluded from gaining authorized
+ access to the same credentials, invocation of GSS_Release_cred()
+ cannot be assumed to delete a particular set of credentials on a
+ system-wide basis.
+
+2.1.3. GSS_Inquire_cred call
+
+ Input:
+
+ o cred_handle OCTET STRING -NULL specifies default credentials
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o cred_name INTERNAL NAME,
+
+ o lifetime_rec INTEGER -in seconds, or reserved value for
+ INDEFINITE
+
+ o cred_usage INTEGER, -0=INITIATE-AND-ACCEPT, 1=INITIATE-ONLY,
+ 2=ACCEPT-ONLY
+
+ o mech_set SET OF OBJECT IDENTIFIER
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that the credentials referenced by the
+ input cred_handle argument were valid, and that the output
+ cred_name, lifetime_rec, and cred_usage values represent,
+ respectively, the credentials' associated principal name,
+ remaining lifetime, suitable usage modes, and supported
+ mechanism types.
+
+
+
+Linn [Page 20]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o GSS_NO_CRED indicates that no information could be returned
+ about the referenced credentials, either because the input
+ cred_handle was invalid or because the caller lacks
+ authorization to access the referenced credentials.
+
+ o GSS_FAILURE indicates that the release operation failed for
+ reasons unspecified at the GSS-API level.
+
+ The GSS_Inquire_cred() call is defined primarily for the use of
+ those callers which make use of default credentials rather than
+ acquiring credentials explicitly with GSS_Acquire_cred(). It enables
+ callers to determine a credential structure's associated principal
+ name, remaining validity period, usability for security context
+ initiation and/or acceptance, and supported mechanisms.
+
+2.2. Context-level calls
+
+ This group of calls is devoted to the establishment and management of
+ security contexts between peers. A context's initiator calls
+ GSS_Init_sec_context(), resulting in generation of a token which the
+ caller passes to the target. At the target, that token is passed to
+ GSS_Accept_sec_context(). Depending on the underlying mech_type and
+ specified options, additional token exchanges may be performed in the
+ course of context establishment; such exchanges are accommodated by
+ GSS_CONTINUE_NEEDED status returns from GSS_Init_sec_context() and
+ GSS_Accept_sec_context(). Either party to an established context may
+ invoke GSS_Delete_sec_context() to flush context information when a
+ context is no longer required. GSS_Process_context_token() is used
+ to process received tokens carrying context-level control
+ information. GSS_Context_time() allows a caller to determine the
+ length of time for which an established context will remain valid.
+
+2.2.1. GSS_Init_sec_context call
+
+ Inputs:
+
+ o claimant_cred_handle OCTET STRING, -NULL specifies "use
+ default"
+
+ o input_context_handle INTEGER, -0 specifies "none assigned
+ yet"
+
+ o targ_name INTERNAL NAME,
+
+ o mech_type OBJECT IDENTIFIER, -NULL parameter specifies "use
+ default"
+
+ o deleg_req_flag BOOLEAN,
+
+
+
+Linn [Page 21]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o mutual_req_flag BOOLEAN,
+
+ o replay_det_req_flag BOOLEAN,
+
+ o sequence_req_flag BOOLEAN,
+
+ o lifetime_req INTEGER,-0 specifies default lifetime
+
+ o chan_bindings OCTET STRING,
+
+ o input_token OCTET STRING-NULL or token received from target
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_context_handle INTEGER,
+
+ o mech_type OBJECT IDENTIFIER, -actual mechanism always
+ indicated, never NULL
+
+ o output_token OCTET STRING, -NULL or token to pass to context
+ target
+
+ o deleg_state BOOLEAN,
+
+ o mutual_state BOOLEAN,
+
+ o replay_det_state BOOLEAN,
+
+ o sequence_state BOOLEAN,
+
+ o conf_avail BOOLEAN,
+
+ o integ_avail BOOLEAN,
+
+ o lifetime_rec INTEGER - in seconds, or reserved value for
+ INDEFINITE
+
+ This call may block pending network interactions for those mech_types
+ in which an authentication server or other network entity must be
+ consulted on behalf of a context initiator in order to generate an
+ output_token suitable for presentation to a specified target.
+
+ Return major_status codes:
+
+
+
+
+Linn [Page 22]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o GSS_COMPLETE indicates that context-level information was
+ successfully initialized, and that the returned output_token will
+ provide sufficient information for the target to perform per-
+ message processing on the newly-established context.
+
+ o GSS_CONTINUE_NEEDED indicates that control information in the
+ returned output_token must be sent to the target, and that a reply
+ must be received and passed as the input_token argument to a
+ continuation call to GSS_Init_sec_context(), before per-message
+ processing can be performed in conjunction with this context.
+
+ o GSS_DEFECTIVE_TOKEN indicates that consistency checks performed on
+ the input_token failed, preventing further processing from being
+ performed based on that token.
+
+ o GSS_DEFECTIVE_CREDENTIAL indicates that consistency checks
+ performed on the credential structure referenced by
+ claimant_cred_handle failed, preventing further processing from
+ being performed using that credential structure.
+
+ o GSS_BAD_SIG indicates that the received input_token contains an
+ incorrect signature, so context setup cannot be accomplished.
+
+ o GSS_NO_CRED indicates that no context was established, either
+ because the input cred_handle was invalid, because the referenced
+ credentials are valid for context acceptor use only, or because
+ the caller lacks authorization to access the referenced
+ credentials.
+
+ o GSS_CREDENTIALS_EXPIRED indicates that the credentials provided
+ through the input claimant_cred_handle argument are no longer
+ valid, so context establishment cannot be completed.
+
+ o GSS_BAD_BINDINGS indicates that a mismatch between the caller-
+ provided chan_bindings and those extracted from the input_token
+ was detected, signifying a security-relevant event and preventing
+ context establishment. (This result will be returned by
+ GSS_Init_sec_context only for contexts where mutual_state is
+ TRUE.)
+
+ o GSS_NO_CONTEXT indicates that no valid context was recognized for
+ the input context_handle provided; this major status will be
+ returned only for successor calls following GSS_CONTINUE_NEEDED
+ status returns.
+
+ o GSS_BAD_NAMETYPE indicates that the provided targ_name is of a
+ type uninterpretable or unsupported by the supporting GSS-API
+ implementation, so context establishment cannot be completed.
+
+
+
+Linn [Page 23]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o GSS_BAD_NAME indicates that the provided targ_name is inconsistent
+ in terms of internally-incorporated type specifier information, so
+ context establishment cannot be accomplished.
+
+ o GSS_FAILURE indicates that context setup could not be accomplished
+ for reasons unspecified at the GSS-API level, and that no
+ interface-defined recovery action is available.
+
+ This routine is used by a context initiator, and ordinarily emits one
+ (or, for the case of a multi-step exchange, more than one)
+ output_token suitable for use by the target within the selected
+ mech_type's protocol. Using information in the credentials structure
+ referenced by claimant_cred_handle, GSS_Init_sec_context()
+ initializes the data structures required to establish a security
+ context with target targ_name. The claimant_cred_handle must
+ correspond to the same valid credentials structure on the initial
+ call to GSS_Init_sec_context() and on any successor calls resulting
+ from GSS_CONTINUE_NEEDED status returns; different protocol sequences
+ modeled by the GSS_CONTINUE_NEEDED mechanism will require access to
+ credentials at different points in the context establishment
+ sequence.
+
+ The input_context_handle argument is 0, specifying "not yet
+ assigned", on the first GSS_Init_sec_context() call relating to a
+ given context. That call returns an output_context_handle for future
+ references to this context. When continuation attempts to
+ GSS_Init_sec_context() are needed to perform context establishment,
+ the previously-returned non-zero handle value is entered into the
+ input_context_handle argument and will be echoed in the returned
+ output_context_handle argument. On such continuation attempts (and
+ only on continuation attempts) the input_token value is used, to
+ provide the token returned from the context's target.
+
+ The chan_bindings argument is used by the caller to provide
+ information binding the security context to security-related
+ characteristics (e.g., addresses, cryptographic keys) of the
+ underlying communications channel. See Section 1.1.6 of this document
+ for more discussion of this argument's usage.
+
+ The input_token argument contains a message received from the target,
+ and is significant only on a call to GSS_Init_sec_context() which
+ follows a previous return indicating GSS_CONTINUE_NEEDED
+ major_status.
+
+ It is the caller's responsibility to establish a communications path
+ to the target, and to transmit any returned output_token (independent
+ of the accompanying returned major_status value) to the target over
+ that path. The output_token can, however, be transmitted along with
+
+
+
+Linn [Page 24]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ the first application-provided input message to be processed by
+ GSS_Sign() or GSS_Seal() in conjunction with a successfully-
+ established context.
+
+ The initiator may request various context-level functions through
+ input flags: the deleg_req_flag requests delegation of access rights,
+ the mutual_req_flag requests mutual authentication, the
+ replay_det_req_flag requests that replay detection features be
+ applied to messages transferred on the established context, and the
+ sequence_req_flag requests that sequencing be enforced. (See Section
+ 1.2.3 for more information on replay detection and sequencing
+ features.)
+
+ Not all of the optionally-requestable features will be available in
+ all underlying mech_types; the corresponding return state values
+ (deleg_state, mutual_state, replay_det_state, sequence_state)
+ indicate, as a function of mech_type processing capabilities and
+ initiator-provided input flags, the set of features which will be
+ active on the context. These state indicators' values are undefined
+ unless the routine's major_status indicates COMPLETE. Failure to
+ provide the precise set of features requested by the caller does not
+ cause context establishment to fail; it is the caller's prerogative
+ to delete the context if the feature set provided is unsuitable for
+ the caller's use. The returned mech_type value indicates the
+ specific mechanism employed on the context, and will never indicate
+ the value for "default".
+
+ The conf_avail return value indicates whether the context supports
+ per-message confidentiality services, and so informs the caller
+ whether or not a request for encryption through the conf_req_flag
+ input to GSS_Seal() can be honored. In similar fashion, the
+ integ_avail return value indicates whether per-message integrity
+ services are available (through either GSS_Sign() or GSS_Seal()) on
+ the established context.
+
+ The lifetime_req input specifies a desired upper bound for the
+ lifetime of the context to be established, with a value of 0 used to
+ request a default lifetime. The lifetime_rec return value indicates
+ the length of time for which the context will be valid, expressed as
+ an offset from the present; depending on mechanism capabilities,
+ credential lifetimes, and local policy, it may not correspond to the
+ value requested in lifetime_req. If no constraints on context
+ lifetime are imposed, this may be indicated by returning a reserved
+ value representing INDEFINITE lifetime_req. The values of conf_avail,
+ integ_avail, and lifetime_rec are undefined unless the routine's
+ major_status indicates COMPLETE.
+
+ If the mutual_state is TRUE, this fact will be reflected within the
+
+
+
+Linn [Page 25]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ output_token. A call to GSS_Accept_sec_context() at the target in
+ conjunction with such a context will return a token, to be processed
+ by a continuation call to GSS_Init_sec_context(), in order to achieve
+ mutual authentication.
+
+2.2.2. GSS_Accept_sec_context call
+
+ Inputs:
+
+ o acceptor_cred_handle OCTET STRING,-NULL specifies "use
+ default"
+
+ o input_context_handle INTEGER, -0 specifies "not yet assigned"
+
+ o chan_bindings OCTET STRING,
+
+ o input_token OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o src_name INTERNAL NAME,
+
+ o mech_type OBJECT IDENTIFIER,
+
+ o output_context_handle INTEGER,
+
+ o deleg_state BOOLEAN,
+
+ o mutual_state BOOLEAN,
+
+ o replay_det_state BOOLEAN,
+
+ o sequence_state BOOLEAN,
+
+ o conf_avail BOOLEAN,
+
+ o integ_avail BOOLEAN,
+
+ o lifetime_rec INTEGER, - in seconds, or reserved value for
+ INDEFINITE
+
+ o delegated_cred_handle OCTET STRING,
+
+ o output_token OCTET STRING -NULL or token to pass to context
+
+
+
+Linn [Page 26]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ initiator
+
+ This call may block pending network interactions for those mech_types
+ in which a directory service or other network entity must be
+ consulted on behalf of a context acceptor in order to validate a
+ received input_token.
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that context-level data structures were
+ successfully initialized, and that per-message processing can now
+ be performed in conjunction with this context.
+
+ o GSS_CONTINUE_NEEDED indicates that control information in the
+ returned output_token must be sent to the initiator, and that a
+ response must be received and passed as the input_token argument
+ to a continuation call to GSS_Accept_sec_context(), before per-
+ message processing can be performed in conjunction with this
+ context.
+
+ o GSS_DEFECTIVE_TOKEN indicates that consistency checks performed on
+ the input_token failed, preventing further processing from being
+ performed based on that token.
+
+ o GSS_DEFECTIVE_CREDENTIAL indicates that consistency checks
+ performed on the credential structure referenced by
+ acceptor_cred_handle failed, preventing further processing from
+ being performed using that credential structure.
+
+ o GSS_BAD_SIG indicates that the received input_token contains an
+ incorrect signature, so context setup cannot be accomplished.
+
+ o GSS_DUPLICATE_TOKEN indicates that the signature on the received
+ input_token was correct, but that the input_token was recognized
+ as a duplicate of an input_token already processed. No new context
+ is established.
+
+ o GSS_OLD_TOKEN indicates that the signature on the received
+ input_token was correct, but that the input_token is too old to be
+ checked for duplication against previously-processed input_tokens.
+ No new context is established.
+
+ o GSS_NO_CRED indicates that no context was established, either
+ because the input cred_handle was invalid, because the referenced
+ credentials are valid for context initiator use only, or because
+ the caller lacks authorization to access the referenced
+ credentials.
+
+
+
+
+Linn [Page 27]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o GSS_CREDENTIALS_EXPIRED indicates that the credentials provided
+ through the input acceptor_cred_handle argument are no longer
+ valid, so context establishment cannot be completed.
+
+ o GSS_BAD_BINDINGS indicates that a mismatch between the caller-
+ provided chan_bindings and those extracted from the input_token
+ was detected, signifying a security-relevant event and preventing
+ context establishment.
+
+ o GSS_NO_CONTEXT indicates that no valid context was recognized for
+ the input context_handle provided; this major status will be
+ returned only for successor calls following GSS_CONTINUE_NEEDED
+ status returns.
+
+ o GSS_FAILURE indicates that context setup could not be accomplished
+ for reasons unspecified at the GSS-API level, and that no
+ interface-defined recovery action is available.
+
+ The GSS_Accept_sec_context() routine is used by a context target.
+ Using information in the credentials structure referenced by the
+ input acceptor_cred_handle, it verifies the incoming input_token and
+ (following the successful completion of a context establishment
+ sequence) returns the authenticated src_name and the mech_type used.
+ The acceptor_cred_handle must correspond to the same valid
+ credentials structure on the initial call to GSS_Accept_sec_context()
+ and on any successor calls resulting from GSS_CONTINUE_NEEDED status
+ returns; different protocol sequences modeled by the
+ GSS_CONTINUE_NEEDED mechanism will require access to credentials at
+ different points in the context establishment sequence.
+
+ The input_context_handle argument is 0, specifying "not yet
+ assigned", on the first GSS_Accept_sec_context() call relating to a
+ given context. That call returns an output_context_handle for future
+ references to this context; when continuation attempts to
+ GSS_Accept_sec_context() are needed to perform context
+ establishment, that handle value will be entered into the
+ input_context_handle argument.
+
+ The chan_bindings argument is used by the caller to provide
+ information binding the security context to security-related
+ characteristics (e.g., addresses, cryptographic keys) of the
+ underlying communications channel. See Section 1.1.6 of this document
+ for more discussion of this argument's usage.
+
+ The returned state results (deleg_state, mutual_state,
+ replay_det_state, and sequence_state) reflect the same context state
+ values as returned to GSS_Init_sec_context()'s caller at the
+ initiator system.
+
+
+
+Linn [Page 28]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ The conf_avail return value indicates whether the context supports
+ per-message confidentiality services, and so informs the caller
+ whether or not a request for encryption through the conf_req_flag
+ input to GSS_Seal() can be honored. In similar fashion, the
+ integ_avail return value indicates whether per-message integrity
+ services are available (through either GSS_Sign() or GSS_Seal()) on
+ the established context.
+
+ The lifetime_rec return value indicates the length of time for which
+ the context will be valid, expressed as an offset from the present.
+ The values of deleg_state, mutual_state, replay_det_state,
+ sequence_state, conf_avail, integ_avail, and lifetime_rec are
+ undefined unless the accompanying major_status indicates COMPLETE.
+
+ The delegated_cred_handle result is significant only when deleg_state
+ is TRUE, and provides a means for the target to reference the
+ delegated credentials. The output_token result, when non-NULL,
+ provides a context-level token to be returned to the context
+ initiator to continue a multi-step context establishment sequence. As
+ noted with GSS_Init_sec_context(), any returned token should be
+ transferred to the context's peer (in this case, the context
+ initiator), independent of the value of the accompanying returned
+ major_status.
+
+ Note: A target must be able to distinguish a context-level
+ input_token, which is passed to GSS_Accept_sec_context(), from the
+ per-message data elements passed to GSS_Verify() or GSS_Unseal().
+ These data elements may arrive in a single application message, and
+ GSS_Accept_sec_context() must be performed before per-message
+ processing can be performed successfully.
+
+2.2.3. GSS_Delete_sec_context call
+
+ Input:
+
+ o context_handle INTEGER
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_context_token OCTET STRING
+
+ Return major_status codes:
+
+
+
+
+
+Linn [Page 29]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o GSS_COMPLETE indicates that the context was recognized, that
+ relevant context-specific information was flushed, and that the
+ returned output_context_token is ready for transfer to the
+ context's peer.
+
+ o GSS_NO_CONTEXT indicates that no valid context was recognized for
+ the input context_handle provide, so no deletion was performed.
+
+ o GSS_FAILURE indicates that the context is recognized, but that the
+ GSS_Delete_sec_context() operation could not be performed for
+ reasons unspecified at the GSS-API level.
+
+ This call may block pending network interactions for mech_types in
+ which active notification must be made to a central server when a
+ security context is to be deleted.
+
+ This call can be made by either peer in a security context, to flush
+ context-specific information and to return an output_context_token
+ which can be passed to the context's peer informing it that the
+ peer's corresponding context information can also be flushed. (Once a
+ context is established, the peers involved are expected to retain
+ cached credential and context-related information until the
+ information's expiration time is reached or until a
+ GSS_Delete_sec_context() call is made.) Attempts to perform per-
+ message processing on a deleted context will result in error returns.
+
+2.2.4. GSS_Process_context_token call
+
+ Inputs:
+
+ o context_handle INTEGER,
+
+ o input_context_token OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that the input_context_token was
+ successfully processed in conjunction with the context referenced
+ by context_handle.
+
+ o GSS_DEFECTIVE_TOKEN indicates that consistency checks performed on
+ the received context_token failed, preventing further processing
+
+
+
+Linn [Page 30]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ from being performed with that token.
+
+ o GSS_NO_CONTEXT indicates that no valid context was recognized for
+ the input context_handle provided.
+
+ o GSS_FAILURE indicates that the context is recognized, but that the
+ GSS_Process_context_token() operation could not be performed for
+ reasons unspecified at the GSS-API level.
+
+ This call is used to process context_tokens received from a peer once
+ a context has been established, with corresponding impact on
+ context-level state information. One use for this facility is
+ processing of the context_tokens generated by
+ GSS_Delete_sec_context(); GSS_Process_context_token() will not block
+ pending network interactions for that purpose. Another use is to
+ process tokens indicating remote-peer context establishment failures
+ after the point where the local GSS-API implementation has already
+ indicated GSS_COMPLETE status.
+
+2.2.5. GSS_Context_time call
+
+ Input:
+
+ o context_handle INTEGER,
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o lifetime_rec INTEGER - in seconds, or reserved value for
+ INDEFINITE
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that the referenced context is valid, and
+ will remain valid for the amount of time indicated in
+ lifetime_rec.
+
+ o GSS_CONTEXT_EXPIRED indicates that data items related to the
+ referenced context have expired.
+
+ o GSS_CREDENTIALS_EXPIRED indicates that the context is recognized,
+ but that its associated credentials have expired.
+
+ o GSS_NO_CONTEXT indicates that no valid context was recognized for
+ the input context_handle provided.
+
+
+
+Linn [Page 31]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o GSS_FAILURE indicates that the requested operation failed for
+ reasons unspecified at the GSS-API level.
+
+ This call is used to determine the amount of time for which a
+ currently established context will remain valid.
+
+2.3. Per-message calls
+
+ This group of calls is used to perform per-message protection
+ processing on an established security context. None of these calls
+ block pending network interactions. These calls may be invoked by a
+ context's initiator or by the context's target. The four members of
+ this group should be considered as two pairs; the output from
+ GSS_Sign() is properly input to GSS_Verify(), and the output from
+ GSS_Seal() is properly input to GSS_Unseal().
+
+ GSS_Sign() and GSS_Verify() support data origin authentication and
+ data integrity services. When GSS_Sign() is invoked on an input
+ message, it yields a per-message token containing data items which
+ allow underlying mechanisms to provide the specified security
+ services. The original message, along with the generated per-message
+ token, is passed to the remote peer; these two data elements are
+ processed by GSS_Verify(), which validates the message in
+ conjunction with the separate token.
+
+ GSS_Seal() and GSS_Unseal() support caller-requested confidentiality
+ in addition to the data origin authentication and data integrity
+ services offered by GSS_Sign() and GSS_Verify(). GSS_Seal() outputs
+ a single data element, encapsulating optionally enciphered user data
+ as well as associated token data items. The data element output from
+ GSS_Seal() is passed to the remote peer and processed by
+ GSS_Unseal() at that system. GSS_Unseal() combines decipherment (as
+ required) with validation of data items related to authentication and
+ integrity.
+
+2.3.1. GSS_Sign call
+
+ Inputs:
+
+ o context_handle INTEGER,
+
+ o qop_req INTEGER,-0 specifies default QOP
+
+ o message OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+
+
+Linn [Page 32]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o minor_status INTEGER,
+
+ o per_msg_token OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that a signature, suitable for an
+ established security context, was successfully applied and that
+ the message and corresponding per_msg_token are ready for
+ transmission.
+
+ o GSS_CONTEXT_EXPIRED indicates that context-related data items have
+ expired, so that the requested operation cannot be performed.
+
+ o GSS_CREDENTIALS_EXPIRED indicates that the context is recognized,
+ but that its associated credentials have expired, so that the
+ requested operation cannot be performed.
+
+ o GSS_NO_CONTEXT indicates that no valid context was recognized for
+ the input context_handle provided.
+
+ o GSS_FAILURE indicates that the context is recognized, but that the
+ requested operation could not be performed for reasons unspecified
+ at the GSS-API level.
+
+ Using the security context referenced by context_handle, apply a
+ signature to the input message (along with timestamps and/or other
+ data included in support of mech_type-specific mechanisms) and return
+ the result in per_msg_token. The qop_req parameter allows quality-
+ of-protection control. The caller passes the message and the
+ per_msg_token to the target.
+
+ The GSS_Sign() function completes before the message and
+ per_msg_token is sent to the peer; successful application of
+ GSS_Sign() does not guarantee that a corresponding GSS_Verify() has
+ been (or can necessarily be) performed successfully when the message
+ arrives at the destination.
+
+2.3.2. GSS_Verify call
+
+ Inputs:
+
+ o context_handle INTEGER,
+
+ o message OCTET STRING,
+
+ o per_msg_token OCTET STRING
+
+
+
+
+Linn [Page 33]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ Outputs:
+
+ o qop_state INTEGER,
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that the message was successfully verified.
+
+ o GSS_DEFECTIVE_TOKEN indicates that consistency checks performed on
+ the received per_msg_token failed, preventing further processing
+ from being performed with that token.
+
+ o GSS_BAD_SIG indicates that the received per_msg_token contains an
+ incorrect signature for the message.
+
+ o GSS_DUPLICATE_TOKEN, GSS_OLD_TOKEN, and GSS_UNSEQ_TOKEN values
+ appear in conjunction with the optional per-message replay
+ detection features described in Section 1.2.3; their semantics are
+ described in that section.
+
+ o GSS_CONTEXT_EXPIRED indicates that context-related data items have
+ expired, so that the requested operation cannot be performed.
+
+ o GSS_CREDENTIALS_EXPIRED indicates that the context is recognized,
+ but that its associated credentials have expired, so that the
+ requested operation cannot be performed.
+
+ o GSS_NO_CONTEXT indicates that no valid context was recognized for
+ the input context_handle provided.
+
+ o GSS_FAILURE indicates that the context is recognized, but that the
+ GSS_Verify() operation could not be performed for reasons
+ unspecified at the GSS-API level.
+
+ Using the security context referenced by context_handle, verify that
+ the input per_msg_token contains an appropriate signature for the
+ input message, and apply any active replay detection or sequencing
+ features. Return an indication of the quality-of-protection applied
+ to the processed message in the qop_state result.
+
+
+
+
+
+
+
+
+Linn [Page 34]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+2.3.3. GSS_Seal call
+
+ Inputs:
+
+ o context_handle INTEGER,
+
+ o conf_req_flag BOOLEAN,
+
+ o qop_req INTEGER,-0 specifies default QOP
+
+ o input_message OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o conf_state BOOLEAN,
+
+ o output_message OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that the input_message was successfully
+ processed and that the output_message is ready for transmission.
+
+ o GSS_CONTEXT_EXPIRED indicates that context-related data items have
+ expired, so that the requested operation cannot be performed.
+
+ o GSS_CREDENTIALS_EXPIRED indicates that the context is recognized,
+ but that its associated credentials have expired, so that the
+ requested operation cannot be performed.
+
+ o GSS_NO_CONTEXT indicates that no valid context was recognized for
+ the input context_handle provided.
+
+ o GSS_FAILURE indicates that the context is recognized, but that the
+ GSS_Seal() operation could not be performed for reasons
+ unspecified at the GSS-API level.
+
+ Performs the data origin authentication and data integrity functions
+ of GSS_Sign(). If the input conf_req_flag is TRUE, requests that
+ confidentiality be applied to the input_message. Confidentiality may
+ not be supported in all mech_types or by all implementations; the
+ returned conf_state flag indicates whether confidentiality was
+ provided for the input_message. The qop_req parameter allows
+ quality-of-protection control.
+
+
+
+Linn [Page 35]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ In all cases, the GSS_Seal() call yields a single output_message
+ data element containing (optionally enciphered) user data as well as
+ control information.
+
+2.3.4. GSS_Unseal call
+
+ Inputs:
+
+ o context_handle INTEGER,
+
+ o input_message OCTET STRING
+
+ Outputs:
+
+ o conf_state BOOLEAN,
+
+ o qop_state INTEGER,
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_message OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that the input_message was successfully
+ processed and that the resulting output_message is available.
+
+ o GSS_DEFECTIVE_TOKEN indicates that consistency checks performed on
+ the per_msg_token extracted from the input_message failed,
+ preventing further processing from being performed.
+
+ o GSS_BAD_SIG indicates that an incorrect signature was detected for
+ the message.
+
+ o GSS_DUPLICATE_TOKEN, GSS_OLD_TOKEN, and GSS_UNSEQ_TOKEN values
+ appear in conjunction with the optional per-message replay
+ detection features described in Section 1.2.3; their semantics are
+ described in that section.
+
+ o GSS_CONTEXT_EXPIRED indicates that context-related data items have
+ expired, so that the requested operation cannot be performed.
+
+ o GSS_CREDENTIALS_EXPIRED indicates that the context is recognized,
+ but that its associated credentials have expired, so that the
+ requested operation cannot be performed.
+
+
+
+
+Linn [Page 36]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o GSS_NO_CONTEXT indicates that no valid context was recognized for
+ the input context_handle provided.
+
+ o GSS_FAILURE indicates that the context is recognized, but that the
+ GSS_Unseal() operation could not be performed for reasons
+ unspecified at the GSS-API level.
+
+ Processes a data element generated (and optionally enciphered) by
+ GSS_Seal(), provided as input_message. The returned conf_state value
+ indicates whether confidentiality was applied to the input_message.
+ If conf_state is TRUE, GSS_Unseal() deciphers the input_message.
+ Returns an indication of the quality-of-protection applied to the
+ processed message in the qop_state result. GSS_Seal() performs the
+ data integrity and data origin authentication checking functions of
+ GSS_Verify() on the plaintext data. Plaintext data is returned in
+ output_message.
+
+2.4. Support calls
+
+ This group of calls provides support functions useful to GSS-API
+ callers, independent of the state of established contexts. Their
+ characterization with regard to blocking or non-blocking status in
+ terms of network interactions is unspecified.
+
+2.4.1. GSS_Display_status call
+
+ Inputs:
+
+ o status_value INTEGER,-GSS-API major_status or minor_status
+ return value
+
+ o status_type INTEGER,-1 if major_status, 2 if minor_status
+
+ o mech_type OBJECT IDENTIFIER-mech_type to be used for minor_
+ status translation
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o status_string_set SET OF OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that a valid printable status
+ representation (possibly representing more than one status event
+
+
+
+Linn [Page 37]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ encoded within the status_value) is available in the returned
+ status_string_set.
+
+ o GSS_BAD_MECH indicates that translation in accordance with an
+ unsupported mech_type was requested, so translation could not be
+ performed.
+
+ o GSS_BAD_STATUS indicates that the input status_value was invalid,
+ or that the input status_type carried a value other than 1 or 2,
+ so translation could not be performed.
+
+ o GSS_FAILURE indicates that the requested operation could not be
+ performed for reasons unspecified at the GSS-API level.
+
+ Provides a means for callers to translate GSS-API-returned major and
+ minor status codes into printable string representations.
+
+2.4.2. GSS_Indicate_mechs call
+
+ Input:
+
+ o (none)
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o mech_set SET OF OBJECT IDENTIFIER
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that a set of available mechanisms has
+ been returned in mech_set.
+
+ o GSS_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to determine the set of mechanism types available on
+ the local system. This call is intended for support of specialized
+ callers who need to request non-default mech_type sets from
+ GSS_Acquire_cred(), and should not be needed by other callers.
+
+2.4.3. GSS_Compare_name call
+
+ Inputs:
+
+
+
+
+Linn [Page 38]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o name1 INTERNAL NAME,
+
+ o name2 INTERNAL NAME
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o name_equal BOOLEAN
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that name1 and name2 were comparable, and
+ that the name_equal result indicates whether name1 and name2 were
+ equal or unequal.
+
+ o GSS_BAD_NAMETYPE indicates that one or both of name1 and name2
+ contained internal type specifiers uninterpretable by the
+ supporting GSS-API implementation, or that the two names' types
+ are different and incomparable, so the equality comparison could
+ not be completed.
+
+ o GSS_BAD_NAME indicates that one or both of the input names was
+ ill-formed in terms of its internal type specifier, so the
+ equality comparison could not be completed.
+
+ o GSS_FAILURE indicates that the requested operation could not be
+ performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to compare two internal name representations for
+ equality.
+
+2.4.4. GSS_Display_name call
+
+ Inputs:
+
+ o name INTERNAL NAME
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o name_string OCTET STRING,
+
+
+
+
+Linn [Page 39]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o name_type OBJECT IDENTIFIER
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that a valid printable name representation
+ is available in the returned name_string.
+
+ o GSS_BAD_NAMETYPE indicates that the provided name was of a type
+ uninterpretable by the supporting GSS-API implementation, so no
+ printable representation could be generated.
+
+ o GSS_BAD_NAME indicates that the contents of the provided name were
+ inconsistent with the internally-indicated name type, so no
+ printable representation could be generated.
+
+ o GSS_FAILURE indicates that the requested operation could not be
+ performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to translate an internal name representation into a
+ printable form with associated namespace type descriptor. The syntax
+ of the printable form is a local matter.
+
+2.4.5. GSS_Import_name call
+
+ Inputs:
+
+ o input_name_string OCTET STRING,
+
+ o input_name_type OBJECT IDENTIFIER
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_name INTERNAL NAME
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that a valid name representation is output
+ in output_name and described by the type value in
+ output_name_type.
+
+ o GSS_BAD_NAMETYPE indicates that the input_name_type is unsupported
+ by the GSS-API implementation, so the import operation could not
+ be completed.
+
+
+
+
+Linn [Page 40]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o GSS_BAD_NAME indicates that the provided input_name_string is
+ ill-formed in terms of the input_name_type, so the import
+ operation could not be completed.
+
+ o GSS_FAILURE indicates that the requested operation could not be
+ performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to provide a printable name representation, designate
+ the type of namespace in conjunction with which it should be parsed,
+ and convert that printable representation to an internal form
+ suitable for input to other GSS-API routines. The syntax of the
+ input_name is a local matter.
+
+2.4.6. GSS_Release_name call
+
+ Inputs:
+
+ o name INTERNAL NAME
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that the storage associated with the input
+ name was successfully released.
+
+ o GSS_BAD_NAME indicates that the input name argument did not
+ contain a valid name.
+
+ o GSS_FAILURE indicates that the requested operation could not be
+ performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to release the storage associated with an internal
+ name representation.
+
+2.4.7. GSS_Release_buffer call
+
+ Inputs:
+
+ o buffer OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+
+
+Linn [Page 41]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ o minor_status INTEGER
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that the storage associated with the input
+ buffer was successfully released.
+
+ o GSS_FAILURE indicates that the requested operation could not be
+ performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to release the storage associated with an OCTET STRING
+ buffer allocated by another GSS-API call.
+
+2.4.8. GSS_Release_oid_set call
+
+ Inputs:
+
+ o buffer SET OF OBJECT IDENTIFIER
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER
+
+ Return major_status codes:
+
+ o GSS_COMPLETE indicates that the storage associated with the input
+ object identifier set was successfully released.
+
+ o GSS_FAILURE indicates that the requested operation could not be
+ performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to release the storage associated with an object
+ identifier set object allocated by another GSS-API call.
+
+3. Mechanism-Specific Example Scenarios
+
+ This section provides illustrative overviews of the use of various
+ candidate mechanism types to support the GSS-API. These discussions
+ are intended primarily for readers familiar with specific security
+ technologies, demonstrating how GSS-API functions can be used and
+ implemented by candidate underlying mechanisms. They should not be
+ regarded as constrictive to implementations or as defining the only
+ means through which GSS-API functions can be realized with a
+ particular underlying technology, and do not demonstrate all GSS-API
+ features with each technology.
+
+
+
+
+Linn [Page 42]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+3.1. Kerberos V5, single-TGT
+
+ OS-specific login functions yield a TGT to the local realm Kerberos
+ server; TGT is placed in a credentials structure for the client.
+ Client calls GSS_Acquire_cred() to acquire a cred_handle in order to
+ reference the credentials for use in establishing security contexts.
+
+ Client calls GSS_Init_sec_context(). If the requested service is
+ located in a different realm, GSS_Init_sec_context() gets the
+ necessary TGT/key pairs needed to traverse the path from local to
+ target realm; these data are placed in the owner's TGT cache. After
+ any needed remote realm resolution, GSS_Init_sec_context() yields a
+ service ticket to the requested service with a corresponding session
+ key; these data are stored in conjunction with the context. GSS-API
+ code sends KRB_TGS_REQ request(s) and receives KRB_TGS_REP
+ response(s) (in the successful case) or KRB_ERROR.
+
+ Assuming success, GSS_Init_sec_context() builds a Kerberos-formatted
+ KRB_AP_REQ message, and returns it in output_token. The client sends
+ the output_token to the service.
+
+ The service passes the received token as the input_token argument to
+ GSS_Accept_sec_context(), which verifies the authenticator, provides
+ the service with the client's authenticated name, and returns an
+ output_context_handle.
+
+ Both parties now hold the session key associated with the service
+ ticket, and can use this key in subsequent GSS_Sign(), GSS_Verify(),
+ GSS_Seal(), and GSS_Unseal() operations.
+
+3.2. Kerberos V5, double-TGT
+
+ TGT acquisition as above.
+
+ Note: To avoid unnecessary frequent invocations of error paths when
+ implementing the GSS-API atop Kerberos V5, it seems appropriate to
+ represent "single-TGT K-V5" and "double-TGT K-V5" with separate
+ mech_types, and this discussion makes that assumption.
+
+ Based on the (specified or defaulted) mech_type,
+ GSS_Init_sec_context() determines that the double-TGT protocol
+ should be employed for the specified target. GSS_Init_sec_context()
+ returns GSS_CONTINUE_NEEDED major_status, and its returned
+ output_token contains a request to the service for the service's TGT.
+ (If a service TGT with suitably long remaining lifetime already
+ exists in a cache, it may be usable, obviating the need for this
+ step.) The client passes the output_token to the service. Note: this
+ scenario illustrates a different use for the GSS_CONTINUE_NEEDED
+
+
+
+Linn [Page 43]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ status return facility than for support of mutual authentication;
+ note that both uses can coexist as successive operations within a
+ single context establishment operation.
+
+ The service passes the received token as the input_token argument to
+ GSS_Accept_sec_context(), which recognizes it as a request for TGT.
+ (Note that current Kerberos V5 defines no intra-protocol mechanism to
+ represent such a request.) GSS_Accept_sec_context() returns
+ GSS_CONTINUE_NEEDED major_status and provides the service's TGT in
+ its output_token. The service sends the output_token to the client.
+
+ The client passes the received token as the input_token argument to a
+ continuation of GSS_Init_sec_context(). GSS_Init_sec_context() caches
+ the received service TGT and uses it as part of a service ticket
+ request to the Kerberos authentication server, storing the returned
+ service ticket and session key in conjunction with the context.
+ GSS_Init_sec_context() builds a Kerberos-formatted authenticator,
+ and returns it in output_token along with GSS_COMPLETE return
+ major_status. The client sends the output_token to the service.
+
+ Service passes the received token as the input_token argument to a
+ continuation call to GSS_Accept_sec_context().
+ GSS_Accept_sec_context() verifies the authenticator, provides the
+ service with the client's authenticated name, and returns
+ major_status GSS_COMPLETE.
+
+ GSS_Sign(), GSS_Verify(), GSS_Seal(), and GSS_Unseal() as above.
+
+3.3. X.509 Authentication Framework
+
+ This example illustrates use of the GSS-API in conjunction with
+ public-key mechanisms, consistent with the X.509 Directory
+ Authentication Framework.
+
+ The GSS_Acquire_cred() call establishes a credentials structure,
+ making the client's private key accessible for use on behalf of the
+ client.
+
+ The client calls GSS_Init_sec_context(), which interrogates the
+ Directory to acquire (and validate) a chain of public-key
+ certificates, thereby collecting the public key of the service. The
+ certificate validation operation determines that suitable signatures
+ were applied by trusted authorities and that those certificates have
+ not expired. GSS_Init_sec_context() generates a secret key for use
+ in per-message protection operations on the context, and enciphers
+ that secret key under the service's public key.
+
+ The enciphered secret key, along with an authenticator quantity
+
+
+
+Linn [Page 44]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ signed with the client's private key, is included in the output_token
+ from GSS_Init_sec_context(). The output_token also carries a
+ certification path, consisting of a certificate chain leading from
+ the service to the client; a variant approach would defer this path
+ resolution to be performed by the service instead of being asserted
+ by the client. The client application sends the output_token to the
+ service.
+
+ The service passes the received token as the input_token argument to
+ GSS_Accept_sec_context(). GSS_Accept_sec_context() validates the
+ certification path, and as a result determines a certified binding
+ between the client's distinguished name and the client's public key.
+ Given that public key, GSS_Accept_sec_context() can process the
+ input_token's authenticator quantity and verify that the client's
+ private key was used to sign the input_token. At this point, the
+ client is authenticated to the service. The service uses its private
+ key to decipher the enciphered secret key provided to it for per-
+ message protection operations on the context.
+
+ The client calls GSS_Sign() or GSS_Seal() on a data message, which
+ causes per-message authentication, integrity, and (optional)
+ confidentiality facilities to be applied to that message. The service
+ uses the context's shared secret key to perform corresponding
+ GSS_Verify() and GSS_Unseal() calls.
+
+4. Related Activities
+
+ In order to implement the GSS-API atop existing, emerging, and future
+ security mechanisms:
+
+ object identifiers must be assigned to candidate GSS-API
+ mechanisms and the name types which they support
+
+ concrete data element formats must be defined for candidate
+ mechanisms
+
+ Calling applications must implement formatting conventions which will
+ enable them to distinguish GSS-API tokens from other data carried in
+ their application protocols.
+
+ Concrete language bindings are required for the programming
+ environments in which the GSS-API is to be employed; such bindings
+ for the C language are available in an associated RFC.
+
+
+
+
+
+
+
+
+Linn [Page 45]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+5. Acknowledgments
+
+ This proposal is the result of a collaborative effort.
+ Acknowledgments are due to the many members of the IETF Security Area
+ Advisory Group (SAAG) and the Common Authentication Technology (CAT)
+ Working Group for their contributions at meetings and by electronic
+ mail. Acknowledgments are also due to Kannan Alagappan, Doug Barlow,
+ Bill Brown, Cliff Kahn, Charlie Kaufman, Butler Lampson, Richard
+ Pitkin, Joe Tardo, and John Wray of Digital Equipment Corporation,
+ and John Carr, John Kohl, Jon Rochlis, Jeff Schiller, and Ted T'so of
+ MIT and Project Athena. Joe Pato and Bill Sommerfeld of HP/Apollo,
+ Walt Tuvell of OSF, and Bill Griffith and Mike Merritt of AT&T,
+ provided inputs which helped to focus and clarify directions.
+ Precursor work by Richard Pitkin, presented to meetings of the
+ Trusted Systems Interoperability Group (TSIG), helped to demonstrate
+ the value of a generic, mechanism-independent security service API.
+
+6. Security Considerations
+
+ Security issues are discussed throughout this memo.
+
+7. Author's Address
+
+ John Linn
+ Geer Zolot Associates
+ One Main St.
+ Cambridge, MA 02142 USA
+
+ Phone: +1 617.374.3700
+ Email: Linn@gza.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Linn [Page 46]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+APPENDIX A
+
+PACS AND AUTHORIZATION SERVICES
+
+ Consideration has been given to modifying the GSS-API service
+ interface to recognize and manipulate Privilege Attribute
+ Certificates (PACs) as in ECMA 138, carrying authorization data as a
+ side effect of establishing a security context, but no such
+ modifications have been incorporated at this time. This appendix
+ provides rationale for this decision and discusses compatibility
+ alternatives between PACs and the GSS-API which do not require that
+ PACs be made visible to GSS-API callers.
+
+ Existing candidate mechanism types such as Kerberos and X.509 do not
+ incorporate PAC manipulation features, and exclusion of such
+ mechanisms from the set of candidates equipped to fully support the
+ GSS-API seems inappropriate. Inclusion (and GSS-API visibility) of a
+ feature supported by only a limited number of mechanisms could
+ encourage the development of ostensibly portable applications which
+ would in fact have only limited portability.
+
+ The status quo, in which PACs are not visible across the GSS-API
+ interface, does not preclude implementations in which PACs are
+ carried transparently, within the tokens defined and used for certain
+ mech_types, and stored within peers' credentials and context-level
+ data structures. While invisible to API callers, such PACs could be
+ used by operating system or other local functions as inputs in the
+ course of mediating access requests made by callers. This course of
+ action allows dynamic selection of PAC contents, if such selection is
+ administratively-directed rather than caller-directed.
+
+ In a distributed computing environment, authentication must span
+ different systems; the need for such authentication provides
+ motivation for GSS-API definition and usage. Heterogeneous systems in
+ a network can intercommunicate, with globally authenticated names
+ comprising the common bond between locally defined access control
+ policies. Access control policies to which authentication provides
+ inputs are often local, or specific to particular operating systems
+ or environments. If the GSS-API made particular authorization models
+ visible across its service interface, its scope of application would
+ become less general. The current GSS-API paradigm is consistent with
+ the precedent set by Kerberos, neither defining the interpretation of
+ authorization-related data nor enforcing access controls based on
+ such data.
+
+ The GSS-API is a general interface, whose callers may reside inside
+ or outside any defined TCB or NTCB boundaries. Given this
+ characteristic, it appears more realistic to provide facilities which
+
+
+
+Linn [Page 47]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ provide "value-added" security services to its callers than to offer
+ facilities which enforce restrictions on those callers. Authorization
+ decisions must often be mediated below the GSS-API level in a local
+ manner against (or in spite of) applications, and cannot be
+ selectively invoked or omitted at those applications' discretion.
+ Given that the GSS-API's placement prevents it from providing a
+ comprehensive solution to the authorization issue, the value of a
+ partial contribution specific to particular authorization models is
+ debatable.
+
+APPENDIX B
+
+MECHANISM-INDEPENDENT TOKEN FORMAT
+
+ This appendix specifies a mechanism-independent level of
+ encapsulating representation for the initial token of a GSS-API
+ context establishment sequence, incorporating an identifier of the
+ mechanism type to be used on that context. Use of this format (with
+ ASN.1-encoded data elements represented in BER, constrained in the
+ interests of parsing simplicity to the Distinguished Encoding Rule
+ (DER) BER subset defined in X.509, clause 8.7) is recommended to the
+ designers of GSS-API implementations based on various mechanisms, so
+ that tokens can be interpreted unambiguously at GSS-API peers. There
+ is no requirement that the mechanism-specific innerContextToken,
+ innerMsgToken, and sealedUserData data elements be encoded in ASN.1
+ BER.
+
+ -- optional top-level token definitions to
+ -- frame different mechanisms
+
+ GSS-API DEFINITIONS ::=
+
+ BEGIN
+
+ MechType ::= OBJECT IDENTIFIER
+ -- data structure definitions
+
+ -- callers must be able to distinguish among
+ -- InitialContextToken, SubsequentContextToken,
+ -- PerMsgToken, and SealedMessage data elements
+ -- based on the usage in which they occur
+
+ InitialContextToken ::=
+ -- option indication (delegation, etc.) indicated within
+ -- mechanism-specific token
+ [APPLICATION 0] IMPLICIT SEQUENCE {
+ thisMech MechType,
+ innerContextToken ANY DEFINED BY thisMech
+
+
+
+Linn [Page 48]
+
+RFC 1508 Generic Security Interface September 1993
+
+
+ -- contents mechanism-specific
+ }
+
+ SubsequentContextToken ::= innerContextToken ANY
+ -- interpretation based on predecessor InitialContextToken
+
+ PerMsgToken ::=
+ -- as emitted by GSS_Sign and processed by GSS_Verify
+ innerMsgToken ANY
+
+ SealedMessage ::=
+ -- as emitted by GSS_Seal and processed by GSS_Unseal
+ -- includes internal, mechanism-defined indicator
+ -- of whether or not encrypted
+ sealedUserData ANY
+
+ END
+
+APPENDIX C
+
+MECHANISM DESIGN CONSTRAINTS
+
+ The following constraints on GSS-API mechanism designs are adopted in
+ response to observed caller protocol requirements, and adherence
+ thereto is anticipated in subsequent descriptions of GSS-API
+ mechanisms to be documented in standards-track Internet
+ specifications.
+
+ Use of the approach defined in Appendix B of this specification,
+ applying a mechanism type tag to the InitialContextToken, is
+ required.
+
+ It is strongly recommended that mechanisms offering per-message
+ protection services also offer at least one of the replay detection
+ and sequencing services, as mechanisms offering neither of the latter
+ will fail to satisfy recognized requirements of certain candidate
+ caller protocols.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Linn [Page 49]
+ \ No newline at end of file
diff --git a/crypto/heimdal/doc/standardisation/rfc1509.txt b/crypto/heimdal/doc/standardisation/rfc1509.txt
new file mode 100644
index 000000000000..f36cd80e6dcd
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/rfc1509.txt
@@ -0,0 +1,2691 @@
+
+
+
+
+
+
+Network Working Group J. Wray
+Request for Comments: 1509 Digital Equipment Corporation
+ September 1993
+
+
+ Generic Security Service API : C-bindings
+
+Status of this Memo
+
+ This RFC specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" for the standardization state and status
+ of this protocol. Distribution of this memo is unlimited.
+
+Abstract
+
+ This document specifies C language bindings for the Generic Security
+ Service Application Program Interface (GSS-API), which is described
+ at a language-independent conceptual level in other documents.
+
+ The Generic Security Service Application Programming Interface (GSS-
+ API) provides security services to its callers, and is intended for
+ implementation atop alternative underlying cryptographic mechanisms.
+ Typically, GSS-API callers will be application protocols into which
+ security enhancements are integrated through invocation of services
+ provided by the GSS-API. The GSS-API allows a caller application to
+ authenticate a principal identity associated with a peer application,
+ to delegate rights to a peer, and to apply security services such as
+ confidentiality and integrity on a per-message basis.
+
+1. INTRODUCTION
+
+ The Generic Security Service Application Programming Interface [1]
+ provides security services to calling applications. It allows a
+ communicating application to authenticate the user associated with
+ another application, to delegate rights to another application, and
+ to apply security services such as confidentiality and integrity on a
+ per-message basis.
+
+ There are four stages to using the GSSAPI:
+
+ (a) The application acquires a set of credentials with which it may
+ prove its identity to other processes. The application's
+ credentials vouch for its global identity, which may or may not
+ be related to the local username under which it is running.
+
+
+
+
+
+Wray [Page 1]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ (b) A pair of communicating applications establish a joint security
+ context using their credentials. The security context is a
+ pair of GSSAPI data structures that contain shared state
+ information, which is required in order that per-message
+ security services may be provided. As part of the
+ establishment of a security context, the context initiator is
+ authenticated to the responder, and may require that the
+ responder is authenticated in turn. The initiator may
+ optionally give the responder the right to initiate further
+ security contexts. This transfer of rights is termed
+ delegation, and is achieved by creating a set of credentials,
+ similar to those used by the originating application, but which
+ may be used by the responder. To establish and maintain the
+ shared information that makes up the security context, certain
+ GSSAPI calls will return a token data structure, which is a
+ cryptographically protected opaque data type. The caller of
+ such a GSSAPI routine is responsible for transferring the token
+ to the peer application, which should then pass it to a
+ corresponding GSSAPI routine which will decode it and extract
+ the information.
+
+ (c) Per-message services are invoked to apply either:
+
+ (i) integrity and data origin authentication, or
+
+ (ii) confidentiality, integrity and data origin authentication
+ to application data, which are treated by GSSAPI as
+ arbitrary octet-strings. The application transmitting a
+ message that it wishes to protect will call the appropriate
+ GSSAPI routine (sign or seal) to apply protection, specifying
+ the appropriate security context, and send the result to the
+ receiving application. The receiver will pass the received
+ data to the corresponding decoding routine (verify or unseal)
+ to remove the protection and validate the data.
+
+ (d) At the completion of a communications session (which may extend
+ across several connections), the peer applications call GSSAPI
+ routines to delete the security context. Multiple contexts may
+ also be used (either successively or simultaneously) within a
+ single communications association.
+
+2. GSSAPI Routines
+
+ This section lists the functions performed by each of the GSSAPI
+ routines and discusses their major parameters, describing how they
+ are to be passed to the routines. The routines are listed in figure
+ 4-1.
+
+
+
+
+Wray [Page 2]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ Figure 4-1 GSSAPI Routines
+
+
+ Routine Function
+
+ gss_acquire_cred Assume a global identity
+
+ gss_release_cred Discard credentials
+
+ gss_init_sec_context Initiate a security context
+ with a peer application
+
+ gss_accept_sec_context Accept a security context
+ initiated by a peer
+ application
+
+ gss_process_context_token Process a token on a security
+ context from a peer
+ application
+
+ gss_delete_sec_context Discard a security context
+
+ gss_context_time Determine for how long a
+ context will remain valid
+
+ gss_sign Sign a message; integrity
+ service
+
+ gss_verify Check signature on a message
+
+ gss_seal Sign (optionally encrypt) a
+ message; confidentiality
+ service
+
+ gss_unseal Verify (optionally decrypt)
+ message
+
+ gss_display_status Convert an API status code
+ to text
+
+ gss_indicate_mechs Determine underlying
+ authentication mechanism
+
+ gss_compare_name Compare two internal-form
+ names
+
+ gss_display_name Convert opaque name to text
+
+
+
+
+Wray [Page 3]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ gss_import_name Convert a textual name to
+ internal-form
+
+ gss_release_name Discard an internal-form
+ name
+
+ gss_release_buffer Discard a buffer
+
+ gss_release_oid_set Discard a set of object
+ identifiers
+
+ gss_inquire_cred Determine information about
+ a credential
+
+ Individual GSSAPI implementations may augment these routines by
+ providing additional mechanism-specific routines if required
+ functionality is not available from the generic forms. Applications
+ are encouraged to use the generic routines wherever possible on
+ portability grounds.
+
+2.1. Data Types and Calling Conventions
+
+ The following conventions are used by the GSSAPI:
+
+2.1.1. Structured data types
+
+ Wherever these GSSAPI C-bindings describe structured data, only
+ fields that must be provided by all GSSAPI implementation are
+ documented. Individual implementations may provide additional
+ fields, either for internal use within GSSAPI routines, or for use by
+ non-portable applications.
+
+2.1.2. Integer types
+
+ GSSAPI defines the following integer data type:
+
+ OM_uint32 32-bit unsigned integer
+
+ Where guaranteed minimum bit-count is important, this portable data
+ type is used by the GSSAPI routine definitions. Individual GSSAPI
+ implementations will include appropriate typedef definitions to map
+ this type onto a built-in data type.
+
+2.1.3. String and similar data
+
+ Many of the GSSAPI routines take arguments and return values that
+ describe contiguous multiple-byte data. All such data is passed
+ between the GSSAPI and the caller using the gss_buffer_t data type.
+
+
+
+Wray [Page 4]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ This data type is a pointer to a buffer descriptor, which consists of
+ a length field that contains the total number of bytes in the datum,
+ and a value field which contains a pointer to the actual datum:
+
+ typedef struct gss_buffer_desc_struct {
+ size_t length;
+ void *value;
+ } gss_buffer_desc, *gss_buffer_t;
+
+ Storage for data passed to the application by a GSSAPI routine using
+ the gss_buffer_t conventions is allocated by the GSSAPI routine. The
+ application may free this storage by invoking the gss_release_buffer
+ routine. Allocation of the gss_buffer_desc object is always the
+ responsibility of the application; Unused gss_buffer_desc objects
+ may be initialized to the value GSS_C_EMPTY_BUFFER.
+
+2.1.3.1. Opaque data types
+
+ Certain multiple-word data items are considered opaque data types at
+ the GSSAPI, because their internal structure has no significance
+ either to the GSSAPI or to the caller. Examples of such opaque data
+ types are the input_token parameter to gss_init_sec_context (which is
+ opaque to the caller), and the input_message parameter to gss_seal
+ (which is opaque to the GSSAPI). Opaque data is passed between the
+ GSSAPI and the application using the gss_buffer_t datatype.
+
+2.1.3.2. Character strings
+
+ Certain multiple-word data items may be regarded as simple ISO
+ Latin-1 character strings. An example of this is the
+ input_name_buffer parameter to gss_import_name. Some GSSAPI routines
+ also return character strings. Character strings are passed between
+ the application and the GSSAPI using the gss_buffer_t datatype,
+ defined earlier.
+
+2.1.4. Object Identifiers
+
+ Certain GSSAPI procedures take parameters of the type gss_OID, or
+ Object identifier. This is a type containing ISO-defined tree-
+ structured values, and is used by the GSSAPI caller to select an
+ underlying security mechanism. A value of type gss_OID has the
+ following structure:
+
+ typedef struct gss_OID_desc_struct {
+ OM_uint32 length;
+ void *elements;
+ } gss_OID_desc, *gss_OID;
+
+
+
+
+Wray [Page 5]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ The elements field of this structure points to the first byte of an
+ octet string containing the ASN.1 BER encoding of the value of the
+ gss_OID. The length field contains the number of bytes in this
+ value. For example, the gss_OID value corresponding to {iso(1)
+ identified- oganization(3) icd-ecma(12) member-company(2) dec(1011)
+ cryptoAlgorithms(7) SPX(5)} meaning SPX (Digital's X.509
+ authentication mechanism) has a length field of 7 and an elements
+ field pointing to seven octets containing the following octal values:
+ 53,14,2,207,163,7,5. GSSAPI implementations should provide constant
+ gss_OID values to allow callers to request any supported mechanism,
+ although applications are encouraged on portability grounds to accept
+ the default mechanism. gss_OID values should also be provided to
+ allow applications to specify particular name types (see section
+ 2.1.10). Applications should treat gss_OID_desc values returned by
+ GSSAPI routines as read-only. In particular, the application should
+ not attempt to deallocate them. The gss_OID_desc datatype is
+ equivalent to the X/Open OM_object_identifier datatype [2].
+
+2.1.5. Object Identifier Sets
+
+ Certain GSSAPI procedures take parameters of the type gss_OID_set.
+ This type represents one or more object identifiers (section 2.1.4).
+ A gss_OID_set object has the following structure:
+
+ typedef struct gss_OID_set_desc_struct {
+ int count;
+ gss_OID elements;
+ } gss_OID_set_desc, *gss_OID_set;
+
+ The count field contains the number of OIDs within the set. The
+ elements field is a pointer to an array of gss_OID_desc objects, each
+ of which describes a single OID. gss_OID_set values are used to name
+ the available mechanisms supported by the GSSAPI, to request the use
+ of specific mechanisms, and to indicate which mechanisms a given
+ credential supports. Storage associated with gss_OID_set values
+ returned to the application by the GSSAPI may be deallocated by the
+ gss_release_oid_set routine.
+
+2.1.6. Credentials
+
+ A credential handle is a caller-opaque atomic datum that identifies a
+ GSSAPI credential data structure. It is represented by the caller-
+ opaque type gss_cred_id_t, which may be implemented as either an
+ arithmetic or a pointer type. Credentials describe a principal, and
+ they give their holder the ability to act as that principal. The
+ GSSAPI does not make the actual credentials available to
+ applications; instead the credential handle is used to identify a
+ particular credential, held internally by GSSAPI or underlying
+
+
+
+Wray [Page 6]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ mechanism. Thus the credential handle contains no security-relavent
+ information, and requires no special protection by the application.
+ Depending on the implementation, a given credential handle may refer
+ to different credentials when presented to the GSSAPI by different
+ callers. Individual GSSAPI implementations should define both the
+ scope of a credential handle and the scope of a credential itself
+ (which must be at least as wide as that of a handle). Possibilities
+ for credential handle scope include the process that acquired the
+ handle, the acquiring process and its children, or all processes
+ sharing some local identification information (e.g., UID). If no
+ handles exist by which a given credential may be reached, the GSSAPI
+ may delete the credential.
+
+ Certain routines allow credential handle parameters to be omitted to
+ indicate the use of a default credential. The mechanism by which a
+ default credential is established and its scope should be defined by
+ the individual GSSAPI implementation.
+
+2.1.7. Contexts
+
+ The gss_ctx_id_t data type contains a caller-opaque atomic value that
+ identifies one end of a GSSAPI security context. It may be
+ implemented as either an arithmetic or a pointer type. Depending on
+ the implementation, a given gss_ctx_id_t value may refer to different
+ GSSAPI security contexts when presented to the GSSAPI by different
+ callers. The security context holds state information about each end
+ of a peer communication, including cryptographic state information.
+ Individual GSSAPI implementations should define the scope of a
+ context. Since no way is provided by which a new gss_ctx_id_t value
+ may be obtained for an existing context, the scope of a context
+ should be the same as the scope of a gss_ctx_id_t.
+
+2.1.8. Authentication tokens
+
+ A token is a caller-opaque type that GSSAPI uses to maintain
+ synchronization between the context data structures at each end of a
+ GSSAPI security context. The token is a cryptographically protected
+ bit-string, generated by the underlying mechanism at one end of a
+ GSSAPI security context for use by the peer mechanism at the other
+ end. Encapsulation (if required) and transfer of the token are the
+ responsibility of the peer applications. A token is passed between
+ the GSSAPI and the application using the gss_buffer_t conventions.
+
+2.1.9. Status values
+
+ One or more status codes are returned by each GSSAPI routine. Two
+ distinct sorts of status codes are returned. These are termed GSS
+ status codes and Mechanism status codes.
+
+
+
+Wray [Page 7]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+2.1.9.1. GSS status codes
+
+ GSSAPI routines return GSS status codes as their OM_uint32 function
+ value. These codes indicate errors that are independent of the
+ underlying mechanism used to provide the security service. The
+ errors that can be indicated via a GSS status code are either generic
+ API routine errors (errors that are defined in the GSSAPI
+ specification) or calling errors (errors that are specific to these
+ bindings).
+
+ A GSS status code can indicate a single fatal generic API error from
+ the routine and a single calling error. In addition, supplementary
+ status information may be indicated via the setting of bits in the
+ supplementary info field of a GSS status code.
+
+ These errors are encoded into the 32-bit GSS status code as follows:
+
+ MSB LSB
+ |------------------------------------------------------------|
+ | Calling Error | Routine Error | Supplementary Info |
+ |------------------------------------------------------------|
+ Bit 31 24 23 16 15 0
+
+ Hence if a GSSAPI routine returns a GSS status code whose upper 16
+ bits contain a non-zero value, the call failed. If the calling error
+ field is non-zero, the invoking application's call of the routine was
+ erroneous. Calling errors are defined in table 5-1. If the routine
+ error field is non-zero, the routine failed for one of the routine-
+ specific reasons listed below in table 5-2. Whether or not the upper
+ 16 bits indicate a failure or a success, the routine may indicate
+ additional information by setting bits in the supplementary info
+ field of the status code. The meaning of individual bits is listed
+ below in table 5-3.
+
+ Table 5-1 Calling Errors
+
+ Name Value in Meaning
+ Field
+ GSS_S_CALL_INACCESSIBLE_READ 1 A required input
+ parameter could
+ not be read.
+ GSS_S_CALL_INACCESSIBLE_WRITE 2 A required output
+ parameter could
+ not be written.
+ GSS_S_CALL_BAD_STRUCTURE 3 A parameter was
+ malformed
+
+
+
+
+
+Wray [Page 8]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ Table 5-2 Routine Errors
+
+ Name Value in Meaning
+ Field
+
+ GSS_S_BAD_MECH 1 An unsupported mechanism was
+ requested
+ GSS_S_BAD_NAME 2 An invalid name was supplied
+ GSS_S_BAD_NAMETYPE 3 A supplied name was of an
+ unsupported type
+ GSS_S_BAD_BINDINGS 4 Incorrect channel bindings
+ were supplied
+ GSS_S_BAD_STATUS 5 An invalid status code was
+ supplied
+
+ GSS_S_BAD_SIG 6 A token had an invalid
+ signature
+ GSS_S_NO_CRED 7 No credentials were supplied
+ GSS_S_NO_CONTEXT 8 No context has been
+ established
+ GSS_S_DEFECTIVE_TOKEN 9 A token was invalid
+ GSS_S_DEFECTIVE_CREDENTIAL 10 A credential was invalid
+ GSS_S_CREDENTIALS_EXPIRED 11 The referenced credentials
+ have expired
+ GSS_S_CONTEXT_EXPIRED 12 The context has expired
+ GSS_S_FAILURE 13 Miscellaneous failure
+ (see text)
+
+ Table 5-3 Supplementary Status Bits
+
+ Name Bit Number Meaning
+ GSS_S_CONTINUE_NEEDED 0 (LSB) The routine must be called
+ again to complete its
+ function.
+ See routine documentation for
+ detailed description.
+ GSS_S_DUPLICATE_TOKEN 1 The token was a duplicate of
+ an earlier token
+ GSS_S_OLD_TOKEN 2 The token's validity period
+ has expired
+ GSS_S_UNSEQ_TOKEN 3 A later token has already been
+ processed
+
+ The routine documentation also uses the name GSS_S_COMPLETE, which is
+ a zero value, to indicate an absence of any API errors or
+ supplementary information bits.
+
+
+
+
+
+Wray [Page 9]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ All GSS_S_xxx symbols equate to complete OM_uint32 status codes,
+ rather than to bitfield values. For example, the actual value of the
+ symbol GSS_S_BAD_NAMETYPE (value 3 in the routine error field) is 3
+ << 16.
+
+ The macros GSS_CALLING_ERROR(), GSS_ROUTINE_ERROR() and
+ GSS_SUPPLEMENTARY_INFO() are provided, each of which takes a GSS
+ status code and removes all but the relevant field. For example, the
+ value obtained by applying GSS_ROUTINE_ERROR to a status code removes
+ the calling errors and supplementary info fields, leaving only the
+ routine errors field. The values delivered by these macros may be
+ directly compared with a GSS_S_xxx symbol of the appropriate type.
+ The macro GSS_ERROR() is also provided, which when applied to a GSS
+ status code returns a non-zero value if the status code indicated a
+ calling or routine error, and a zero value otherwise.
+
+ A GSSAPI implementation may choose to signal calling errors in a
+ platform-specific manner instead of, or in addition to the routine
+ value; routine errors and supplementary info should be returned via
+ routine status values only.
+
+2.1.9.2. Mechanism-specific status codes
+
+ GSSAPI routines return a minor_status parameter, which is used to
+ indicate specialized errors from the underlying security mechanism.
+ This parameter may contain a single mechanism-specific error,
+ indicated by a OM_uint32 value.
+
+ The minor_status parameter will always be set by a GSSAPI routine,
+ even if it returns a calling error or one of the generic API errors
+ indicated above as fatal, although other output parameters may remain
+ unset in such cases. However, output parameters that are expected to
+ return pointers to storage allocated by a routine must always set set
+ by the routine, even in the event of an error, although in such cases
+ the GSSAPI routine may elect to set the returned parameter value to
+ NULL to indicate that no storage was actually allocated. Any length
+ field associated with such pointers (as in a gss_buffer_desc
+ structure) should also be set to zero in such cases.
+
+ The GSS status code GSS_S_FAILURE is used to indicate that the
+ underlying mechanism detected an error for which no specific GSS
+ status code is defined. The mechanism status code will provide more
+ details about the error.
+
+2.1.10. Names
+
+ A name is used to identify a person or entity. GSSAPI authenticates
+ the relationship between a name and the entity claiming the name.
+
+
+
+Wray [Page 10]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ Two distinct representations are defined for names:
+
+ (a) A printable form, for presentation to a user
+
+ (b) An internal form, for presentation at the API
+
+ The syntax of a printable name is defined by the GSSAPI
+ implementation, and may be dependent on local system configuration,
+ or on individual user preference. The internal form provides a
+ canonical representation of the name that is independent of
+ configuration.
+
+ A given GSSAPI implementation may support names drawn from multiple
+ namespaces. In such an implementation, the internal form of the name
+ must include fields that identify the namespace from which the name
+ is drawn. The namespace from which a printable name is drawn is
+ specified by an accompanying object identifier.
+
+ Routines (gss_import_name and gss_display_name) are provided to
+ convert names between their printable representations and the
+ gss_name_t type. gss_import_name may support multiple syntaxes for
+ each supported namespace, allowing users the freedom to choose a
+ preferred name representation. gss_display_name should use an
+ implementation-chosen preferred syntax for each supported name-type.
+
+ Comparison of internal-form names is accomplished via the
+ gss_compare_names routine. This removes the need for the application
+ program to understand the syntaxes of the various printable names
+ that a given GSSAPI implementation may support.
+
+ Storage is allocated by routines that return gss_name_t values. A
+ procedure, gss_release_name, is provided to free storage associated
+ with a name.
+
+2.1.11. Channel Bindings
+
+ GSSAPI supports the use of user-specified tags to identify a given
+ context to the peer application. These tags are used to identify the
+ particular communications channel that carries the context. Channel
+ bindings are communicated to the GSSAPI using the following
+ structure:
+
+
+
+
+
+
+
+
+
+
+Wray [Page 11]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ typedef struct gss_channel_bindings_struct {
+ OM_uint32 initiator_addrtype;
+ gss_buffer_desc initiator_address;
+ OM_uint32 acceptor_addrtype;
+ gss_buffer_desc acceptor_address;
+ gss_buffer_desc application_data;
+ } *gss_channel_bindings_t;
+
+ The initiator_addrtype and acceptor_addrtype fields denote the type
+ of addresses contained in the initiator_address and acceptor_address
+ buffers. The address type should be one of the following:
+
+ GSS_C_AF_UNSPEC Unspecified address type
+ GSS_C_AF_LOCAL Host-local address type
+ GSS_C_AF_INET DARPA Internet address type
+ GSS_C_AF_IMPLINK ARPAnet IMP address type (eg IP)
+ GSS_C_AF_PUP pup protocols (eg BSP) address type
+ GSS_C_AF_CHAOS MIT CHAOS protocol address type
+ GSS_C_AF_NS XEROX NS address type
+ GSS_C_AF_NBS nbs address type
+ GSS_C_AF_ECMA ECMA address type
+ GSS_C_AF_DATAKIT datakit protocols address type
+ GSS_C_AF_CCITT CCITT protocols (eg X.25)
+ GSS_C_AF_SNA IBM SNA address type
+ GSS_C_AF_DECnet DECnet address type
+ GSS_C_AF_DLI Direct data link interface address type
+ GSS_C_AF_LAT LAT address type
+ GSS_C_AF_HYLINK NSC Hyperchannel address type
+ GSS_C_AF_APPLETALK AppleTalk address type
+ GSS_C_AF_BSC BISYNC 2780/3780 address type
+ GSS_C_AF_DSS Distributed system services address type
+ GSS_C_AF_OSI OSI TP4 address type
+ GSS_C_AF_X25 X25
+ GSS_C_AF_NULLADDR No address specified
+
+ Note that these name address families rather than specific addressing
+ formats. For address families that contain several alternative
+ address forms, the initiator_address and acceptor_address fields must
+ contain sufficient information to determine which address form is
+ used. When not otherwise specified, addresses should be specified in
+ network byte-order.
+
+ Conceptually, the GSSAPI concatenates the initiator_addrtype,
+ initiator_address, acceptor_addrtype, acceptor_address and
+ application_data to form an octet string. The mechanism signs this
+ octet string, and binds the signature to the context establishment
+ token emitted by gss_init_sec_context. The same bindings are
+ presented by the context acceptor to gss_accept_sec_context, and a
+
+
+
+Wray [Page 12]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ signature is calculated in the same way. The calculated signature is
+ compared with that found in the token, and if the signatures differ,
+ gss_accept_sec_context will return a GSS_S_BAD_BINDINGS error, and
+ the context will not be established. Some mechanisms may include the
+ actual channel binding data in the token (rather than just a
+ signature); applications should therefore not use confidential data
+ as channel-binding components. Individual mechanisms may impose
+ additional constraints on addresses and address types that may appear
+ in channel bindings. For example, a mechanism may verify that the
+ initiator_address field of the channel bindings presented to
+ gss_init_sec_context contains the correct network address of the host
+ system.
+
+2.1.12. Optional parameters
+
+ Various parameters are described as optional. This means that they
+ follow a convention whereby a default value may be requested. The
+ following conventions are used for omitted parameters. These
+ conventions apply only to those parameters that are explicitly
+ documented as optional.
+
+2.1.12.1. gss_buffer_t types
+
+ Specify GSS_C_NO_BUFFER as a value. For an input parameter this
+ signifies that default behavior is requested, while for an output
+ parameter it indicates that the information that would be returned
+ via the parameter is not required by the application.
+
+2.1.12.2. Integer types (input)
+
+ Individual parameter documentation lists values to be used to
+ indicate default actions.
+
+2.1.12.3. Integer types (output)
+
+ Specify NULL as the value for the pointer.
+
+2.1.12.4. Pointer types
+
+ Specify NULL as the value.
+
+2.1.12.5. Object IDs
+
+ Specify GSS_C_NULL_OID as the value.
+
+2.1.12.6. Object ID Sets
+
+ Specify GSS_C_NULL_OID_SET as the value.
+
+
+
+Wray [Page 13]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+2.1.12.7. Credentials
+
+ Specify GSS_C_NO_CREDENTIAL to use the default credential handle.
+
+2.1.12.8. Channel Bindings
+
+ Specify GSS_C_NO_CHANNEL_BINDINGS to indicate that channel bindings
+ are not to be used.
+
+3. GSSAPI routine descriptions
+
+2.1. gss_acquire_cred
+
+ OM_uint32 gss_acquire_cred (
+ OM_uint32 * minor_status,
+ gss_name_t desired_name,
+ OM_uint32 time_req,
+ gss_OID_set desired_mechs,
+ int cred_usage,
+ gss_cred_id_t * output_cred_handle,
+ gss_OID_set * actual_mechs,
+ OM_int32 * time_rec)
+ Purpose:
+
+ Allows an application to acquire a handle for a pre-existing
+ credential by name. GSSAPI implementations must impose a local
+ access-control policy on callers of this routine to prevent
+ unauthorized callers from acquiring credentials to which they are not
+ entitled. This routine is not intended to provide a "login to the
+ network" function, as such a function would result in the creation of
+ new credentials rather than merely acquiring a handle to existing
+ credentials. Such functions, if required, should be defined in
+ implementation-specific extensions to the API.
+
+ If credential acquisition is time-consuming for a mechanism, the
+ mechanism may chooses to delay the actual acquisition until the
+ credential is required (e.g., by gss_init_sec_context or
+ gss_accept_sec_context). Such mechanism-specific implementation
+ decisions should be invisible to the calling application; thus a call
+ of gss_inquire_cred immediately following the call of
+ gss_acquire_cred must return valid credential data, and may therefore
+ incur the overhead of a deferred credential acquisition.
+
+ Parameters:
+
+ desired_name gss_name_t, read
+ Name of principal whose credential
+ should be acquired
+
+
+
+Wray [Page 14]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ time_req integer, read
+ number of seconds that credentials
+ should remain valid
+
+ desired_mechs Set of Object IDs, read
+ set of underlying security mechanisms that
+ may be used. GSS_C_NULL_OID_SET may be used
+ to obtain an implementation-specific default.
+
+ cred_usage integer, read
+ GSS_C_BOTH - Credentials may be used
+ either to initiate or accept
+ security contexts.
+ GSS_C_INITIATE - Credentials will only be
+ used to initiate security
+ contexts.
+ GSS_C_ACCEPT - Credentials will only be used to
+ accept security contexts.
+
+ output_cred_handle gss_cred_id_t, modify
+ The returned credential handle.
+
+ actual_mechs Set of Object IDs, modify, optional
+ The set of mechanisms for which the
+ credential is valid. Specify NULL
+ if not required.
+
+ time_rec Integer, modify, optional
+ Actual number of seconds for which the
+ returned credentials will remain valid. If the
+ implementation does not support expiration of
+ credentials, the value GSS_C_INDEFINITE will
+ be returned. Specify NULL if not required
+
+ minor_status Integer, modify
+ Mechanism specific status code.
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_MECH Unavailable mechanism requested
+
+ GSS_S_BAD_NAMETYPE Type contained within desired_name parameter is
+ not supported
+
+ GSS_S_BAD_NAME Value supplied for desired_name parameter is
+
+
+
+Wray [Page 15]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ ill-formed.
+
+ GSS_S_FAILURE Unspecified failure. The minor_status parameter
+ contains more detailed information
+
+3.2. gss_release_cred
+
+ OM_uint32 gss_release_cred (
+ OM_uint32 * minor_status,
+ gss_cred_id_t * cred_handle)
+
+ Purpose:
+
+ Informs GSSAPI that the specified credential handle is no longer
+ required by the process. When all processes have released a
+ credential, it will be deleted.
+
+ Parameters:
+
+ cred_handle gss_cred_id_t, modify, optional
+ buffer containing opaque credential
+ handle. If GSS_C_NO_CREDENTIAL is supplied,
+ the default credential will be released
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_NO_CRED Credentials could not be accessed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wray [Page 16]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+3.3. gss_init_sec_context
+
+ OM_uint32 gss_init_sec_context (
+ OM_uint32 * minor_status,
+ gss_cred_id_t claimant_cred_handle,
+ gss_ctx_id_t * context_handle,
+ gss_name_t target_name,
+ gss_OID mech_type,
+ int req_flags,
+ int time_req,
+ gss_channel_bindings_t
+ input_chan_bindings,
+ gss_buffer_t input_token
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ int * ret_flags,
+ OM_uint32 * time_rec )
+
+ Purpose:
+
+ Initiates the establishment of a security context between the
+ application and a remote peer. Initially, the input_token parameter
+ should be specified as GSS_C_NO_BUFFER. The routine may return a
+ output_token which should be transferred to the peer application,
+ where the peer application will present it to gss_accept_sec_context.
+ If no token need be sent, gss_init_sec_context will indicate this by
+ setting the length field of the output_token argument to zero. To
+ complete the context establishment, one or more reply tokens may be
+ required from the peer application; if so, gss_init_sec_context will
+ return a status indicating GSS_S_CONTINUE_NEEDED in which case it
+ should be called again when the reply token is received from the peer
+ application, passing the token to gss_init_sec_context via the
+ input_token parameters.
+
+ The values returned via the ret_flags and time_rec parameters are not
+ defined unless the routine returns GSS_S_COMPLETE.
+
+ Parameters:
+
+ claimant_cred_handle gss_cred_id_t, read, optional
+ handle for credentials claimed. Supply
+ GSS_C_NO_CREDENTIAL to use default
+ credentials.
+
+ context_handle gss_ctx_id_t, read/modify
+ context handle for new context. Supply
+ GSS_C_NO_CONTEXT for first call; use value
+ returned by first call in continuation calls.
+
+
+
+Wray [Page 17]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ target_name gss_name_t, read
+ Name of target
+
+ mech_type OID, read, optional
+ Object ID of desired mechanism. Supply
+ GSS_C_NULL_OID to obtain an implementation
+ specific default
+
+ req_flags bit-mask, read
+ Contains four independent flags, each of
+ which requests that the context support a
+ specific service option. Symbolic
+ names are provided for each flag, and the
+ symbolic names corresponding to the required
+ flags should be logically-ORed
+ together to form the bit-mask value. The
+ flags are:
+
+ GSS_C_DELEG_FLAG
+ True - Delegate credentials to remote peer
+ False - Don't delegate
+ GSS_C_MUTUAL_FLAG
+ True - Request that remote peer
+ authenticate itself
+ False - Authenticate self to remote peer
+ only
+ GSS_C_REPLAY_FLAG
+ True - Enable replay detection for signed
+ or sealed messages
+ False - Don't attempt to detect
+ replayed messages
+ GSS_C_SEQUENCE_FLAG
+ True - Enable detection of out-of-sequence
+ signed or sealed messages
+ False - Don't attempt to detect
+ out-of-sequence messages
+
+ time_req integer, read
+ Desired number of seconds for which context
+ should remain valid. Supply 0 to request a
+ default validity period.
+
+ input_chan_bindings channel bindings, read
+ Application-specified bindings. Allows
+ application to securely bind channel
+ identification information to the security
+ context.
+
+
+
+
+Wray [Page 18]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ input_token buffer, opaque, read, optional (see text)
+ Token received from peer application.
+ Supply GSS_C_NO_BUFFER on initial call.
+
+ actual_mech_type OID, modify
+ actual mechanism used.
+
+ output_token buffer, opaque, modify
+ token to be sent to peer application. If
+ the length field of the returned buffer is
+ zero, no token need be sent to the peer
+ application.
+
+ ret_flags bit-mask, modify
+ Contains six independent flags, each of which
+ indicates that the context supports a specific
+ service option. Symbolic names are provided
+ for each flag, and the symbolic names
+ corresponding to the required flags should be
+ logically-ANDed with the ret_flags value to test
+ whether a given option is supported by the
+ context. The flags are:
+
+ GSS_C_DELEG_FLAG
+ True - Credentials were delegated to
+ the remote peer
+ False - No credentials were delegated
+ GSS_C_MUTUAL_FLAG
+ True - Remote peer has been asked to
+ authenticated itself
+ False - Remote peer has not been asked to
+ authenticate itself
+ GSS_C_REPLAY_FLAG
+ True - replay of signed or sealed messages
+ will be detected
+ False - replayed messages will not be
+ detected
+ GSS_C_SEQUENCE_FLAG
+ True - out-of-sequence signed or sealed
+ messages will be detected
+ False - out-of-sequence messages will not
+ be detected
+ GSS_C_CONF_FLAG
+ True - Confidentiality service may be
+ invoked by calling seal routine
+ False - No confidentiality service (via
+ seal) available. seal will provide
+ message encapsulation, data-origin
+
+
+
+Wray [Page 19]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ authentication and integrity
+ services only.
+ GSS_C_INTEG_FLAG
+ True - Integrity service may be invoked by
+ calling either gss_sign or gss_seal
+ routines.
+ False - Per-message integrity service
+ unavailable.
+
+ time_rec integer, modify, optional
+ number of seconds for which the context
+ will remain valid. If the implementation does
+ not support credential expiration, the value
+ GSS_C_INDEFINITE will be returned. Specify
+ NULL if not required.
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTINUE_NEEDED Indicates that a token from the peer
+ application is required to complete thecontext, and
+ that gss_init_sec_context must be called again with
+ that token.
+
+ GSS_S_DEFECTIVE_TOKEN Indicates that consistency checks performed on
+ the input_token failed
+
+ GSS_S_DEFECTIVE_CREDENTIAL Indicates that consistency checks
+ performed on the credential failed.
+
+ GSS_S_NO_CRED The supplied credentials were not valid for context
+ initiation, or the credential handle did not
+ reference any credentials.
+
+ GSS_S_CREDENTIALS_EXPIRED The referenced credentials have expired
+
+ GSS_S_BAD_BINDINGS The input_token contains different channel
+ bindings to those specified via the
+ input_chan_bindings parameter
+
+ GSS_S_BAD_SIG The input_token contains an invalid signature, or a
+ signature that could not be verified
+
+
+
+Wray [Page 20]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ GSS_S_OLD_TOKEN The input_token was too old. This is a fatal error
+ during context establishment
+
+ GSS_S_DUPLICATE_TOKEN The input_token is valid, but is a duplicate of
+ a token already processed. This is a fatal error
+ during context establishment.
+
+ GSS_S_NO_CONTEXT Indicates that the supplied context handle did not
+ refer to a valid context
+
+ GSS_S_BAD_NAMETYPE The provided target_name parameter contained an
+ invalid or unsupported type of name
+
+ GSS_S_BAD_NAME The provided target_name parameter was ill-formed.
+
+ GSS_S_FAILURE Failure. See minor_status for more information
+
+3.4. gss_accept_sec_context
+
+ OM_uint32 gss_accept_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_cred_id_t verifier_cred_handle,
+ gss_buffer_t input_token_buffer
+ gss_channel_bindings_t
+ input_chan_bindings,
+ gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ int * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t * delegated_cred_handle)
+
+ Purpose:
+
+ Allows a remotely initiated security context between the application
+ and a remote peer to be established. The routine may return a
+ output_token which should be transferred to the peer application,
+ where the peer application will present it to gss_init_sec_context.
+ If no token need be sent, gss_accept_sec_context will indicate this
+ by setting the length field of the output_token argument to zero. To
+ complete the context establishment, one or more reply tokens may be
+ required from the peer application; if so, gss_accept_sec_context
+ will return a status flag of GSS_S_CONTINUE_NEEDED, in which case it
+ should be called again when the reply token is received from the peer
+ application, passing the token to gss_accept_sec_context via the
+ input_token parameters.
+
+
+
+
+Wray [Page 21]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ The values returned via the src_name, ret_flags, time_rec, and
+ delegated_cred_handle parameters are not defined unless the routine
+ returns GSS_S_COMPLETE.
+
+ Parameters:
+
+ context_handle gss_ctx_id_t, read/modify
+ context handle for new context. Supply
+ GSS_C_NO_CONTEXT for first call; use value
+ returned in subsequent calls.
+
+ verifier_cred_handle gss_cred_id_t, read, optional
+ Credential handle claimed by context
+ acceptor.
+ Specify GSS_C_NO_CREDENTIAL to use default
+ credentials. If GSS_C_NO_CREDENTIAL is
+ specified, but the caller has no default
+ credentials established, an
+ implementation-defined default credential
+ may be used.
+
+ input_token_buffer buffer, opaque, read
+ token obtained from remote application
+
+ input_chan_bindings channel bindings, read
+ Application-specified bindings. Allows
+ application to securely bind channel
+ identification information to the security
+ context.
+
+ src_name gss_name_t, modify, optional
+ Authenticated name of context initiator.
+ After use, this name should be deallocated by
+ passing it to gss_release_name. If not required,
+ specify NULL.
+
+ mech_type Object ID, modify
+ Security mechanism used. The returned
+ OID value will be a pointer into static
+ storage, and should be treated as read-only
+ by the caller.
+
+ output_token buffer, opaque, modify
+ Token to be passed to peer application. If the
+ length field of the returned token buffer is 0,
+ then no token need be passed to the peer
+ application.
+
+
+
+
+Wray [Page 22]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ ret_flags bit-mask, modify
+ Contains six independent flags, each of
+ which indicates that the context supports a
+ specific service option. Symbolic names are
+ provided for each flag, and the symbolic names
+ corresponding to the required flags
+ should be logically-ANDed with the ret_flags
+ value to test whether a given option is
+ supported by the context. The flags are:
+ GSS_C_DELEG_FLAG
+ True - Delegated credentials are available
+ via the delegated_cred_handle
+ parameter
+ False - No credentials were delegated
+ GSS_C_MUTUAL_FLAG
+ True - Remote peer asked for mutual
+ authentication
+ False - Remote peer did not ask for mutual
+ authentication
+ GSS_C_REPLAY_FLAG
+ True - replay of signed or sealed messages
+ will be detected
+ False - replayed messages will not be
+ detected
+ GSS_C_SEQUENCE_FLAG
+ True - out-of-sequence signed or sealed
+ messages will be detected
+ False - out-of-sequence messages will not
+ be detected
+ GSS_C_CONF_FLAG
+ True - Confidentiality service may be
+ invoked by calling seal routine
+ False - No confidentiality service (via
+ seal) available. seal will
+ provide message encapsulation,
+ data-origin authentication and
+ integrity services only.
+ GSS_C_INTEG_FLAG
+ True - Integrity service may be invoked
+ by calling either gss_sign or
+ gss_seal routines.
+ False - Per-message integrity service
+ unavailable.
+
+ time_rec integer, modify, optional
+ number of seconds for which the context
+ will remain valid. Specify NULL if not required.
+
+
+
+
+Wray [Page 23]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ delegated_cred_handle
+ gss_cred_id_t, modify
+ credential handle for credentials received from
+ context initiator. Only valid if deleg_flag in
+ ret_flags is true.
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTINUE_NEEDED Indicates that a token from the peer
+ application is required to complete the context,
+ and that gss_accept_sec_context must be called
+ again with that token.
+
+ GSS_S_DEFECTIVE_TOKEN Indicates that consistency checks
+ performed on the input_token failed.
+
+ GSS_S_DEFECTIVE_CREDENTIAL Indicates that consistency checks
+ performed on the credential failed.
+
+ GSS_S_NO_CRED The supplied credentials were not valid for
+ context acceptance, or the credential handle
+ did not reference any credentials.
+
+ GSS_S_CREDENTIALS_EXPIRED The referenced credentials have
+ expired.
+
+ GSS_S_BAD_BINDINGS The input_token contains different channel
+ bindings to those specified via the
+ input_chan_bindings parameter.
+
+ GSS_S_NO_CONTEXT Indicates that the supplied context handle did
+ not refer to a valid context.
+
+ GSS_S_BAD_SIG The input_token contains an invalid signature.
+
+ GSS_S_OLD_TOKEN The input_token was too old. This is a fatal
+ error during context establishment.
+
+ GSS_S_DUPLICATE_TOKEN The input_token is valid, but is a
+ duplicate of a token already processed. This
+ is a fatal error during context establishment.
+
+
+
+Wray [Page 24]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ GSS_S_FAILURE Failure. See minor_status for more information.
+
+3.5. gss_process_context_token
+
+ OM_uint32 gss_process_context_token (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t token_buffer)
+
+ Purpose:
+
+ Provides a way to pass a token to the security service. Usually,
+ tokens are associated either with context establishment (when they
+ would be passed to gss_init_sec_context or gss_accept_sec_context) or
+ with per-message security service (when they would be passed to
+ gss_verify or gss_unseal). Occasionally, tokens may be received at
+ other times, and gss_process_context_token allows such tokens to be
+ passed to the underlying security service for processing. At
+ present, such additional tokens may only be generated by
+ gss_delete_sec_context. GSSAPI implementation may use this service
+ to implement deletion of the security context.
+
+ Parameters:
+
+ context_handle gss_ctx_id_t, read
+ context handle of context on which token is to
+ be processed
+
+ token_buffer buffer, opaque, read
+ pointer to first byte of token to process
+
+ minor_status integer, modify
+ Implementation specific status code.
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_DEFECTIVE_TOKEN Indicates that consistency checks
+ performed on the token failed
+
+ GSS_S_FAILURE Failure. See minor_status for more information
+
+ GSS_S_NO_CONTEXT The context_handle did not refer to a valid
+ context
+
+
+
+
+Wray [Page 25]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+3.6. gss_delete_sec_context
+
+ OM_uint32 gss_delete_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t output_token)
+
+ Purpose:
+
+ Delete a security context. gss_delete_sec_context will delete the
+ local data structures associated with the specified security context,
+ and generate an output_token, which when passed to the peer
+ gss_process_context_token will instruct it to do likewise. No
+ further security services may be obtained using the context specified
+ by context_handle.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+ context_handle gss_ctx_id_t, modify
+ context handle identifying context to delete.
+
+ output_token buffer, opaque, modify
+ token to be sent to remote application to
+ instruct it to also delete the context
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_FAILURE Failure, see minor_status for more information
+
+ GSS_S_NO_CONTEXT No valid context was supplied
+
+3.7. gss_context_time
+
+ OM_uint32 gss_context_time (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ OM_uint32 * time_rec)
+ Purpose:
+
+ Determines the number of seconds for which the specified context will
+ remain valid.
+
+
+
+Wray [Page 26]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ Parameters:
+
+ minor_status integer, modify
+ Implementation specific status code.
+
+ context_handle gss_ctx_id_t, read
+ Identifies the context to be interrogated.
+
+ time_rec integer, modify
+ Number of seconds that the context will remain
+ valid. If the context has already expired,
+ zero will be returned.
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTEXT_EXPIRED The context has already expired
+
+ GSS_S_CREDENTIALS_EXPIRED The context is recognized, but
+ associated credentials have expired
+
+ GSS_S_NO_CONTEXT The context_handle parameter did not identify a
+ valid context
+
+3.8. gss_sign
+
+ OM_uint32 gss_sign (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int qop_req,
+ gss_buffer_t message_buffer,
+ gss_buffer_t msg_token)
+ Purpose:
+
+ Generates a cryptographic signature for the supplied message, and
+ places the signature in a token for transfer to the peer application.
+ The qop_req parameter allows a choice between several cryptographic
+ algorithms, if supported by the chosen mechanism.
+
+ Parameters:
+
+ minor_status integer, modify
+ Implementation specific status code.
+
+ context_handle gss_ctx_id_t, read
+ identifies the context on which the message
+
+
+
+Wray [Page 27]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ will be sent
+
+ qop_req integer, read, optional
+ Specifies requested quality of protection.
+ Callers are encouraged, on portability grounds,
+ to accept the default quality of protection
+ offered by the chosen mechanism, which may be
+ requested by specifying GSS_C_QOP_DEFAULT for
+ this parameter. If an unsupported protection
+ strength is requested, gss_sign will return a
+ major_status of GSS_S_FAILURE.
+
+ message_buffer buffer, opaque, read
+ message to be signed
+
+ msg_token buffer, opaque, modify
+ buffer to receive token
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTEXT_EXPIRED The context has already expired
+
+ GSS_S_CREDENTIALS_EXPIRED The context is recognized, but
+ associated credentials have expired
+
+ GSS_S_NO_CONTEXT The context_handle parameter did not identify a
+ valid context
+
+ GSS_S_FAILURE Failure. See minor_status for more information.
+
+3.9. gss_verify
+
+ OM_uint32 gss_verify (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t message_buffer,
+ gss_buffer_t token_buffer,
+ int * qop_state)
+ Purpose:
+
+ Verifies that a cryptographic signature, contained in the token
+ parameter, fits the supplied message. The qop_state parameter allows
+ a message recipient to determine the strength of protection that was
+ applied to the message.
+
+
+
+Wray [Page 28]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+ context_handle gss_ctx_id_t, read
+ identifies the context on which the message
+ arrived
+
+ message_buffer buffer, opaque, read
+ message to be verified
+
+ token_buffer buffer, opaque, read
+ token associated with message
+
+ qop_state integer, modify
+ quality of protection gained from signature
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_DEFECTIVE_TOKEN The token failed consistency checks
+
+ GSS_S_BAD_SIG The signature was incorrect
+
+ GSS_S_DUPLICATE_TOKEN The token was valid, and contained a correct
+ signature for the message, but it had already
+ been processed
+
+ GSS_S_OLD_TOKEN The token was valid, and contained a correct
+ signature for the message, but it is too old
+
+ GSS_S_UNSEQ_TOKEN The token was valid, and contained a correct
+ signature for the message, but has been
+ verified out of sequence; an earlier token has
+ been signed or sealed by the remote
+ application, but not yet been processed
+ locally.
+
+ GSS_S_CONTEXT_EXPIRED The context has already expired
+
+ GSS_S_CREDENTIALS_EXPIRED The context is recognized, but
+ associated credentials have expired
+
+
+
+
+
+Wray [Page 29]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ GSS_S_NO_CONTEXT The context_handle parameter did not identify a
+ valid context
+
+ GSS_S_FAILURE Failure. See minor_status for more information.
+
+3.10. gss_seal
+
+ OM_uint32 gss_seal (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ int qop_req
+ gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer)
+
+ Purpose:
+
+ Cryptographically signs and optionally encrypts the specified
+ input_message. The output_message contains both the signature and
+ the message. The qop_req parameter allows a choice between several
+ cryptographic algorithms, if supported by the chosen mechanism.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+ context_handle gss_ctx_id_t, read
+ identifies the context on which the message
+ will be sent
+
+ conf_req_flag boolean, read
+ True - Both confidentiality and integrity
+ services are requested
+ False - Only integrity service is requested
+
+ qop_req integer, read, optional
+ Specifies required quality of protection. A
+ mechanism-specific default may be requested by
+ setting qop_req to GSS_C_QOP_DEFAULT. If an
+ unsupported protection strength is requested,
+ gss_seal will return a major_status of
+ GSS_S_FAILURE.
+
+ input_message_buffer buffer, opaque, read
+ message to be sealed
+
+
+
+
+Wray [Page 30]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ conf_state boolean, modify
+ True - Confidentiality, data origin
+ authentication and integrity services
+ have been applied
+ False - Integrity and data origin services only
+ has been applied.
+
+ output_message_buffer buffer, opaque, modify
+ buffer to receive sealed message
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_CONTEXT_EXPIRED The context has already expired
+
+ GSS_S_CREDENTIALS_EXPIRED The context is recognized, but
+ associated credentials have expired
+
+ GSS_S_NO_CONTEXT The context_handle parameter did not identify a
+ valid context
+
+ GSS_S_FAILURE Failure. See minor_status for more information.
+
+3.11. gss_unseal
+
+ OM_uint32 gss_unseal (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ int * qop_state)
+
+ Purpose:
+
+ Converts a previously sealed message back to a usable form, verifying
+ the embedded signature. The conf_state parameter indicates whether
+ the message was encrypted; the qop_state parameter indicates the
+ strength of protection that was used to provide the confidentiality
+ and integrity services.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+
+
+Wray [Page 31]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ context_handle gss_ctx_id_t, read
+ identifies the context on which the message
+ arrived
+
+ input_message_buffer buffer, opaque, read
+ sealed message
+
+ output_message_buffer buffer, opaque, modify
+ buffer to receive unsealed message
+
+ conf_state boolean, modify
+ True - Confidentiality and integrity protection
+ were used
+ False - Inteegrity service only was used
+
+ qop_state integer, modify
+ quality of protection gained from signature
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_DEFECTIVE_TOKEN The token failed consistency checks
+
+ GSS_S_BAD_SIG The signature was incorrect
+
+ GSS_S_DUPLICATE_TOKEN The token was valid, and contained a
+ correct signature for the message, but it had
+ already been processed
+
+ GSS_S_OLD_TOKEN The token was valid, and contained a correct
+ signature for the message, but it is too old
+
+ GSS_S_UNSEQ_TOKEN The token was valid, and contained a correct
+ signature for the message, but has been
+ verified out of sequence; an earlier token has
+ been signed or sealed by the remote
+ application, but not yet been processed
+ locally.
+
+ GSS_S_CONTEXT_EXPIRED The context has already expired
+
+ GSS_S_CREDENTIALS_EXPIRED The context is recognized, but
+ associated credentials have expired
+
+
+
+
+
+Wray [Page 32]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ GSS_S_NO_CONTEXT The context_handle parameter did not identify a
+ valid context
+
+ GSS_S_FAILURE Failure. See minor_status for more information.
+
+3.12. gss_display_status
+
+ OM_uint32 gss_display_status (
+ OM_uint32 * minor_status,
+ int status_value,
+ int status_type,
+ gss_OID mech_type,
+ int * message_context,
+ gss_buffer_t status_string)
+
+ Purpose:
+
+ Allows an application to obtain a textual representation of a GSSAPI
+ status code, for display to the user or for logging purposes. Since
+ some status values may indicate multiple errors, applications may
+ need to call gss_display_status multiple times, each call generating
+ a single text string. The message_context parameter is used to
+ indicate which error message should be extracted from a given
+ status_value; message_context should be initialized to 0, and
+ gss_display_status will return a non-zero value if there are further
+ messages to extract.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+ status_value integer, read
+ Status value to be converted
+
+ status_type integer, read
+ GSS_C_GSS_CODE - status_value is a GSS status
+ code
+ GSS_C_MECH_CODE - status_value is a mechanism
+ status code
+
+ mech_type Object ID, read, optional
+ Underlying mechanism (used to interpret a
+ minor status value) Supply GSS_C_NULL_OID to
+ obtain the system default.
+
+ message_context integer, read/modify
+ Should be initialized to zero by caller
+
+
+
+Wray [Page 33]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ on first call. If further messages are
+ contained in the status_value parameter,
+ message_context will be non-zero on return,
+ and this value should be passed back to
+ subsequent calls, along with the same
+ status_value, status_type and mech_type
+ parameters.
+
+ status_string buffer, character string, modify
+ textual interpretation of the status_value
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_MECH Indicates that translation in accordance with
+ an unsupported mechanism type was requested
+
+ GSS_S_BAD_STATUS The status value was not recognized, or the
+ status type was neither GSS_C_GSS_CODE nor
+ GSS_C_MECH_CODE.
+
+
+3.13. gss_indicate_mechs
+
+ OM_uint32 gss_indicate_mechs (
+ OM_uint32 * minor_status,
+ gss_OID_set * mech_set)
+
+ Purpose:
+
+ Allows an application to determine which underlying security
+ mechanisms are available.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+ mech_set set of Object IDs, modify
+ set of implementation-supported mechanisms.
+ The returned gss_OID_set value will be a
+ pointer into static storage, and should be
+ treated as read-only by the caller.
+
+
+
+
+
+Wray [Page 34]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+3.14. gss_compare_name
+
+ OM_uint32 gss_compare_name (
+ OM_uint32 * minor_status,
+ gss_name_t name1,
+ gss_name_t name2,
+ int * name_equal)
+
+ Purpose:
+
+ Allows an application to compare two internal-form names to determine
+ whether they refer to the same entity.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+ name1 gss_name_t, read
+ internal-form name
+
+ name2 gss_name_t, read
+ internal-form name
+
+ name_equal boolean, modify
+ True - names refer to same entity
+ False - names refer to different entities
+ (strictly, the names are not known to
+ refer to the same identity).
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_NAMETYPE The type contained within either name1 or
+ name2 was unrecognized, or the names were of
+ incomparable types.
+
+ GSS_S_BAD_NAME One or both of name1 or name2 was ill-formed
+
+
+
+
+
+Wray [Page 35]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+3.15. gss_display_name
+
+ OM_uint32 gss_display_name (
+ OM_uint32 * minor_status,
+ gss_name_t input_name,
+ gss_buffer_t output_name_buffer,
+ gss_OID * output_name_type)
+
+ Purpose:
+
+ Allows an application to obtain a textual representation of an opaque
+ internal-form name for display purposes. The syntax of a printable
+ name is defined by the GSSAPI implementation.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code.
+
+ input_name gss_name_t, read
+ name to be displayed
+
+ output_name_buffer buffer, character-string, modify
+ buffer to receive textual name string
+
+ output_name_type Object ID, modify
+ The type of the returned name. The returned
+ gss_OID will be a pointer into static storage,
+ and should be treated as read-only by the caller
+
+ Function value:
+
+ GSS status code:
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_NAMETYPE The type of input_name was not recognized
+
+ GSS_S_BAD_NAME input_name was ill-formed
+
+3.16. gss_import_name
+
+ OM_uint32 gss_import_name (
+ OM_uint32 * minor_status,
+ gss_buffer_t input_name_buffer,
+ gss_OID input_name_type,
+ gss_name_t * output_name)
+
+
+
+
+Wray [Page 36]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ Purpose:
+
+ Convert a printable name to internal form.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code
+
+ input_name_buffer buffer, character-string, read
+ buffer containing printable name to convert
+
+ input_name_type Object ID, read, optional
+ Object Id specifying type of printable
+ name. Applications may specify either
+ GSS_C_NULL_OID to use a local system-specific
+ printable syntax, or an OID registered by the
+ GSSAPI implementation to name a particular
+ namespace.
+
+ output_name gss_name_t, modify
+ returned name in internal form
+
+ Function value:
+
+ GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_NAMETYPE The input_name_type was unrecognized
+
+ GSS_S_BAD_NAME The input_name parameter could not be
+ interpreted as a name of the specified type
+
+3.17. gss_release_name
+
+ OM_uint32 gss_release_name (
+ OM_uint32 * minor_status,
+ gss_name_t * name)
+
+ Purpose:
+
+ Free GSSAPI-allocated storage associated with an internal form name.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code
+
+
+
+Wray [Page 37]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ name gss_name_t, modify
+ The name to be deleted
+
+ Function value:
+
+ GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_BAD_NAME The name parameter did not contain a valid name
+
+3.18. gss_release_buffer
+
+ OM_uint32 gss_release_buffer (
+ OM_uint32 * minor_status,
+ gss_buffer_t buffer)
+
+ Purpose:
+
+ Free storage associated with a buffer format name. The storage must
+ have been allocated by a GSSAPI routine. In addition to freeing the
+ associated storage, the routine will zero the length field in the
+ buffer parameter.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code
+
+ buffer buffer, modify
+ The storage associated with the buffer will be
+ deleted. The gss_buffer_desc object will not
+ be freed, but its length field will be zeroed.
+
+ Function value:
+
+ GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+3.19. gss_release_oid_set
+
+ OM_uint32 gss_release_oid_set (
+ OM_uint32 * minor_status,
+ gss_OID_set * set)
+
+ Purpose:
+
+
+
+
+Wray [Page 38]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ Free storage associated with a gss_OID_set object. The storage must
+ have been allocated by a GSSAPI routine.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code
+
+ set Set of Object IDs, modify
+ The storage associated with the gss_OID_set
+ will be deleted.
+
+ Function value:
+
+ GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+3.20. gss_inquire_cred
+
+ OM_uint32 gss_inquire_cred (
+ OM_uint32 * minor_status,
+ gss_cred_id_t cred_handle,
+ gss_name_t * name,
+ OM_uint32 * lifetime,
+ int * cred_usage,
+ gss_OID_set * mechanisms )
+
+ Purpose:
+
+ Obtains information about a credential. The caller must already have
+ obtained a handle that refers to the credential.
+
+ Parameters:
+
+ minor_status integer, modify
+ Mechanism specific status code
+
+ cred_handle gss_cred_id_t, read
+ A handle that refers to the target credential.
+ Specify GSS_C_NO_CREDENTIAL to inquire about
+ the default credential.
+
+ name gss_name_t, modify
+ The name whose identity the credential asserts.
+ Specify NULL if not required.
+
+ lifetime Integer, modify
+
+
+
+Wray [Page 39]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ The number of seconds for which the credential
+ will remain valid. If the credential has
+ expired, this parameter will be set to zero.
+ If the implementation does not support
+ credential expiration, the value
+ GSS_C_INDEFINITE will be returned. Specify
+ NULL if not required.
+
+ cred_usage Integer, modify
+ How the credential may be used. One of the
+ following:
+ GSS_C_INITIATE
+ GSS_C_ACCEPT
+ GSS_C_BOTH
+ Specify NULL if not required.
+
+ mechanisms gss_OID_set, modify
+ Set of mechanisms supported by the credential.
+ Specify NULL if not required.
+
+ Function value:
+
+ GSS status code
+
+ GSS_S_COMPLETE Successful completion
+
+ GSS_S_NO_CRED The referenced credentials could not be
+ accessed.
+
+ GSS_S_DEFECTIVE_CREDENTIAL The referenced credentials were
+ invalid.
+
+ GSS_S_CREDENTIALS_EXPIRED The referenced credentials have expired.
+ If the lifetime parameter was not passed as
+ NULL, it will be set to 0.
+
+
+ #ifndef GSSAPI_H_
+ #define GSSAPI_H_
+
+ /*
+ * First, define the platform-dependent types.
+ */
+ typedef <platform-specific> OM_uint32;
+ typedef <platform-specific> gss_ctx_id_t;
+ typedef <platform-specific> gss_cred_id_t;
+ typedef <platform-specific> gss_name_t;
+
+
+
+
+Wray [Page 40]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ /*
+ * Note that a platform supporting the xom.h X/Open header file
+ * may make use of that header for the definitions of OM_uint32
+ * and the structure to which gss_OID_desc equates.
+ */
+
+ typedef struct gss_OID_desc_struct {
+ OM_uint32 length;
+ void *elements;
+ } gss_OID_desc, *gss_OID;
+
+ typedef struct gss_OID_set_desc_struct {
+ int count;
+ gss_OID elements;
+ } gss_OID_set_desc, *gss_OID_set;
+
+ typedef struct gss_buffer_desc_struct {
+ size_t length;
+ void *value;
+ } gss_buffer_desc, *gss_buffer_t;
+
+ typedef struct gss_channel_bindings_struct {
+ OM_uint32 initiator_addrtype;
+ gss_buffer_desc initiator_address;
+ OM_uint32 acceptor_addrtype;
+ gss_buffer_desc acceptor_address;
+ gss_buffer_desc application_data;
+ } *gss_channel_bindings_t;
+
+
+ /*
+ * Six independent flags each of which indicates that a context
+ * supports a specific service option.
+ */
+ #define GSS_C_DELEG_FLAG 1
+ #define GSS_C_MUTUAL_FLAG 2
+ #define GSS_C_REPLAY_FLAG 4
+ #define GSS_C_SEQUENCE_FLAG 8
+ #define GSS_C_CONF_FLAG 16
+ #define GSS_C_INTEG_FLAG 32
+
+
+ /*
+ * Credential usage options
+ */
+ #define GSS_C_BOTH 0
+ #define GSS_C_INITIATE 1
+ #define GSS_C_ACCEPT 2
+
+
+
+Wray [Page 41]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ /*
+ * Status code types for gss_display_status
+ */
+ #define GSS_C_GSS_CODE 1
+ #define GSS_C_MECH_CODE 2
+
+ /*
+ * The constant definitions for channel-bindings address families
+ */
+ #define GSS_C_AF_UNSPEC 0;
+ #define GSS_C_AF_LOCAL 1;
+ #define GSS_C_AF_INET 2;
+ #define GSS_C_AF_IMPLINK 3;
+ #define GSS_C_AF_PUP 4;
+ #define GSS_C_AF_CHAOS 5;
+ #define GSS_C_AF_NS 6;
+ #define GSS_C_AF_NBS 7;
+ #define GSS_C_AF_ECMA 8;
+ #define GSS_C_AF_DATAKIT 9;
+ #define GSS_C_AF_CCITT 10;
+ #define GSS_C_AF_SNA 11;
+ #define GSS_C_AF_DECnet 12;
+ #define GSS_C_AF_DLI 13;
+ #define GSS_C_AF_LAT 14;
+ #define GSS_C_AF_HYLINK 15;
+ #define GSS_C_AF_APPLETALK 16;
+ #define GSS_C_AF_BSC 17;
+ #define GSS_C_AF_DSS 18;
+ #define GSS_C_AF_OSI 19;
+ #define GSS_C_AF_X25 21;
+
+ #define GSS_C_AF_NULLADDR 255;
+
+ #define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
+ #define GSS_C_NULL_OID ((gss_OID) 0)
+ #define GSS_C_NULL_OID_SET ((gss_OID_set) 0)
+ #define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
+ #define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
+ #define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
+ #define GSS_C_EMPTY_BUFFER {0, NULL}
+
+ /*
+ * Define the default Quality of Protection for per-message
+ * services. Note that an implementation that offers multiple
+ * levels of QOP may either reserve a value (for example zero,
+ * as assumed here) to mean "default protection", or alternatively
+ * may simply equate GSS_C_QOP_DEFAULT to a specific explicit QOP
+ * value.
+
+
+
+Wray [Page 42]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ */
+ #define GSS_C_QOP_DEFAULT 0
+
+ /*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+ #define GSS_C_INDEFINITE 0xfffffffful
+
+
+ /* Major status codes */
+
+ #define GSS_S_COMPLETE 0
+
+ /*
+ * Some "helper" definitions to make the status code macros obvious.
+ */
+ #define GSS_C_CALLING_ERROR_OFFSET 24
+ #define GSS_C_ROUTINE_ERROR_OFFSET 16
+ #define GSS_C_SUPPLEMENTARY_OFFSET 0
+ #define GSS_C_CALLING_ERROR_MASK 0377ul
+ #define GSS_C_ROUTINE_ERROR_MASK 0377ul
+ #define GSS_C_SUPPLEMENTARY_MASK 0177777ul
+
+ /*
+ * The macros that test status codes for error conditions
+ */
+ #define GSS_CALLING_ERROR(x) \
+ (x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+ #define GSS_ROUTINE_ERROR(x) \
+ (x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+ #define GSS_SUPPLEMENTARY_INFO(x) \
+ (x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+ #define GSS_ERROR(x) \
+ ((GSS_CALLING_ERROR(x) != 0) || (GSS_ROUTINE_ERROR(x) != 0))
+
+
+ /*
+ * Now the actual status code definitions
+ */
+
+ /*
+ * Calling errors:
+ */
+ #define GSS_S_CALL_INACCESSIBLE_READ \
+ (1ul << GSS_C_CALLING_ERROR_OFFSET)
+ #define GSS_S_CALL_INACCESSIBLE_WRITE \
+ (2ul << GSS_C_CALLING_ERROR_OFFSET)
+
+
+
+Wray [Page 43]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ #define GSS_S_CALL_BAD_STRUCTURE \
+ (3ul << GSS_C_CALLING_ERROR_OFFSET)
+
+ /*
+ * Routine errors:
+ */
+ #define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET)
+ #define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET)
+
+ /*
+ * Supplementary info bits:
+ */
+ #define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
+ #define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
+ #define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
+ #define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
+
+
+ /*
+ * Finally, function prototypes for the GSSAPI routines.
+ */
+
+ OM_uint32 gss_acquire_cred
+ (OM_uint32*, /* minor_status */
+ gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ gss_OID_set, /* desired_mechs */
+ int, /* cred_usage */
+ gss_cred_id_t*, /* output_cred_handle */
+ gss_OID_set*, /* actual_mechs */
+ OM_uint32* /* time_rec */
+ );
+
+ OM_uint32 gss_release_cred,
+ (OM_uint32*, /* minor_status */
+ gss_cred_id_t* /* cred_handle */
+ );
+
+
+
+Wray [Page 44]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ OM_uint32 gss_init_sec_context
+ (OM_uint32*, /* minor_status */
+ gss_cred_id_t, /* claimant_cred_handle */
+ gss_ctx_id_t*, /* context_handle */
+ gss_name_t, /* target_name */
+ gss_OID, /* mech_type */
+ int, /* req_flags */
+ OM_uint32, /* time_req */
+ gss_channel_bindings_t,
+ /* input_chan_bindings */
+ gss_buffer_t, /* input_token */
+ gss_OID*, /* actual_mech_type */
+ gss_buffer_t, /* output_token */
+ int*, /* ret_flags */
+ OM_uint32* /* time_rec */
+ );
+
+ OM_uint32 gss_accept_sec_context
+ (OM_uint32*, /* minor_status */
+ gss_ctx_id_t*, /* context_handle */
+ gss_cred_id_t, /* verifier_cred_handle */
+ gss_buffer_t, /* input_token_buffer */
+ gss_channel_bindings_t,
+ /* input_chan_bindings */
+ gss_name_t*, /* src_name */
+ gss_OID*, /* mech_type */
+ gss_buffer_t, /* output_token */
+ int*, /* ret_flags */
+ OM_uint32*, /* time_rec */
+ gss_cred_id_t* /* delegated_cred_handle */
+ );
+
+ OM_uint32 gss_process_context_token
+ (OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t /* token_buffer */
+ );
+
+ OM_uint32 gss_delete_sec_context
+ (OM_uint32*, /* minor_status */
+ gss_ctx_id_t*, /* context_handle */
+ gss_buffer_t /* output_token */
+ );
+
+
+
+
+
+
+
+
+Wray [Page 45]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ OM_uint32 gss_context_time
+ (OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ OM_uint32* /* time_rec */
+ );
+
+ OM_uint32 gss_sign
+ (OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* qop_req */
+ gss_buffer_t, /* message_buffer */
+ gss_buffer_t /* message_token */
+ );
+
+ OM_uitn32 gss_verify
+ (OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t, /* message_buffer */
+ gss_buffer_t, /* token_buffer */
+ int* /* qop_state */
+ );
+
+ OM_uint32 gss_seal
+ (OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ int, /* qop_req */
+ gss_buffer_t, /* input_message_buffer */
+ int*, /* conf_state */
+ gss_buffer_t /* output_message_buffer */
+ );
+
+ OM_uint32 gss_unseal
+ (OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t, /* input_message_buffer */
+ gss_buffer_t, /* output_message_buffer */
+ int*, /* conf_state */
+ int* /* qop_state */
+ );
+
+
+
+
+
+
+
+
+
+
+
+Wray [Page 46]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ OM_uint32 gss_display_status
+ (OM_uint32*, /* minor_status */
+ OM_uint32, /* status_value */
+ int, /* status_type */
+ gss_OID, /* mech_type */
+ int*, /* message_context */
+ gss_buffer_t /* status_string */
+ );
+
+ OM_uint32 gss_indicate_mechs
+ (OM_uint32*, /* minor_status */
+ gss_OID_set* /* mech_set */
+ );
+
+ OM_uint32 gss_compare_name
+ (OM_uint32*, /* minor_status */
+ gss_name_t, /* name1 */
+ gss_name_t, /* name2 */
+ int* /* name_equal */
+ );
+
+ OM_uint32 gss_display_name,
+ (OM_uint32*, /* minor_status */
+ gss_name_t, /* input_name */
+ gss_buffer_t, /* output_name_buffer */
+ gss_OID* /* output_name_type */
+ );
+
+ OM_uint32 gss_import_name
+ (OM_uint32*, /* minor_status */
+ gss_buffer_t, /* input_name_buffer */
+ gss_OID, /* input_name_type */
+ gss_name_t* /* output_name */
+ );
+
+ OM_uint32 gss_release_name
+ (OM_uint32*, /* minor_status */
+ gss_name_t* /* input_name */
+ );
+
+ OM_uint32 gss_release_buffer
+ (OM_uint32*, /* minor_status */
+ gss_buffer_t /* buffer */
+ );
+
+ OM_uint32 gss_release_oid_set
+ (OM_uint32*, /* minor_status */
+ gss_OID_set* /* set */
+
+
+
+Wray [Page 47]
+
+RFC 1509 GSSAPI - Overview and C bindings September 1993
+
+
+ );
+
+ OM_uint32 gss_inquire_cred
+ (OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* cred_handle */
+ gss_name_t *, /* name */
+ OM_uint32 *, /* lifetime */
+ int *, /* cred_usage */
+ gss_OID_set * /* mechanisms */
+ );
+
+
+
+ #endif /* GSSAPI_H_ */
+
+References
+
+ [1] Linn, J., "Generic Security Service Application Program
+ Interface", RFC 1508, Geer Zolot Associate, September 1993.
+
+ [2] "OSI Object Management API Specification, Version 2.0 t", X.400
+ API Association & X/Open Company Limited, August 24, 1990.
+ Specification of datatypes and routines for manipulating
+ information objects.
+
+Security Considerations
+
+ Security issues are discussed throughout this memo.
+
+Author's Address
+
+ John Wray
+ Digital Equipment Corporation
+ 550 King Street, LKG2-2/AA6
+ Littleton, MA 01460
+ USA
+
+ Phone: +1-508-486-5210
+ EMail: Wray@tuxedo.enet.dec.com
+
+
+
+
+
+
+
+
+
+
+
+
+Wray [Page 48]
+ \ No newline at end of file
diff --git a/crypto/heimdal/doc/standardisation/rfc1510.txt b/crypto/heimdal/doc/standardisation/rfc1510.txt
new file mode 100644
index 000000000000..bc810cc506fa
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/rfc1510.txt
@@ -0,0 +1,6275 @@
+
+
+
+
+
+
+Network Working Group J. Kohl
+Request for Comments: 1510 Digital Equipment Corporation
+ C. Neuman
+ ISI
+ September 1993
+
+
+ The Kerberos Network Authentication Service (V5)
+
+Status of this Memo
+
+ This RFC specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" for the standardization state and status
+ of this protocol. Distribution of this memo is unlimited.
+
+Abstract
+
+ This document gives an overview and specification of Version 5 of the
+ protocol for the Kerberos network authentication system. Version 4,
+ described elsewhere [1,2], is presently in production use at MIT's
+ Project Athena, and at other Internet sites.
+
+Overview
+
+ Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos,
+ Moira, and Zephyr are trademarks of the Massachusetts Institute of
+ Technology (MIT). No commercial use of these trademarks may be made
+ without prior written permission of MIT.
+
+ This RFC describes the concepts and model upon which the Kerberos
+ network authentication system is based. It also specifies Version 5
+ of the Kerberos protocol.
+
+ The motivations, goals, assumptions, and rationale behind most design
+ decisions are treated cursorily; for Version 4 they are fully
+ described in the Kerberos portion of the Athena Technical Plan [1].
+ The protocols are under review, and are not being submitted for
+ consideration as an Internet standard at this time. Comments are
+ encouraged. Requests for addition to an electronic mailing list for
+ discussion of Kerberos, kerberos@MIT.EDU, may be addressed to
+ kerberos-request@MIT.EDU. This mailing list is gatewayed onto the
+ Usenet as the group comp.protocols.kerberos. Requests for further
+ information, including documents and code availability, may be sent
+ to info-kerberos@MIT.EDU.
+
+
+
+
+
+Kohl & Neuman [Page 1]
+
+RFC 1510 Kerberos September 1993
+
+
+Background
+
+ The Kerberos model is based in part on Needham and Schroeder's
+ trusted third-party authentication protocol [3] and on modifications
+ suggested by Denning and Sacco [4]. The original design and
+ implementation of Kerberos Versions 1 through 4 was the work of two
+ former Project Athena staff members, Steve Miller of Digital
+ Equipment Corporation and Clifford Neuman (now at the Information
+ Sciences Institute of the University of Southern California), along
+ with Jerome Saltzer, Technical Director of Project Athena, and
+ Jeffrey Schiller, MIT Campus Network Manager. Many other members of
+ Project Athena have also contributed to the work on Kerberos.
+ Version 4 is publicly available, and has seen wide use across the
+ Internet.
+
+ Version 5 (described in this document) has evolved from Version 4
+ based on new requirements and desires for features not available in
+ Version 4. Details on the differences between Kerberos Versions 4
+ and 5 can be found in [5].
+
+Table of Contents
+
+ 1. Introduction ....................................... 5
+ 1.1. Cross-Realm Operation ............................ 7
+ 1.2. Environmental assumptions ........................ 8
+ 1.3. Glossary of terms ................................ 9
+ 2. Ticket flag uses and requests ...................... 12
+ 2.1. Initial and pre-authenticated tickets ............ 12
+ 2.2. Invalid tickets .................................. 12
+ 2.3. Renewable tickets ................................ 12
+ 2.4. Postdated tickets ................................ 13
+ 2.5. Proxiable and proxy tickets ...................... 14
+ 2.6. Forwardable tickets .............................. 15
+ 2.7. Other KDC options ................................ 15
+ 3. Message Exchanges .................................. 16
+ 3.1. The Authentication Service Exchange .............. 16
+ 3.1.1. Generation of KRB_AS_REQ message ............... 17
+ 3.1.2. Receipt of KRB_AS_REQ message .................. 17
+ 3.1.3. Generation of KRB_AS_REP message ............... 17
+ 3.1.4. Generation of KRB_ERROR message ................ 19
+ 3.1.5. Receipt of KRB_AS_REP message .................. 19
+ 3.1.6. Receipt of KRB_ERROR message ................... 20
+ 3.2. The Client/Server Authentication Exchange ........ 20
+ 3.2.1. The KRB_AP_REQ message ......................... 20
+ 3.2.2. Generation of a KRB_AP_REQ message ............. 20
+ 3.2.3. Receipt of KRB_AP_REQ message .................. 21
+ 3.2.4. Generation of a KRB_AP_REP message ............. 23
+ 3.2.5. Receipt of KRB_AP_REP message .................. 23
+
+
+
+Kohl & Neuman [Page 2]
+
+RFC 1510 Kerberos September 1993
+
+
+ 3.2.6. Using the encryption key ....................... 24
+ 3.3. The Ticket-Granting Service (TGS) Exchange ....... 24
+ 3.3.1. Generation of KRB_TGS_REQ message .............. 25
+ 3.3.2. Receipt of KRB_TGS_REQ message ................. 26
+ 3.3.3. Generation of KRB_TGS_REP message .............. 27
+ 3.3.3.1. Encoding the transited field ................. 29
+ 3.3.4. Receipt of KRB_TGS_REP message ................. 31
+ 3.4. The KRB_SAFE Exchange ............................ 31
+ 3.4.1. Generation of a KRB_SAFE message ............... 31
+ 3.4.2. Receipt of KRB_SAFE message .................... 32
+ 3.5. The KRB_PRIV Exchange ............................ 33
+ 3.5.1. Generation of a KRB_PRIV message ............... 33
+ 3.5.2. Receipt of KRB_PRIV message .................... 33
+ 3.6. The KRB_CRED Exchange ............................ 34
+ 3.6.1. Generation of a KRB_CRED message ............... 34
+ 3.6.2. Receipt of KRB_CRED message .................... 34
+ 4. The Kerberos Database .............................. 35
+ 4.1. Database contents ................................ 35
+ 4.2. Additional fields ................................ 36
+ 4.3. Frequently Changing Fields ....................... 37
+ 4.4. Site Constants ................................... 37
+ 5. Message Specifications ............................. 38
+ 5.1. ASN.1 Distinguished Encoding Representation ...... 38
+ 5.2. ASN.1 Base Definitions ........................... 38
+ 5.3. Tickets and Authenticators ....................... 42
+ 5.3.1. Tickets ........................................ 42
+ 5.3.2. Authenticators ................................. 47
+ 5.4. Specifications for the AS and TGS exchanges ...... 49
+ 5.4.1. KRB_KDC_REQ definition ......................... 49
+ 5.4.2. KRB_KDC_REP definition ......................... 56
+ 5.5. Client/Server (CS) message specifications ........ 58
+ 5.5.1. KRB_AP_REQ definition .......................... 58
+ 5.5.2. KRB_AP_REP definition .......................... 60
+ 5.5.3. Error message reply ............................ 61
+ 5.6. KRB_SAFE message specification ................... 61
+ 5.6.1. KRB_SAFE definition ............................ 61
+ 5.7. KRB_PRIV message specification ................... 62
+ 5.7.1. KRB_PRIV definition ............................ 62
+ 5.8. KRB_CRED message specification ................... 63
+ 5.8.1. KRB_CRED definition ............................ 63
+ 5.9. Error message specification ...................... 65
+ 5.9.1. KRB_ERROR definition ........................... 66
+ 6. Encryption and Checksum Specifications ............. 67
+ 6.1. Encryption Specifications ........................ 68
+ 6.2. Encryption Keys .................................. 71
+ 6.3. Encryption Systems ............................... 71
+ 6.3.1. The NULL Encryption System (null) .............. 71
+ 6.3.2. DES in CBC mode with a CRC-32 checksum (descbc-crc)71
+
+
+
+Kohl & Neuman [Page 3]
+
+RFC 1510 Kerberos September 1993
+
+
+ 6.3.3. DES in CBC mode with an MD4 checksum (descbc-md4) 72
+ 6.3.4. DES in CBC mode with an MD5 checksum (descbc-md5) 72
+ 6.4. Checksums ........................................ 74
+ 6.4.1. The CRC-32 Checksum (crc32) .................... 74
+ 6.4.2. The RSA MD4 Checksum (rsa-md4) ................. 75
+ 6.4.3. RSA MD4 Cryptographic Checksum Using DES
+ (rsa-md4-des) ......................................... 75
+ 6.4.4. The RSA MD5 Checksum (rsa-md5) ................. 76
+ 6.4.5. RSA MD5 Cryptographic Checksum Using DES
+ (rsa-md5-des) ......................................... 76
+ 6.4.6. DES cipher-block chained checksum (des-mac)
+ 6.4.7. RSA MD4 Cryptographic Checksum Using DES
+ alternative (rsa-md4-des-k) ........................... 77
+ 6.4.8. DES cipher-block chained checksum alternative
+ (des-mac-k) ........................................... 77
+ 7. Naming Constraints ................................. 78
+ 7.1. Realm Names ...................................... 77
+ 7.2. Principal Names .................................. 79
+ 7.2.1. Name of server principals ...................... 80
+ 8. Constants and other defined values ................. 80
+ 8.1. Host address types ............................... 80
+ 8.2. KDC messages ..................................... 81
+ 8.2.1. IP transport ................................... 81
+ 8.2.2. OSI transport .................................. 82
+ 8.2.3. Name of the TGS ................................ 82
+ 8.3. Protocol constants and associated values ......... 82
+ 9. Interoperability requirements ...................... 86
+ 9.1. Specification 1 .................................. 86
+ 9.2. Recommended KDC values ........................... 88
+ 10. Acknowledgments ................................... 88
+ 11. References ........................................ 89
+ 12. Security Considerations ........................... 90
+ 13. Authors' Addresses ................................ 90
+ A. Pseudo-code for protocol processing ................ 91
+ A.1. KRB_AS_REQ generation ............................ 91
+ A.2. KRB_AS_REQ verification and KRB_AS_REP generation 92
+ A.3. KRB_AS_REP verification .......................... 95
+ A.4. KRB_AS_REP and KRB_TGS_REP common checks ......... 96
+ A.5. KRB_TGS_REQ generation ........................... 97
+ A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation 98
+ A.7. KRB_TGS_REP verification ......................... 104
+ A.8. Authenticator generation ......................... 104
+ A.9. KRB_AP_REQ generation ............................ 105
+ A.10. KRB_AP_REQ verification ......................... 105
+ A.11. KRB_AP_REP generation ........................... 106
+ A.12. KRB_AP_REP verification ......................... 107
+ A.13. KRB_SAFE generation ............................. 107
+ A.14. KRB_SAFE verification ........................... 108
+
+
+
+Kohl & Neuman [Page 4]
+
+RFC 1510 Kerberos September 1993
+
+
+ A.15. KRB_SAFE and KRB_PRIV common checks ............. 108
+ A.16. KRB_PRIV generation ............................. 109
+ A.17. KRB_PRIV verification ........................... 110
+ A.18. KRB_CRED generation ............................. 110
+ A.19. KRB_CRED verification ........................... 111
+ A.20. KRB_ERROR generation ............................ 112
+
+1. Introduction
+
+ Kerberos provides a means of verifying the identities of principals,
+ (e.g., a workstation user or a network server) on an open
+ (unprotected) network. This is accomplished without relying on
+ authentication by the host operating system, without basing trust on
+ host addresses, without requiring physical security of all the hosts
+ on the network, and under the assumption that packets traveling along
+ the network can be read, modified, and inserted at will. (Note,
+ however, that many applications use Kerberos' functions only upon the
+ initiation of a stream-based network connection, and assume the
+ absence of any "hijackers" who might subvert such a connection. Such
+ use implicitly trusts the host addresses involved.) Kerberos
+ performs authentication under these conditions as a trusted third-
+ party authentication service by using conventional cryptography,
+ i.e., shared secret key. (shared secret key - Secret and private are
+ often used interchangeably in the literature. In our usage, it takes
+ two (or more) to share a secret, thus a shared DES key is a secret
+ key. Something is only private when no one but its owner knows it.
+ Thus, in public key cryptosystems, one has a public and a private
+ key.)
+
+ The authentication process proceeds as follows: A client sends a
+ request to the authentication server (AS) requesting "credentials"
+ for a given server. The AS responds with these credentials,
+ encrypted in the client's key. The credentials consist of 1) a
+ "ticket" for the server and 2) a temporary encryption key (often
+ called a "session key"). The client transmits the ticket (which
+ contains the client's identity and a copy of the session key, all
+ encrypted in the server's key) to the server. The session key (now
+ shared by the client and server) is used to authenticate the client,
+ and may optionally be used to authenticate the server. It may also
+ be used to encrypt further communication between the two parties or
+ to exchange a separate sub-session key to be used to encrypt further
+ communication.
+
+ The implementation consists of one or more authentication servers
+ running on physically secure hosts. The authentication servers
+ maintain a database of principals (i.e., users and servers) and their
+ secret keys. Code libraries provide encryption and implement the
+ Kerberos protocol. In order to add authentication to its
+
+
+
+Kohl & Neuman [Page 5]
+
+RFC 1510 Kerberos September 1993
+
+
+ transactions, a typical network application adds one or two calls to
+ the Kerberos library, which results in the transmission of the
+ necessary messages to achieve authentication.
+
+ The Kerberos protocol consists of several sub-protocols (or
+ exchanges). There are two methods by which a client can ask a
+ Kerberos server for credentials. In the first approach, the client
+ sends a cleartext request for a ticket for the desired server to the
+ AS. The reply is sent encrypted in the client's secret key. Usually
+ this request is for a ticket-granting ticket (TGT) which can later be
+ used with the ticket-granting server (TGS). In the second method,
+ the client sends a request to the TGS. The client sends the TGT to
+ the TGS in the same manner as if it were contacting any other
+ application server which requires Kerberos credentials. The reply is
+ encrypted in the session key from the TGT.
+
+ Once obtained, credentials may be used to verify the identity of the
+ principals in a transaction, to ensure the integrity of messages
+ exchanged between them, or to preserve privacy of the messages. The
+ application is free to choose whatever protection may be necessary.
+
+ To verify the identities of the principals in a transaction, the
+ client transmits the ticket to the server. Since the ticket is sent
+ "in the clear" (parts of it are encrypted, but this encryption
+ doesn't thwart replay) and might be intercepted and reused by an
+ attacker, additional information is sent to prove that the message
+ was originated by the principal to whom the ticket was issued. This
+ information (called the authenticator) is encrypted in the session
+ key, and includes a timestamp. The timestamp proves that the message
+ was recently generated and is not a replay. Encrypting the
+ authenticator in the session key proves that it was generated by a
+ party possessing the session key. Since no one except the requesting
+ principal and the server know the session key (it is never sent over
+ the network in the clear) this guarantees the identity of the client.
+
+ The integrity of the messages exchanged between principals can also
+ be guaranteed using the session key (passed in the ticket and
+ contained in the credentials). This approach provides detection of
+ both replay attacks and message stream modification attacks. It is
+ accomplished by generating and transmitting a collision-proof
+ checksum (elsewhere called a hash or digest function) of the client's
+ message, keyed with the session key. Privacy and integrity of the
+ messages exchanged between principals can be secured by encrypting
+ the data to be passed using the session key passed in the ticket, and
+ contained in the credentials.
+
+ The authentication exchanges mentioned above require read-only access
+ to the Kerberos database. Sometimes, however, the entries in the
+
+
+
+Kohl & Neuman [Page 6]
+
+RFC 1510 Kerberos September 1993
+
+
+ database must be modified, such as when adding new principals or
+ changing a principal's key. This is done using a protocol between a
+ client and a third Kerberos server, the Kerberos Administration
+ Server (KADM). The administration protocol is not described in this
+ document. There is also a protocol for maintaining multiple copies of
+ the Kerberos database, but this can be considered an implementation
+ detail and may vary to support different database technologies.
+
+1.1. Cross-Realm Operation
+
+ The Kerberos protocol is designed to operate across organizational
+ boundaries. A client in one organization can be authenticated to a
+ server in another. Each organization wishing to run a Kerberos
+ server establishes its own "realm". The name of the realm in which a
+ client is registered is part of the client's name, and can be used by
+ the end-service to decide whether to honor a request.
+
+ By establishing "inter-realm" keys, the administrators of two realms
+ can allow a client authenticated in the local realm to use its
+ authentication remotely (Of course, with appropriate permission the
+ client could arrange registration of a separately-named principal in
+ a remote realm, and engage in normal exchanges with that realm's
+ services. However, for even small numbers of clients this becomes
+ cumbersome, and more automatic methods as described here are
+ necessary). The exchange of inter-realm keys (a separate key may be
+ used for each direction) registers the ticket-granting service of
+ each realm as a principal in the other realm. A client is then able
+ to obtain a ticket-granting ticket for the remote realm's ticket-
+ granting service from its local realm. When that ticket-granting
+ ticket is used, the remote ticket-granting service uses the inter-
+ realm key (which usually differs from its own normal TGS key) to
+ decrypt the ticket-granting ticket, and is thus certain that it was
+ issued by the client's own TGS. Tickets issued by the remote ticket-
+ granting service will indicate to the end-service that the client was
+ authenticated from another realm.
+
+ A realm is said to communicate with another realm if the two realms
+ share an inter-realm key, or if the local realm shares an inter-realm
+ key with an intermediate realm that communicates with the remote
+ realm. An authentication path is the sequence of intermediate realms
+ that are transited in communicating from one realm to another.
+
+ Realms are typically organized hierarchically. Each realm shares a
+ key with its parent and a different key with each child. If an
+ inter-realm key is not directly shared by two realms, the
+ hierarchical organization allows an authentication path to be easily
+ constructed. If a hierarchical organization is not used, it may be
+ necessary to consult some database in order to construct an
+
+
+
+Kohl & Neuman [Page 7]
+
+RFC 1510 Kerberos September 1993
+
+
+ authentication path between realms.
+
+ Although realms are typically hierarchical, intermediate realms may
+ be bypassed to achieve cross-realm authentication through alternate
+ authentication paths (these might be established to make
+ communication between two realms more efficient). It is important
+ for the end-service to know which realms were transited when deciding
+ how much faith to place in the authentication process. To facilitate
+ this decision, a field in each ticket contains the names of the
+ realms that were involved in authenticating the client.
+
+1.2. Environmental assumptions
+
+ Kerberos imposes a few assumptions on the environment in which it can
+ properly function:
+
+ + "Denial of service" attacks are not solved with Kerberos. There
+ are places in these protocols where an intruder intruder can
+ prevent an application from participating in the proper
+ authentication steps. Detection and solution of such attacks
+ (some of which can appear to be not-uncommon "normal" failure
+ modes for the system) is usually best left to the human
+ administrators and users.
+
+ + Principals must keep their secret keys secret. If an intruder
+ somehow steals a principal's key, it will be able to masquerade
+ as that principal or impersonate any server to the legitimate
+ principal.
+
+ + "Password guessing" attacks are not solved by Kerberos. If a
+ user chooses a poor password, it is possible for an attacker to
+ successfully mount an offline dictionary attack by repeatedly
+ attempting to decrypt, with successive entries from a
+ dictionary, messages obtained which are encrypted under a key
+ derived from the user's password.
+
+ + Each host on the network must have a clock which is "loosely
+ synchronized" to the time of the other hosts; this
+ synchronization is used to reduce the bookkeeping needs of
+ application servers when they do replay detection. The degree
+ of "looseness" can be configured on a per-server basis. If the
+ clocks are synchronized over the network, the clock
+ synchronization protocol must itself be secured from network
+ attackers.
+
+ + Principal identifiers are not recycled on a short-term basis. A
+ typical mode of access control will use access control lists
+ (ACLs) to grant permissions to particular principals. If a
+
+
+
+Kohl & Neuman [Page 8]
+
+RFC 1510 Kerberos September 1993
+
+
+ stale ACL entry remains for a deleted principal and the
+ principal identifier is reused, the new principal will inherit
+ rights specified in the stale ACL entry. By not re-using
+ principal identifiers, the danger of inadvertent access is
+ removed.
+
+1.3. Glossary of terms
+
+ Below is a list of terms used throughout this document.
+
+
+ Authentication Verifying the claimed identity of a
+ principal.
+
+
+ Authentication header A record containing a Ticket and an
+ Authenticator to be presented to a
+ server as part of the authentication
+ process.
+
+
+ Authentication path A sequence of intermediate realms transited
+ in the authentication process when
+ communicating from one realm to another.
+
+ Authenticator A record containing information that can
+ be shown to have been recently generated
+ using the session key known only by the
+ client and server.
+
+
+ Authorization The process of determining whether a
+ client may use a service, which objects
+ the client is allowed to access, and the
+ type of access allowed for each.
+
+
+ Capability A token that grants the bearer permission
+ to access an object or service. In
+ Kerberos, this might be a ticket whose
+ use is restricted by the contents of the
+ authorization data field, but which
+ lists no network addresses, together
+ with the session key necessary to use
+ the ticket.
+
+
+
+
+
+
+Kohl & Neuman [Page 9]
+
+RFC 1510 Kerberos September 1993
+
+
+ Ciphertext The output of an encryption function.
+ Encryption transforms plaintext into
+ ciphertext.
+
+
+ Client A process that makes use of a network
+ service on behalf of a user. Note that
+ in some cases a Server may itself be a
+ client of some other server (e.g., a
+ print server may be a client of a file
+ server).
+
+
+ Credentials A ticket plus the secret session key
+ necessary to successfully use that
+ ticket in an authentication exchange.
+
+
+ KDC Key Distribution Center, a network service
+ that supplies tickets and temporary
+ session keys; or an instance of that
+ service or the host on which it runs.
+ The KDC services both initial ticket and
+ ticket-granting ticket requests. The
+ initial ticket portion is sometimes
+ referred to as the Authentication Server
+ (or service). The ticket-granting
+ ticket portion is sometimes referred to
+ as the ticket-granting server (or service).
+
+ Kerberos Aside from the 3-headed dog guarding
+ Hades, the name given to Project
+ Athena's authentication service, the
+ protocol used by that service, or the
+ code used to implement the authentication
+ service.
+
+
+ Plaintext The input to an encryption function or
+ the output of a decryption function.
+ Decryption transforms ciphertext into
+ plaintext.
+
+
+ Principal A uniquely named client or server
+ instance that participates in a network
+ communication.
+
+
+
+
+Kohl & Neuman [Page 10]
+
+RFC 1510 Kerberos September 1993
+
+
+ Principal identifier The name used to uniquely identify each
+ different principal.
+
+
+ Seal To encipher a record containing several
+ fields in such a way that the fields
+ cannot be individually replaced without
+ either knowledge of the encryption key
+ or leaving evidence of tampering.
+
+
+ Secret key An encryption key shared by a principal
+ and the KDC, distributed outside the
+ bounds of the system, with a long lifetime.
+ In the case of a human user's
+ principal, the secret key is derived
+ from a password.
+
+
+ Server A particular Principal which provides a
+ resource to network clients.
+
+
+ Service A resource provided to network clients;
+ often provided by more than one server
+ (for example, remote file service).
+
+
+ Session key A temporary encryption key used between
+ two principals, with a lifetime limited
+ to the duration of a single login "session".
+
+
+ Sub-session key A temporary encryption key used between
+ two principals, selected and exchanged
+ by the principals using the session key,
+ and with a lifetime limited to the duration
+ of a single association.
+
+
+ Ticket A record that helps a client authenticate
+ itself to a server; it contains the
+ client's identity, a session key, a
+ timestamp, and other information, all
+ sealed using the server's secret key.
+ It only serves to authenticate a client
+ when presented along with a fresh
+ Authenticator.
+
+
+
+Kohl & Neuman [Page 11]
+
+RFC 1510 Kerberos September 1993
+
+
+2. Ticket flag uses and requests
+
+ Each Kerberos ticket contains a set of flags which are used to
+ indicate various attributes of that ticket. Most flags may be
+ requested by a client when the ticket is obtained; some are
+ automatically turned on and off by a Kerberos server as required.
+ The following sections explain what the various flags mean, and gives
+ examples of reasons to use such a flag.
+
+2.1. Initial and pre-authenticated tickets
+
+ The INITIAL flag indicates that a ticket was issued using the AS
+ protocol and not issued based on a ticket-granting ticket.
+ Application servers that want to require the knowledge of a client's
+ secret key (e.g., a passwordchanging program) can insist that this
+ flag be set in any tickets they accept, and thus be assured that the
+ client's key was recently presented to the application client.
+
+ The PRE-AUTHENT and HW-AUTHENT flags provide addition information
+ about the initial authentication, regardless of whether the current
+ ticket was issued directly (in which case INITIAL will also be set)
+ or issued on the basis of a ticket-granting ticket (in which case the
+ INITIAL flag is clear, but the PRE-AUTHENT and HW-AUTHENT flags are
+ carried forward from the ticket-granting ticket).
+
+2.2. Invalid tickets
+
+ The INVALID flag indicates that a ticket is invalid. Application
+ servers must reject tickets which have this flag set. A postdated
+ ticket will usually be issued in this form. Invalid tickets must be
+ validated by the KDC before use, by presenting them to the KDC in a
+ TGS request with the VALIDATE option specified. The KDC will only
+ validate tickets after their starttime has passed. The validation is
+ required so that postdated tickets which have been stolen before
+ their starttime can be rendered permanently invalid (through a hot-
+ list mechanism).
+
+2.3. Renewable tickets
+
+ Applications may desire to hold tickets which can be valid for long
+ periods of time. However, this can expose their credentials to
+ potential theft for equally long periods, and those stolen
+ credentials would be valid until the expiration time of the
+ ticket(s). Simply using shortlived tickets and obtaining new ones
+ periodically would require the client to have long-term access to its
+ secret key, an even greater risk. Renewable tickets can be used to
+ mitigate the consequences of theft. Renewable tickets have two
+ "expiration times": the first is when the current instance of the
+
+
+
+Kohl & Neuman [Page 12]
+
+RFC 1510 Kerberos September 1993
+
+
+ ticket expires, and the second is the latest permissible value for an
+ individual expiration time. An application client must periodically
+ (i.e., before it expires) present a renewable ticket to the KDC, with
+ the RENEW option set in the KDC request. The KDC will issue a new
+ ticket with a new session key and a later expiration time. All other
+ fields of the ticket are left unmodified by the renewal process.
+ When the latest permissible expiration time arrives, the ticket
+ expires permanently. At each renewal, the KDC may consult a hot-list
+ to determine if the ticket had been reported stolen since its last
+ renewal; it will refuse to renew such stolen tickets, and thus the
+ usable lifetime of stolen tickets is reduced.
+
+ The RENEWABLE flag in a ticket is normally only interpreted by the
+ ticket-granting service (discussed below in section 3.3). It can
+ usually be ignored by application servers. However, some
+ particularly careful application servers may wish to disallow
+ renewable tickets.
+
+ If a renewable ticket is not renewed by its expiration time, the KDC
+ will not renew the ticket. The RENEWABLE flag is reset by default,
+ but a client may request it be set by setting the RENEWABLE option
+ in the KRB_AS_REQ message. If it is set, then the renew-till field
+ in the ticket contains the time after which the ticket may not be
+ renewed.
+
+2.4. Postdated tickets
+
+ Applications may occasionally need to obtain tickets for use much
+ later, e.g., a batch submission system would need tickets to be valid
+ at the time the batch job is serviced. However, it is dangerous to
+ hold valid tickets in a batch queue, since they will be on-line
+ longer and more prone to theft. Postdated tickets provide a way to
+ obtain these tickets from the KDC at job submission time, but to
+ leave them "dormant" until they are activated and validated by a
+ further request of the KDC. If a ticket theft were reported in the
+ interim, the KDC would refuse to validate the ticket, and the thief
+ would be foiled.
+
+ The MAY-POSTDATE flag in a ticket is normally only interpreted by the
+ ticket-granting service. It can be ignored by application servers.
+ This flag must be set in a ticket-granting ticket in order to issue a
+ postdated ticket based on the presented ticket. It is reset by
+ default; it may be requested by a client by setting the ALLOW-
+ POSTDATE option in the KRB_AS_REQ message. This flag does not allow
+ a client to obtain a postdated ticket-granting ticket; postdated
+ ticket-granting tickets can only by obtained by requesting the
+ postdating in the KRB_AS_REQ message. The life (endtime-starttime)
+ of a postdated ticket will be the remaining life of the ticket-
+
+
+
+Kohl & Neuman [Page 13]
+
+RFC 1510 Kerberos September 1993
+
+
+ granting ticket at the time of the request, unless the RENEWABLE
+ option is also set, in which case it can be the full life (endtime-
+ starttime) of the ticket-granting ticket. The KDC may limit how far
+ in the future a ticket may be postdated.
+
+ The POSTDATED flag indicates that a ticket has been postdated. The
+ application server can check the authtime field in the ticket to see
+ when the original authentication occurred. Some services may choose
+ to reject postdated tickets, or they may only accept them within a
+ certain period after the original authentication. When the KDC issues
+ a POSTDATED ticket, it will also be marked as INVALID, so that the
+ application client must present the ticket to the KDC to be validated
+ before use.
+
+2.5. Proxiable and proxy tickets
+
+ At times it may be necessary for a principal to allow a service to
+ perform an operation on its behalf. The service must be able to take
+ on the identity of the client, but only for a particular purpose. A
+ principal can allow a service to take on the principal's identity for
+ a particular purpose by granting it a proxy.
+
+ The PROXIABLE flag in a ticket is normally only interpreted by the
+ ticket-granting service. It can be ignored by application servers.
+ When set, this flag tells the ticket-granting server that it is OK to
+ issue a new ticket (but not a ticket-granting ticket) with a
+ different network address based on this ticket. This flag is set by
+ default.
+
+ This flag allows a client to pass a proxy to a server to perform a
+ remote request on its behalf, e.g., a print service client can give
+ the print server a proxy to access the client's files on a particular
+ file server in order to satisfy a print request.
+
+ In order to complicate the use of stolen credentials, Kerberos
+ tickets are usually valid from only those network addresses
+ specifically included in the ticket (It is permissible to request or
+ issue tickets with no network addresses specified, but we do not
+ recommend it). For this reason, a client wishing to grant a proxy
+ must request a new ticket valid for the network address of the
+ service to be granted the proxy.
+
+ The PROXY flag is set in a ticket by the TGS when it issues a
+ proxy ticket. Application servers may check this flag and require
+ additional authentication from the agent presenting the proxy in
+ order to provide an audit trail.
+
+
+
+
+
+Kohl & Neuman [Page 14]
+
+RFC 1510 Kerberos September 1993
+
+
+2.6. Forwardable tickets
+
+ Authentication forwarding is an instance of the proxy case where the
+ service is granted complete use of the client's identity. An example
+ where it might be used is when a user logs in to a remote system and
+ wants authentication to work from that system as if the login were
+ local.
+
+ The FORWARDABLE flag in a ticket is normally only interpreted by the
+ ticket-granting service. It can be ignored by application servers.
+ The FORWARDABLE flag has an interpretation similar to that of the
+ PROXIABLE flag, except ticket-granting tickets may also be issued
+ with different network addresses. This flag is reset by default, but
+ users may request that it be set by setting the FORWARDABLE option in
+ the AS request when they request their initial ticket-granting
+ ticket.
+
+ This flag allows for authentication forwarding without requiring the
+ user to enter a password again. If the flag is not set, then
+ authentication forwarding is not permitted, but the same end result
+ can still be achieved if the user engages in the AS exchange with the
+ requested network addresses and supplies a password.
+
+ The FORWARDED flag is set by the TGS when a client presents a ticket
+ with the FORWARDABLE flag set and requests it be set by specifying
+ the FORWARDED KDC option and supplying a set of addresses for the new
+ ticket. It is also set in all tickets issued based on tickets with
+ the FORWARDED flag set. Application servers may wish to process
+ FORWARDED tickets differently than non-FORWARDED tickets.
+
+2.7. Other KDC options
+
+ There are two additional options which may be set in a client's
+ request of the KDC. The RENEWABLE-OK option indicates that the
+ client will accept a renewable ticket if a ticket with the requested
+ life cannot otherwise be provided. If a ticket with the requested
+ life cannot be provided, then the KDC may issue a renewable ticket
+ with a renew-till equal to the the requested endtime. The value of
+ the renew-till field may still be adjusted by site-determined limits
+ or limits imposed by the individual principal or server.
+
+ The ENC-TKT-IN-SKEY option is honored only by the ticket-granting
+ service. It indicates that the to-be-issued ticket for the end
+ server is to be encrypted in the session key from the additional
+ ticket-granting ticket provided with the request. See section 3.3.3
+ for specific details.
+
+
+
+
+
+Kohl & Neuman [Page 15]
+
+RFC 1510 Kerberos September 1993
+
+
+3. Message Exchanges
+
+ The following sections describe the interactions between network
+ clients and servers and the messages involved in those exchanges.
+
+3.1. The Authentication Service Exchange
+
+ Summary
+
+ Message direction Message type Section
+ 1. Client to Kerberos KRB_AS_REQ 5.4.1
+ 2. Kerberos to client KRB_AS_REP or 5.4.2
+ KRB_ERROR 5.9.1
+
+ The Authentication Service (AS) Exchange between the client and the
+ Kerberos Authentication Server is usually initiated by a client when
+ it wishes to obtain authentication credentials for a given server but
+ currently holds no credentials. The client's secret key is used for
+ encryption and decryption. This exchange is typically used at the
+ initiation of a login session, to obtain credentials for a Ticket-
+ Granting Server, which will subsequently be used to obtain
+ credentials for other servers (see section 3.3) without requiring
+ further use of the client's secret key. This exchange is also used
+ to request credentials for services which must not be mediated
+ through the Ticket-Granting Service, but rather require a principal's
+ secret key, such as the password-changing service. (The password-
+ changing request must not be honored unless the requester can provide
+ the old password (the user's current secret key). Otherwise, it
+ would be possible for someone to walk up to an unattended session and
+ change another user's password.) This exchange does not by itself
+ provide any assurance of the the identity of the user. (To
+ authenticate a user logging on to a local system, the credentials
+ obtained in the AS exchange may first be used in a TGS exchange to
+ obtain credentials for a local server. Those credentials must then
+ be verified by the local server through successful completion of the
+ Client/Server exchange.)
+
+ The exchange consists of two messages: KRB_AS_REQ from the client to
+ Kerberos, and KRB_AS_REP or KRB_ERROR in reply. The formats for these
+ messages are described in sections 5.4.1, 5.4.2, and 5.9.1.
+
+ In the request, the client sends (in cleartext) its own identity and
+ the identity of the server for which it is requesting credentials.
+ The response, KRB_AS_REP, contains a ticket for the client to present
+ to the server, and a session key that will be shared by the client
+ and the server. The session key and additional information are
+ encrypted in the client's secret key. The KRB_AS_REP message
+ contains information which can be used to detect replays, and to
+
+
+
+Kohl & Neuman [Page 16]
+
+RFC 1510 Kerberos September 1993
+
+
+ associate it with the message to which it replies. Various errors
+ can occur; these are indicated by an error response (KRB_ERROR)
+ instead of the KRB_AS_REP response. The error message is not
+ encrypted. The KRB_ERROR message also contains information which can
+ be used to associate it with the message to which it replies. The
+ lack of encryption in the KRB_ERROR message precludes the ability to
+ detect replays or fabrications of such messages.
+
+ In the normal case the authentication server does not know whether
+ the client is actually the principal named in the request. It simply
+ sends a reply without knowing or caring whether they are the same.
+ This is acceptable because nobody but the principal whose identity
+ was given in the request will be able to use the reply. Its critical
+ information is encrypted in that principal's key. The initial
+ request supports an optional field that can be used to pass
+ additional information that might be needed for the initial exchange.
+ This field may be used for preauthentication if desired, but the
+ mechanism is not currently specified.
+
+3.1.1. Generation of KRB_AS_REQ message
+
+ The client may specify a number of options in the initial request.
+ Among these options are whether preauthentication is to be performed;
+ whether the requested ticket is to be renewable, proxiable, or
+ forwardable; whether it should be postdated or allow postdating of
+ derivative tickets; and whether a renewable ticket will be accepted
+ in lieu of a non-renewable ticket if the requested ticket expiration
+ date cannot be satisfied by a nonrenewable ticket (due to
+ configuration constraints; see section 4). See section A.1 for
+ pseudocode.
+
+ The client prepares the KRB_AS_REQ message and sends it to the KDC.
+
+3.1.2. Receipt of KRB_AS_REQ message
+
+ If all goes well, processing the KRB_AS_REQ message will result in
+ the creation of a ticket for the client to present to the server.
+ The format for the ticket is described in section 5.3.1. The
+ contents of the ticket are determined as follows.
+
+3.1.3. Generation of KRB_AS_REP message
+
+ The authentication server looks up the client and server principals
+ named in the KRB_AS_REQ in its database, extracting their respective
+ keys. If required, the server pre-authenticates the request, and if
+ the pre-authentication check fails, an error message with the code
+ KDC_ERR_PREAUTH_FAILED is returned. If the server cannot accommodate
+ the requested encryption type, an error message with code
+
+
+
+Kohl & Neuman [Page 17]
+
+RFC 1510 Kerberos September 1993
+
+
+ KDC_ERR_ETYPE_NOSUPP is returned. Otherwise it generates a "random"
+ session key ("Random" means that, among other things, it should be
+ impossible to guess the next session key based on knowledge of past
+ session keys. This can only be achieved in a pseudo-random number
+ generator if it is based on cryptographic principles. It would be
+ more desirable to use a truly random number generator, such as one
+ based on measurements of random physical phenomena.).
+
+ If the requested start time is absent or indicates a time in the
+ past, then the start time of the ticket is set to the authentication
+ server's current time. If it indicates a time in the future, but the
+ POSTDATED option has not been specified, then the error
+ KDC_ERR_CANNOT_POSTDATE is returned. Otherwise the requested start
+ time is checked against the policy of the local realm (the
+ administrator might decide to prohibit certain types or ranges of
+ postdated tickets), and if acceptable, the ticket's start time is set
+ as requested and the INVALID flag is set in the new ticket. The
+ postdated ticket must be validated before use by presenting it to the
+ KDC after the start time has been reached.
+
+ The expiration time of the ticket will be set to the minimum of the
+ following:
+
+ +The expiration time (endtime) requested in the KRB_AS_REQ
+ message.
+
+ +The ticket's start time plus the maximum allowable lifetime
+ associated with the client principal (the authentication
+ server's database includes a maximum ticket lifetime field
+ in each principal's record; see section 4).
+
+ +The ticket's start time plus the maximum allowable lifetime
+ associated with the server principal.
+
+ +The ticket's start time plus the maximum lifetime set by
+ the policy of the local realm.
+
+ If the requested expiration time minus the start time (as determined
+ above) is less than a site-determined minimum lifetime, an error
+ message with code KDC_ERR_NEVER_VALID is returned. If the requested
+ expiration time for the ticket exceeds what was determined as above,
+ and if the "RENEWABLE-OK" option was requested, then the "RENEWABLE"
+ flag is set in the new ticket, and the renew-till value is set as if
+ the "RENEWABLE" option were requested (the field and option names are
+ described fully in section 5.4.1). If the RENEWABLE option has been
+ requested or if the RENEWABLE-OK option has been set and a renewable
+ ticket is to be issued, then the renew-till field is set to the
+ minimum of:
+
+
+
+Kohl & Neuman [Page 18]
+
+RFC 1510 Kerberos September 1993
+
+
+ +Its requested value.
+
+ +The start time of the ticket plus the minimum of the two
+ maximum renewable lifetimes associated with the principals'
+ database entries.
+
+ +The start time of the ticket plus the maximum renewable
+ lifetime set by the policy of the local realm.
+
+ The flags field of the new ticket will have the following options set
+ if they have been requested and if the policy of the local realm
+ allows: FORWARDABLE, MAY-POSTDATE, POSTDATED, PROXIABLE, RENEWABLE.
+ If the new ticket is postdated (the start time is in the future), its
+ INVALID flag will also be set.
+
+ If all of the above succeed, the server formats a KRB_AS_REP message
+ (see section 5.4.2), copying the addresses in the request into the
+ caddr of the response, placing any required pre-authentication data
+ into the padata of the response, and encrypts the ciphertext part in
+ the client's key using the requested encryption method, and sends it
+ to the client. See section A.2 for pseudocode.
+
+3.1.4. Generation of KRB_ERROR message
+
+ Several errors can occur, and the Authentication Server responds by
+ returning an error message, KRB_ERROR, to the client, with the
+ error-code and e-text fields set to appropriate values. The error
+ message contents and details are described in Section 5.9.1.
+
+3.1.5. Receipt of KRB_AS_REP message
+
+ If the reply message type is KRB_AS_REP, then the client verifies
+ that the cname and crealm fields in the cleartext portion of the
+ reply match what it requested. If any padata fields are present,
+ they may be used to derive the proper secret key to decrypt the
+ message. The client decrypts the encrypted part of the response
+ using its secret key, verifies that the nonce in the encrypted part
+ matches the nonce it supplied in its request (to detect replays). It
+ also verifies that the sname and srealm in the response match those
+ in the request, and that the host address field is also correct. It
+ then stores the ticket, session key, start and expiration times, and
+ other information for later use. The key-expiration field from the
+ encrypted part of the response may be checked to notify the user of
+ impending key expiration (the client program could then suggest
+ remedial action, such as a password change). See section A.3 for
+ pseudocode.
+
+ Proper decryption of the KRB_AS_REP message is not sufficient to
+
+
+
+Kohl & Neuman [Page 19]
+
+RFC 1510 Kerberos September 1993
+
+
+ verify the identity of the user; the user and an attacker could
+ cooperate to generate a KRB_AS_REP format message which decrypts
+ properly but is not from the proper KDC. If the host wishes to
+ verify the identity of the user, it must require the user to present
+ application credentials which can be verified using a securely-stored
+ secret key. If those credentials can be verified, then the identity
+ of the user can be assured.
+
+3.1.6. Receipt of KRB_ERROR message
+
+ If the reply message type is KRB_ERROR, then the client interprets it
+ as an error and performs whatever application-specific tasks are
+ necessary to recover.
+
+3.2. The Client/Server Authentication Exchange
+
+ Summary
+
+ Message direction Message type Section
+ Client to Application server KRB_AP_REQ 5.5.1
+ [optional] Application server to client KRB_AP_REP or 5.5.2
+ KRB_ERROR 5.9.1
+
+ The client/server authentication (CS) exchange is used by network
+ applications to authenticate the client to the server and vice versa.
+ The client must have already acquired credentials for the server
+ using the AS or TGS exchange.
+
+3.2.1. The KRB_AP_REQ message
+
+ The KRB_AP_REQ contains authentication information which should be
+ part of the first message in an authenticated transaction. It
+ contains a ticket, an authenticator, and some additional bookkeeping
+ information (see section 5.5.1 for the exact format). The ticket by
+ itself is insufficient to authenticate a client, since tickets are
+ passed across the network in cleartext(Tickets contain both an
+ encrypted and unencrypted portion, so cleartext here refers to the
+ entire unit, which can be copied from one message and replayed in
+ another without any cryptographic skill.), so the authenticator is
+ used to prevent invalid replay of tickets by proving to the server
+ that the client knows the session key of the ticket and thus is
+ entitled to use it. The KRB_AP_REQ message is referred to elsewhere
+ as the "authentication header."
+
+3.2.2. Generation of a KRB_AP_REQ message
+
+ When a client wishes to initiate authentication to a server, it
+ obtains (either through a credentials cache, the AS exchange, or the
+
+
+
+Kohl & Neuman [Page 20]
+
+RFC 1510 Kerberos September 1993
+
+
+ TGS exchange) a ticket and session key for the desired service. The
+ client may re-use any tickets it holds until they expire. The client
+ then constructs a new Authenticator from the the system time, its
+ name, and optionally an application specific checksum, an initial
+ sequence number to be used in KRB_SAFE or KRB_PRIV messages, and/or a
+ session subkey to be used in negotiations for a session key unique to
+ this particular session. Authenticators may not be re-used and will
+ be rejected if replayed to a server (Note that this can make
+ applications based on unreliable transports difficult to code
+ correctly, if the transport might deliver duplicated messages. In
+ such cases, a new authenticator must be generated for each retry.).
+ If a sequence number is to be included, it should be randomly chosen
+ so that even after many messages have been exchanged it is not likely
+ to collide with other sequence numbers in use.
+
+ The client may indicate a requirement of mutual authentication or the
+ use of a session-key based ticket by setting the appropriate flag(s)
+ in the ap-options field of the message.
+
+ The Authenticator is encrypted in the session key and combined with
+ the ticket to form the KRB_AP_REQ message which is then sent to the
+ end server along with any additional application-specific
+ information. See section A.9 for pseudocode.
+
+3.2.3. Receipt of KRB_AP_REQ message
+
+ Authentication is based on the server's current time of day (clocks
+ must be loosely synchronized), the authenticator, and the ticket.
+ Several errors are possible. If an error occurs, the server is
+ expected to reply to the client with a KRB_ERROR message. This
+ message may be encapsulated in the application protocol if its "raw"
+ form is not acceptable to the protocol. The format of error messages
+ is described in section 5.9.1.
+
+ The algorithm for verifying authentication information is as follows.
+ If the message type is not KRB_AP_REQ, the server returns the
+ KRB_AP_ERR_MSG_TYPE error. If the key version indicated by the Ticket
+ in the KRB_AP_REQ is not one the server can use (e.g., it indicates
+ an old key, and the server no longer possesses a copy of the old
+ key), the KRB_AP_ERR_BADKEYVER error is returned. If the USE-
+ SESSION-KEY flag is set in the ap-options field, it indicates to the
+ server that the ticket is encrypted in the session key from the
+ server's ticket-granting ticket rather than its secret key (This is
+ used for user-to-user authentication as described in [6]). Since it
+ is possible for the server to be registered in multiple realms, with
+ different keys in each, the srealm field in the unencrypted portion
+ of the ticket in the KRB_AP_REQ is used to specify which secret key
+ the server should use to decrypt that ticket. The KRB_AP_ERR_NOKEY
+
+
+
+Kohl & Neuman [Page 21]
+
+RFC 1510 Kerberos September 1993
+
+
+ error code is returned if the server doesn't have the proper key to
+ decipher the ticket.
+
+ The ticket is decrypted using the version of the server's key
+ specified by the ticket. If the decryption routines detect a
+ modification of the ticket (each encryption system must provide
+ safeguards to detect modified ciphertext; see section 6), the
+ KRB_AP_ERR_BAD_INTEGRITY error is returned (chances are good that
+ different keys were used to encrypt and decrypt).
+
+ The authenticator is decrypted using the session key extracted from
+ the decrypted ticket. If decryption shows it to have been modified,
+ the KRB_AP_ERR_BAD_INTEGRITY error is returned. The name and realm
+ of the client from the ticket are compared against the same fields in
+ the authenticator. If they don't match, the KRB_AP_ERR_BADMATCH
+ error is returned (they might not match, for example, if the wrong
+ session key was used to encrypt the authenticator). The addresses in
+ the ticket (if any) are then searched for an address matching the
+ operating-system reported address of the client. If no match is
+ found or the server insists on ticket addresses but none are present
+ in the ticket, the KRB_AP_ERR_BADADDR error is returned.
+
+ If the local (server) time and the client time in the authenticator
+ differ by more than the allowable clock skew (e.g., 5 minutes), the
+ KRB_AP_ERR_SKEW error is returned. If the server name, along with
+ the client name, time and microsecond fields from the Authenticator
+ match any recently-seen such tuples, the KRB_AP_ERR_REPEAT error is
+ returned (Note that the rejection here is restricted to
+ authenticators from the same principal to the same server. Other
+ client principals communicating with the same server principal should
+ not be have their authenticators rejected if the time and microsecond
+ fields happen to match some other client's authenticator.). The
+ server must remember any authenticator presented within the allowable
+ clock skew, so that a replay attempt is guaranteed to fail. If a
+ server loses track of any authenticator presented within the
+ allowable clock skew, it must reject all requests until the clock
+ skew interval has passed. This assures that any lost or re-played
+ authenticators will fall outside the allowable clock skew and can no
+ longer be successfully replayed (If this is not done, an attacker
+ could conceivably record the ticket and authenticator sent over the
+ network to a server, then disable the client's host, pose as the
+ disabled host, and replay the ticket and authenticator to subvert the
+ authentication.). If a sequence number is provided in the
+ authenticator, the server saves it for later use in processing
+ KRB_SAFE and/or KRB_PRIV messages. If a subkey is present, the
+ server either saves it for later use or uses it to help generate its
+ own choice for a subkey to be returned in a KRB_AP_REP message.
+
+
+
+
+Kohl & Neuman [Page 22]
+
+RFC 1510 Kerberos September 1993
+
+
+ The server computes the age of the ticket: local (server) time minus
+ the start time inside the Ticket. If the start time is later than
+ the current time by more than the allowable clock skew or if the
+ INVALID flag is set in the ticket, the KRB_AP_ERR_TKT_NYV error is
+ returned. Otherwise, if the current time is later than end time by
+ more than the allowable clock skew, the KRB_AP_ERR_TKT_EXPIRED error
+ is returned.
+
+ If all these checks succeed without an error, the server is assured
+ that the client possesses the credentials of the principal named in
+ the ticket and thus, the client has been authenticated to the server.
+ See section A.10 for pseudocode.
+
+3.2.4. Generation of a KRB_AP_REP message
+
+ Typically, a client's request will include both the authentication
+ information and its initial request in the same message, and the
+ server need not explicitly reply to the KRB_AP_REQ. However, if
+ mutual authentication (not only authenticating the client to the
+ server, but also the server to the client) is being performed, the
+ KRB_AP_REQ message will have MUTUAL-REQUIRED set in its ap-options
+ field, and a KRB_AP_REP message is required in response. As with the
+ error message, this message may be encapsulated in the application
+ protocol if its "raw" form is not acceptable to the application's
+ protocol. The timestamp and microsecond field used in the reply must
+ be the client's timestamp and microsecond field (as provided in the
+ authenticator). [Note: In the Kerberos version 4 protocol, the
+ timestamp in the reply was the client's timestamp plus one. This is
+ not necessary in version 5 because version 5 messages are formatted
+ in such a way that it is not possible to create the reply by
+ judicious message surgery (even in encrypted form) without knowledge
+ of the appropriate encryption keys.] If a sequence number is to be
+ included, it should be randomly chosen as described above for the
+ authenticator. A subkey may be included if the server desires to
+ negotiate a different subkey. The KRB_AP_REP message is encrypted in
+ the session key extracted from the ticket. See section A.11 for
+ pseudocode.
+
+3.2.5. Receipt of KRB_AP_REP message
+
+ If a KRB_AP_REP message is returned, the client uses the session key
+ from the credentials obtained for the server (Note that for
+ encrypting the KRB_AP_REP message, the sub-session key is not used,
+ even if present in the Authenticator.) to decrypt the message, and
+ verifies that the timestamp and microsecond fields match those in the
+ Authenticator it sent to the server. If they match, then the client
+ is assured that the server is genuine. The sequence number and subkey
+ (if present) are retained for later use. See section A.12 for
+
+
+
+Kohl & Neuman [Page 23]
+
+RFC 1510 Kerberos September 1993
+
+
+ pseudocode.
+
+3.2.6. Using the encryption key
+
+ After the KRB_AP_REQ/KRB_AP_REP exchange has occurred, the client and
+ server share an encryption key which can be used by the application.
+ The "true session key" to be used for KRB_PRIV, KRB_SAFE, or other
+ application-specific uses may be chosen by the application based on
+ the subkeys in the KRB_AP_REP message and the authenticator
+ (Implementations of the protocol may wish to provide routines to
+ choose subkeys based on session keys and random numbers and to
+ orchestrate a negotiated key to be returned in the KRB_AP_REP
+ message.). In some cases, the use of this session key will be
+ implicit in the protocol; in others the method of use must be chosen
+ from a several alternatives. We leave the protocol negotiations of
+ how to use the key (e.g., selecting an encryption or checksum type)
+ to the application programmer; the Kerberos protocol does not
+ constrain the implementation options.
+
+ With both the one-way and mutual authentication exchanges, the peers
+ should take care not to send sensitive information to each other
+ without proper assurances. In particular, applications that require
+ privacy or integrity should use the KRB_AP_REP or KRB_ERROR responses
+ from the server to client to assure both client and server of their
+ peer's identity. If an application protocol requires privacy of its
+ messages, it can use the KRB_PRIV message (section 3.5). The KRB_SAFE
+ message (section 3.4) can be used to assure integrity.
+
+3.3. The Ticket-Granting Service (TGS) Exchange
+
+ Summary
+
+ Message direction Message type Section
+ 1. Client to Kerberos KRB_TGS_REQ 5.4.1
+ 2. Kerberos to client KRB_TGS_REP or 5.4.2
+ KRB_ERROR 5.9.1
+
+ The TGS exchange between a client and the Kerberos Ticket-Granting
+ Server is initiated by a client when it wishes to obtain
+ authentication credentials for a given server (which might be
+ registered in a remote realm), when it wishes to renew or validate an
+ existing ticket, or when it wishes to obtain a proxy ticket. In the
+ first case, the client must already have acquired a ticket for the
+ Ticket-Granting Service using the AS exchange (the ticket-granting
+ ticket is usually obtained when a client initially authenticates to
+ the system, such as when a user logs in). The message format for the
+ TGS exchange is almost identical to that for the AS exchange. The
+ primary difference is that encryption and decryption in the TGS
+
+
+
+Kohl & Neuman [Page 24]
+
+RFC 1510 Kerberos September 1993
+
+
+ exchange does not take place under the client's key. Instead, the
+ session key from the ticket-granting ticket or renewable ticket, or
+ sub-session key from an Authenticator is used. As is the case for
+ all application servers, expired tickets are not accepted by the TGS,
+ so once a renewable or ticket-granting ticket expires, the client
+ must use a separate exchange to obtain valid tickets.
+
+ The TGS exchange consists of two messages: A request (KRB_TGS_REQ)
+ from the client to the Kerberos Ticket-Granting Server, and a reply
+ (KRB_TGS_REP or KRB_ERROR). The KRB_TGS_REQ message includes
+ information authenticating the client plus a request for credentials.
+ The authentication information consists of the authentication header
+ (KRB_AP_REQ) which includes the client's previously obtained ticket-
+ granting, renewable, or invalid ticket. In the ticket-granting
+ ticket and proxy cases, the request may include one or more of: a
+ list of network addresses, a collection of typed authorization data
+ to be sealed in the ticket for authorization use by the application
+ server, or additional tickets (the use of which are described later).
+ The TGS reply (KRB_TGS_REP) contains the requested credentials,
+ encrypted in the session key from the ticket-granting ticket or
+ renewable ticket, or if present, in the subsession key from the
+ Authenticator (part of the authentication header). The KRB_ERROR
+ message contains an error code and text explaining what went wrong.
+ The KRB_ERROR message is not encrypted. The KRB_TGS_REP message
+ contains information which can be used to detect replays, and to
+ associate it with the message to which it replies. The KRB_ERROR
+ message also contains information which can be used to associate it
+ with the message to which it replies, but the lack of encryption in
+ the KRB_ERROR message precludes the ability to detect replays or
+ fabrications of such messages.
+
+3.3.1. Generation of KRB_TGS_REQ message
+
+ Before sending a request to the ticket-granting service, the client
+ must determine in which realm the application server is registered
+ [Note: This can be accomplished in several ways. It might be known
+ beforehand (since the realm is part of the principal identifier), or
+ it might be stored in a nameserver. Presently, however, this
+ information is obtained from a configuration file. If the realm to
+ be used is obtained from a nameserver, there is a danger of being
+ spoofed if the nameservice providing the realm name is not
+ authenticated. This might result in the use of a realm which has
+ been compromised, and would result in an attacker's ability to
+ compromise the authentication of the application server to the
+ client.]. If the client does not already possess a ticket-granting
+ ticket for the appropriate realm, then one must be obtained. This is
+ first attempted by requesting a ticket-granting ticket for the
+ destination realm from the local Kerberos server (using the
+
+
+
+Kohl & Neuman [Page 25]
+
+RFC 1510 Kerberos September 1993
+
+
+ KRB_TGS_REQ message recursively). The Kerberos server may return a
+ TGT for the desired realm in which case one can proceed.
+ Alternatively, the Kerberos server may return a TGT for a realm which
+ is "closer" to the desired realm (further along the standard
+ hierarchical path), in which case this step must be repeated with a
+ Kerberos server in the realm specified in the returned TGT. If
+ neither are returned, then the request must be retried with a
+ Kerberos server for a realm higher in the hierarchy. This request
+ will itself require a ticket-granting ticket for the higher realm
+ which must be obtained by recursively applying these directions.
+
+ Once the client obtains a ticket-granting ticket for the appropriate
+ realm, it determines which Kerberos servers serve that realm, and
+ contacts one. The list might be obtained through a configuration file
+ or network service; as long as the secret keys exchanged by realms
+ are kept secret, only denial of service results from a false Kerberos
+ server.
+
+ As in the AS exchange, the client may specify a number of options in
+ the KRB_TGS_REQ message. The client prepares the KRB_TGS_REQ
+ message, providing an authentication header as an element of the
+ padata field, and including the same fields as used in the KRB_AS_REQ
+ message along with several optional fields: the enc-authorization-
+ data field for application server use and additional tickets required
+ by some options.
+
+ In preparing the authentication header, the client can select a sub-
+ session key under which the response from the Kerberos server will be
+ encrypted (If the client selects a sub-session key, care must be
+ taken to ensure the randomness of the selected subsession key. One
+ approach would be to generate a random number and XOR it with the
+ session key from the ticket-granting ticket.). If the sub-session key
+ is not specified, the session key from the ticket-granting ticket
+ will be used. If the enc-authorization-data is present, it must be
+ encrypted in the sub-session key, if present, from the authenticator
+ portion of the authentication header, or if not present in the
+ session key from the ticket-granting ticket.
+
+ Once prepared, the message is sent to a Kerberos server for the
+ destination realm. See section A.5 for pseudocode.
+
+3.3.2. Receipt of KRB_TGS_REQ message
+
+ The KRB_TGS_REQ message is processed in a manner similar to the
+ KRB_AS_REQ message, but there are many additional checks to be
+ performed. First, the Kerberos server must determine which server
+ the accompanying ticket is for and it must select the appropriate key
+ to decrypt it. For a normal KRB_TGS_REQ message, it will be for the
+
+
+
+Kohl & Neuman [Page 26]
+
+RFC 1510 Kerberos September 1993
+
+
+ ticket granting service, and the TGS's key will be used. If the TGT
+ was issued by another realm, then the appropriate inter-realm key
+ must be used. If the accompanying ticket is not a ticket granting
+ ticket for the current realm, but is for an application server in the
+ current realm, the RENEW, VALIDATE, or PROXY options are specified in
+ the request, and the server for which a ticket is requested is the
+ server named in the accompanying ticket, then the KDC will decrypt
+ the ticket in the authentication header using the key of the server
+ for which it was issued. If no ticket can be found in the padata
+ field, the KDC_ERR_PADATA_TYPE_NOSUPP error is returned.
+
+ Once the accompanying ticket has been decrypted, the user-supplied
+ checksum in the Authenticator must be verified against the contents
+ of the request, and the message rejected if the checksums do not
+ match (with an error code of KRB_AP_ERR_MODIFIED) or if the checksum
+ is not keyed or not collision-proof (with an error code of
+ KRB_AP_ERR_INAPP_CKSUM). If the checksum type is not supported, the
+ KDC_ERR_SUMTYPE_NOSUPP error is returned. If the authorization-data
+ are present, they are decrypted using the sub-session key from the
+ Authenticator.
+
+ If any of the decryptions indicate failed integrity checks, the
+ KRB_AP_ERR_BAD_INTEGRITY error is returned.
+
+3.3.3. Generation of KRB_TGS_REP message
+
+ The KRB_TGS_REP message shares its format with the KRB_AS_REP
+ (KRB_KDC_REP), but with its type field set to KRB_TGS_REP. The
+ detailed specification is in section 5.4.2.
+
+ The response will include a ticket for the requested server. The
+ Kerberos database is queried to retrieve the record for the requested
+ server (including the key with which the ticket will be encrypted).
+ If the request is for a ticket granting ticket for a remote realm,
+ and if no key is shared with the requested realm, then the Kerberos
+ server will select the realm "closest" to the requested realm with
+ which it does share a key, and use that realm instead. This is the
+ only case where the response from the KDC will be for a different
+ server than that requested by the client.
+
+ By default, the address field, the client's name and realm, the list
+ of transited realms, the time of initial authentication, the
+ expiration time, and the authorization data of the newly-issued
+ ticket will be copied from the ticket-granting ticket (TGT) or
+ renewable ticket. If the transited field needs to be updated, but
+ the transited type is not supported, the KDC_ERR_TRTYPE_NOSUPP error
+ is returned.
+
+
+
+
+Kohl & Neuman [Page 27]
+
+RFC 1510 Kerberos September 1993
+
+
+ If the request specifies an endtime, then the endtime of the new
+ ticket is set to the minimum of (a) that request, (b) the endtime
+ from the TGT, and (c) the starttime of the TGT plus the minimum of
+ the maximum life for the application server and the maximum life for
+ the local realm (the maximum life for the requesting principal was
+ already applied when the TGT was issued). If the new ticket is to be
+ a renewal, then the endtime above is replaced by the minimum of (a)
+ the value of the renew_till field of the ticket and (b) the starttime
+ for the new ticket plus the life (endtimestarttime) of the old
+ ticket.
+
+ If the FORWARDED option has been requested, then the resulting ticket
+ will contain the addresses specified by the client. This option will
+ only be honored if the FORWARDABLE flag is set in the TGT. The PROXY
+ option is similar; the resulting ticket will contain the addresses
+ specified by the client. It will be honored only if the PROXIABLE
+ flag in the TGT is set. The PROXY option will not be honored on
+ requests for additional ticket-granting tickets.
+
+ If the requested start time is absent or indicates a time in the
+ past, then the start time of the ticket is set to the authentication
+ server's current time. If it indicates a time in the future, but the
+ POSTDATED option has not been specified or the MAY-POSTDATE flag is
+ not set in the TGT, then the error KDC_ERR_CANNOT_POSTDATE is
+ returned. Otherwise, if the ticket-granting ticket has the
+ MAYPOSTDATE flag set, then the resulting ticket will be postdated and
+ the requested starttime is checked against the policy of the local
+ realm. If acceptable, the ticket's start time is set as requested,
+ and the INVALID flag is set. The postdated ticket must be validated
+ before use by presenting it to the KDC after the starttime has been
+ reached. However, in no case may the starttime, endtime, or renew-
+ till time of a newly-issued postdated ticket extend beyond the
+ renew-till time of the ticket-granting ticket.
+
+ If the ENC-TKT-IN-SKEY option has been specified and an additional
+ ticket has been included in the request, the KDC will decrypt the
+ additional ticket using the key for the server to which the
+ additional ticket was issued and verify that it is a ticket-granting
+ ticket. If the name of the requested server is missing from the
+ request, the name of the client in the additional ticket will be
+ used. Otherwise the name of the requested server will be compared to
+ the name of the client in the additional ticket and if different, the
+ request will be rejected. If the request succeeds, the session key
+ from the additional ticket will be used to encrypt the new ticket
+ that is issued instead of using the key of the server for which the
+ new ticket will be used (This allows easy implementation of user-to-
+ user authentication [6], which uses ticket-granting ticket session
+ keys in lieu of secret server keys in situations where such secret
+
+
+
+Kohl & Neuman [Page 28]
+
+RFC 1510 Kerberos September 1993
+
+
+ keys could be easily compromised.).
+
+ If the name of the server in the ticket that is presented to the KDC
+ as part of the authentication header is not that of the ticket-
+ granting server itself, and the server is registered in the realm of
+ the KDC, If the RENEW option is requested, then the KDC will verify
+ that the RENEWABLE flag is set in the ticket and that the renew_till
+ time is still in the future. If the VALIDATE option is rqeuested,
+ the KDC will check that the starttime has passed and the INVALID flag
+ is set. If the PROXY option is requested, then the KDC will check
+ that the PROXIABLE flag is set in the ticket. If the tests succeed,
+ the KDC will issue the appropriate new ticket.
+
+ Whenever a request is made to the ticket-granting server, the
+ presented ticket(s) is(are) checked against a hot-list of tickets
+ which have been canceled. This hot-list might be implemented by
+ storing a range of issue dates for "suspect tickets"; if a presented
+ ticket had an authtime in that range, it would be rejected. In this
+ way, a stolen ticket-granting ticket or renewable ticket cannot be
+ used to gain additional tickets (renewals or otherwise) once the
+ theft has been reported. Any normal ticket obtained before it was
+ reported stolen will still be valid (because they require no
+ interaction with the KDC), but only until their normal expiration
+ time.
+
+ The ciphertext part of the response in the KRB_TGS_REP message is
+ encrypted in the sub-session key from the Authenticator, if present,
+ or the session key key from the ticket-granting ticket. It is not
+ encrypted using the client's secret key. Furthermore, the client's
+ key's expiration date and the key version number fields are left out
+ since these values are stored along with the client's database
+ record, and that record is not needed to satisfy a request based on a
+ ticket-granting ticket. See section A.6 for pseudocode.
+
+3.3.3.1. Encoding the transited field
+
+ If the identity of the server in the TGT that is presented to the KDC
+ as part of the authentication header is that of the ticket-granting
+ service, but the TGT was issued from another realm, the KDC will look
+ up the inter-realm key shared with that realm and use that key to
+ decrypt the ticket. If the ticket is valid, then the KDC will honor
+ the request, subject to the constraints outlined above in the section
+ describing the AS exchange. The realm part of the client's identity
+ will be taken from the ticket-granting ticket. The name of the realm
+ that issued the ticket-granting ticket will be added to the transited
+ field of the ticket to be issued. This is accomplished by reading
+ the transited field from the ticket-granting ticket (which is treated
+ as an unordered set of realm names), adding the new realm to the set,
+
+
+
+Kohl & Neuman [Page 29]
+
+RFC 1510 Kerberos September 1993
+
+
+ then constructing and writing out its encoded (shorthand) form (this
+ may involve a rearrangement of the existing encoding).
+
+ Note that the ticket-granting service does not add the name of its
+ own realm. Instead, its responsibility is to add the name of the
+ previous realm. This prevents a malicious Kerberos server from
+ intentionally leaving out its own name (it could, however, omit other
+ realms' names).
+
+ The names of neither the local realm nor the principal's realm are to
+ be included in the transited field. They appear elsewhere in the
+ ticket and both are known to have taken part in authenticating the
+ principal. Since the endpoints are not included, both local and
+ single-hop inter-realm authentication result in a transited field
+ that is empty.
+
+ Because the name of each realm transited is added to this field,
+ it might potentially be very long. To decrease the length of this
+ field, its contents are encoded. The initially supported encoding is
+ optimized for the normal case of inter-realm communication: a
+ hierarchical arrangement of realms using either domain or X.500 style
+ realm names. This encoding (called DOMAIN-X500-COMPRESS) is now
+ described.
+
+ Realm names in the transited field are separated by a ",". The ",",
+ "\", trailing "."s, and leading spaces (" ") are special characters,
+ and if they are part of a realm name, they must be quoted in the
+ transited field by preceding them with a "\".
+
+ A realm name ending with a "." is interpreted as being prepended to
+ the previous realm. For example, we can encode traversal of EDU,
+ MIT.EDU, ATHENA.MIT.EDU, WASHINGTON.EDU, and CS.WASHINGTON.EDU as:
+
+ "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS.".
+
+ Note that if ATHENA.MIT.EDU, or CS.WASHINGTON.EDU were endpoints,
+ that they would not be included in this field, and we would have:
+
+ "EDU,MIT.,WASHINGTON.EDU"
+
+ A realm name beginning with a "/" is interpreted as being appended to
+ the previous realm (For the purpose of appending, the realm preceding
+ the first listed realm is considered to be the null realm ("")). If
+ it is to stand by itself, then it should be preceded by a space ("
+ "). For example, we can encode traversal of /COM/HP/APOLLO, /COM/HP,
+ /COM, and /COM/DEC as:
+
+ "/COM,/HP,/APOLLO, /COM/DEC".
+
+
+
+Kohl & Neuman [Page 30]
+
+RFC 1510 Kerberos September 1993
+
+
+ Like the example above, if /COM/HP/APOLLO and /COM/DEC are endpoints,
+ they they would not be included in this field, and we would have:
+
+ "/COM,/HP"
+
+ A null subfield preceding or following a "," indicates that all
+ realms between the previous realm and the next realm have been
+ traversed (For the purpose of interpreting null subfields, the
+ client's realm is considered to precede those in the transited field,
+ and the server's realm is considered to follow them.). Thus, ","
+ means that all realms along the path between the client and the
+ server have been traversed. ",EDU, /COM," means that that all realms
+ from the client's realm up to EDU (in a domain style hierarchy) have
+ been traversed, and that everything from /COM down to the server's
+ realm in an X.500 style has also been traversed. This could occur if
+ the EDU realm in one hierarchy shares an inter-realm key directly
+ with the /COM realm in another hierarchy.
+
+3.3.4. Receipt of KRB_TGS_REP message
+
+ When the KRB_TGS_REP is received by the client, it is processed in
+ the same manner as the KRB_AS_REP processing described above. The
+ primary difference is that the ciphertext part of the response must
+ be decrypted using the session key from the ticket-granting ticket
+ rather than the client's secret key. See section A.7 for pseudocode.
+
+3.4. The KRB_SAFE Exchange
+
+ The KRB_SAFE message may be used by clients requiring the ability to
+ detect modifications of messages they exchange. It achieves this by
+ including a keyed collisionproof checksum of the user data and some
+ control information. The checksum is keyed with an encryption key
+ (usually the last key negotiated via subkeys, or the session key if
+ no negotiation has occured).
+
+3.4.1. Generation of a KRB_SAFE message
+
+ When an application wishes to send a KRB_SAFE message, it collects
+ its data and the appropriate control information and computes a
+ checksum over them. The checksum algorithm should be some sort of
+ keyed one-way hash function (such as the RSA-MD5-DES checksum
+ algorithm specified in section 6.4.5, or the DES MAC), generated
+ using the sub-session key if present, or the session key. Different
+ algorithms may be selected by changing the checksum type in the
+ message. Unkeyed or non-collision-proof checksums are not suitable
+ for this use.
+
+ The control information for the KRB_SAFE message includes both a
+
+
+
+Kohl & Neuman [Page 31]
+
+RFC 1510 Kerberos September 1993
+
+
+ timestamp and a sequence number. The designer of an application
+ using the KRB_SAFE message must choose at least one of the two
+ mechanisms. This choice should be based on the needs of the
+ application protocol.
+
+ Sequence numbers are useful when all messages sent will be received
+ by one's peer. Connection state is presently required to maintain
+ the session key, so maintaining the next sequence number should not
+ present an additional problem.
+
+ If the application protocol is expected to tolerate lost messages
+ without them being resent, the use of the timestamp is the
+ appropriate replay detection mechanism. Using timestamps is also the
+ appropriate mechanism for multi-cast protocols where all of one's
+ peers share a common sub-session key, but some messages will be sent
+ to a subset of one's peers.
+
+ After computing the checksum, the client then transmits the
+ information and checksum to the recipient in the message format
+ specified in section 5.6.1.
+
+3.4.2. Receipt of KRB_SAFE message
+
+ When an application receives a KRB_SAFE message, it verifies it as
+ follows. If any error occurs, an error code is reported for use by
+ the application.
+
+ The message is first checked by verifying that the protocol version
+ and type fields match the current version and KRB_SAFE, respectively.
+ A mismatch generates a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE
+ error. The application verifies that the checksum used is a
+ collisionproof keyed checksum, and if it is not, a
+ KRB_AP_ERR_INAPP_CKSUM error is generated. The recipient verifies
+ that the operating system's report of the sender's address matches
+ the sender's address in the message, and (if a recipient address is
+ specified or the recipient requires an address) that one of the
+ recipient's addresses appears as the recipient's address in the
+ message. A failed match for either case generates a
+ KRB_AP_ERR_BADADDR error. Then the timestamp and usec and/or the
+ sequence number fields are checked. If timestamp and usec are
+ expected and not present, or they are present but not current, the
+ KRB_AP_ERR_SKEW error is generated. If the server name, along with
+ the client name, time and microsecond fields from the Authenticator
+ match any recently-seen such tuples, the KRB_AP_ERR_REPEAT error is
+ generated. If an incorrect sequence number is included, or a
+ sequence number is expected but not present, the KRB_AP_ERR_BADORDER
+ error is generated. If neither a timestamp and usec or a sequence
+ number is present, a KRB_AP_ERR_MODIFIED error is generated.
+
+
+
+Kohl & Neuman [Page 32]
+
+RFC 1510 Kerberos September 1993
+
+
+ Finally, the checksum is computed over the data and control
+ information, and if it doesn't match the received checksum, a
+ KRB_AP_ERR_MODIFIED error is generated.
+
+ If all the checks succeed, the application is assured that the
+ message was generated by its peer and was not modified in transit.
+
+3.5. The KRB_PRIV Exchange
+
+ The KRB_PRIV message may be used by clients requiring confidentiality
+ and the ability to detect modifications of exchanged messages. It
+ achieves this by encrypting the messages and adding control
+ information.
+
+3.5.1. Generation of a KRB_PRIV message
+
+ When an application wishes to send a KRB_PRIV message, it collects
+ its data and the appropriate control information (specified in
+ section 5.7.1) and encrypts them under an encryption key (usually the
+ last key negotiated via subkeys, or the session key if no negotiation
+ has occured). As part of the control information, the client must
+ choose to use either a timestamp or a sequence number (or both); see
+ the discussion in section 3.4.1 for guidelines on which to use.
+ After the user data and control information are encrypted, the client
+ transmits the ciphertext and some "envelope" information to the
+ recipient.
+
+3.5.2. Receipt of KRB_PRIV message
+
+ When an application receives a KRB_PRIV message, it verifies it as
+ follows. If any error occurs, an error code is reported for use by
+ the application.
+
+ The message is first checked by verifying that the protocol version
+ and type fields match the current version and KRB_PRIV, respectively.
+ A mismatch generates a KRB_AP_ERR_BADVERSION or KRB_AP_ERR_MSG_TYPE
+ error. The application then decrypts the ciphertext and processes
+ the resultant plaintext. If decryption shows the data to have been
+ modified, a KRB_AP_ERR_BAD_INTEGRITY error is generated. The
+ recipient verifies that the operating system's report of the sender's
+ address matches the sender's address in the message, and (if a
+ recipient address is specified or the recipient requires an address)
+ that one of the recipient's addresses appears as the recipient's
+ address in the message. A failed match for either case generates a
+ KRB_AP_ERR_BADADDR error. Then the timestamp and usec and/or the
+ sequence number fields are checked. If timestamp and usec are
+ expected and not present, or they are present but not current, the
+ KRB_AP_ERR_SKEW error is generated. If the server name, along with
+
+
+
+Kohl & Neuman [Page 33]
+
+RFC 1510 Kerberos September 1993
+
+
+ the client name, time and microsecond fields from the Authenticator
+ match any recently-seen such tuples, the KRB_AP_ERR_REPEAT error is
+ generated. If an incorrect sequence number is included, or a
+ sequence number is expected but not present, the KRB_AP_ERR_BADORDER
+ error is generated. If neither a timestamp and usec or a sequence
+ number is present, a KRB_AP_ERR_MODIFIED error is generated.
+
+ If all the checks succeed, the application can assume the message was
+ generated by its peer, and was securely transmitted (without
+ intruders able to see the unencrypted contents).
+
+3.6. The KRB_CRED Exchange
+
+ The KRB_CRED message may be used by clients requiring the ability to
+ send Kerberos credentials from one host to another. It achieves this
+ by sending the tickets together with encrypted data containing the
+ session keys and other information associated with the tickets.
+
+3.6.1. Generation of a KRB_CRED message
+
+ When an application wishes to send a KRB_CRED message it first (using
+ the KRB_TGS exchange) obtains credentials to be sent to the remote
+ host. It then constructs a KRB_CRED message using the ticket or
+ tickets so obtained, placing the session key needed to use each
+ ticket in the key field of the corresponding KrbCredInfo sequence of
+ the encrypted part of the the KRB_CRED message.
+
+ Other information associated with each ticket and obtained during the
+ KRB_TGS exchange is also placed in the corresponding KrbCredInfo
+ sequence in the encrypted part of the KRB_CRED message. The current
+ time and, if specifically required by the application the nonce, s-
+ address, and raddress fields, are placed in the encrypted part of the
+ KRB_CRED message which is then encrypted under an encryption key
+ previosuly exchanged in the KRB_AP exchange (usually the last key
+ negotiated via subkeys, or the session key if no negotiation has
+ occured).
+
+3.6.2. Receipt of KRB_CRED message
+
+ When an application receives a KRB_CRED message, it verifies it. If
+ any error occurs, an error code is reported for use by the
+ application. The message is verified by checking that the protocol
+ version and type fields match the current version and KRB_CRED,
+ respectively. A mismatch generates a KRB_AP_ERR_BADVERSION or
+ KRB_AP_ERR_MSG_TYPE error. The application then decrypts the
+ ciphertext and processes the resultant plaintext. If decryption shows
+ the data to have been modified, a KRB_AP_ERR_BAD_INTEGRITY error is
+ generated.
+
+
+
+Kohl & Neuman [Page 34]
+
+RFC 1510 Kerberos September 1993
+
+
+ If present or required, the recipient verifies that the operating
+ system's report of the sender's address matches the sender's address
+ in the message, and that one of the recipient's addresses appears as
+ the recipient's address in the message. A failed match for either
+ case generates a KRB_AP_ERR_BADADDR error. The timestamp and usec
+ fields (and the nonce field if required) are checked next. If the
+ timestamp and usec are not present, or they are present but not
+ current, the KRB_AP_ERR_SKEW error is generated.
+
+ If all the checks succeed, the application stores each of the new
+ tickets in its ticket cache together with the session key and other
+ information in the corresponding KrbCredInfo sequence from the
+ encrypted part of the KRB_CRED message.
+
+4. The Kerberos Database
+
+ The Kerberos server must have access to a database containing the
+ principal identifiers and secret keys of principals to be
+ authenticated (The implementation of the Kerberos server need not
+ combine the database and the server on the same machine; it is
+ feasible to store the principal database in, say, a network name
+ service, as long as the entries stored therein are protected from
+ disclosure to and modification by unauthorized parties. However, we
+ recommend against such strategies, as they can make system management
+ and threat analysis quite complex.).
+
+4.1. Database contents
+
+ A database entry should contain at least the following fields:
+
+ Field Value
+
+ name Principal's identifier
+ key Principal's secret key
+ p_kvno Principal's key version
+ max_life Maximum lifetime for Tickets
+ max_renewable_life Maximum total lifetime for renewable
+ Tickets
+
+ The name field is an encoding of the principal's identifier. The key
+ field contains an encryption key. This key is the principal's secret
+ key. (The key can be encrypted before storage under a Kerberos
+ "master key" to protect it in case the database is compromised but
+ the master key is not. In that case, an extra field must be added to
+ indicate the master key version used, see below.) The p_kvno field is
+ the key version number of the principal's secret key. The max_life
+ field contains the maximum allowable lifetime (endtime - starttime)
+ for any Ticket issued for this principal. The max_renewable_life
+
+
+
+Kohl & Neuman [Page 35]
+
+RFC 1510 Kerberos September 1993
+
+
+ field contains the maximum allowable total lifetime for any renewable
+ Ticket issued for this principal. (See section 3.1 for a description
+ of how these lifetimes are used in determining the lifetime of a
+ given Ticket.)
+
+ A server may provide KDC service to several realms, as long as the
+ database representation provides a mechanism to distinguish between
+ principal records with identifiers which differ only in the realm
+ name.
+
+ When an application server's key changes, if the change is routine
+ (i.e., not the result of disclosure of the old key), the old key
+ should be retained by the server until all tickets that had been
+ issued using that key have expired. Because of this, it is possible
+ for several keys to be active for a single principal. Ciphertext
+ encrypted in a principal's key is always tagged with the version of
+ the key that was used for encryption, to help the recipient find the
+ proper key for decryption.
+
+ When more than one key is active for a particular principal, the
+ principal will have more than one record in the Kerberos database.
+ The keys and key version numbers will differ between the records (the
+ rest of the fields may or may not be the same). Whenever Kerberos
+ issues a ticket, or responds to a request for initial authentication,
+ the most recent key (known by the Kerberos server) will be used for
+ encryption. This is the key with the highest key version number.
+
+4.2. Additional fields
+
+ Project Athena's KDC implementation uses additional fields in its
+ database:
+
+ Field Value
+
+ K_kvno Kerberos' key version
+ expiration Expiration date for entry
+ attributes Bit field of attributes
+ mod_date Timestamp of last modification
+ mod_name Modifying principal's identifier
+
+ The K_kvno field indicates the key version of the Kerberos master key
+ under which the principal's secret key is encrypted.
+
+ After an entry's expiration date has passed, the KDC will return an
+ error to any client attempting to gain tickets as or for the
+ principal. (A database may want to maintain two expiration dates:
+ one for the principal, and one for the principal's current key. This
+ allows password aging to work independently of the principal's
+
+
+
+Kohl & Neuman [Page 36]
+
+RFC 1510 Kerberos September 1993
+
+
+ expiration date. However, due to the limited space in the responses,
+ the KDC must combine the key expiration and principal expiration date
+ into a single value called "key_exp", which is used as a hint to the
+ user to take administrative action.)
+
+ The attributes field is a bitfield used to govern the operations
+ involving the principal. This field might be useful in conjunction
+ with user registration procedures, for site-specific policy
+ implementations (Project Athena currently uses it for their user
+ registration process controlled by the system-wide database service,
+ Moira [7]), or to identify the "string to key" conversion algorithm
+ used for a principal's key. (See the discussion of the padata field
+ in section 5.4.2 for details on why this can be useful.) Other bits
+ are used to indicate that certain ticket options should not be
+ allowed in tickets encrypted under a principal's key (one bit each):
+ Disallow issuing postdated tickets, disallow issuing forwardable
+ tickets, disallow issuing tickets based on TGT authentication,
+ disallow issuing renewable tickets, disallow issuing proxiable
+ tickets, and disallow issuing tickets for which the principal is the
+ server.
+
+ The mod_date field contains the time of last modification of the
+ entry, and the mod_name field contains the name of the principal
+ which last modified the entry.
+
+4.3. Frequently Changing Fields
+
+ Some KDC implementations may wish to maintain the last time that a
+ request was made by a particular principal. Information that might
+ be maintained includes the time of the last request, the time of the
+ last request for a ticket-granting ticket, the time of the last use
+ of a ticket-granting ticket, or other times. This information can
+ then be returned to the user in the last-req field (see section 5.2).
+
+ Other frequently changing information that can be maintained is the
+ latest expiration time for any tickets that have been issued using
+ each key. This field would be used to indicate how long old keys
+ must remain valid to allow the continued use of outstanding tickets.
+
+4.4. Site Constants
+
+ The KDC implementation should have the following configurable
+ constants or options, to allow an administrator to make and enforce
+ policy decisions:
+
+ + The minimum supported lifetime (used to determine whether the
+ KDC_ERR_NEVER_VALID error should be returned). This constant
+ should reflect reasonable expectations of round-trip time to the
+
+
+
+Kohl & Neuman [Page 37]
+
+RFC 1510 Kerberos September 1993
+
+
+ KDC, encryption/decryption time, and processing time by the client
+ and target server, and it should allow for a minimum "useful"
+ lifetime.
+
+ + The maximum allowable total (renewable) lifetime of a ticket
+ (renew_till - starttime).
+
+ + The maximum allowable lifetime of a ticket (endtime - starttime).
+
+ + Whether to allow the issue of tickets with empty address fields
+ (including the ability to specify that such tickets may only be
+ issued if the request specifies some authorization_data).
+
+ + Whether proxiable, forwardable, renewable or post-datable tickets
+ are to be issued.
+
+5. Message Specifications
+
+ The following sections describe the exact contents and encoding of
+ protocol messages and objects. The ASN.1 base definitions are
+ presented in the first subsection. The remaining subsections specify
+ the protocol objects (tickets and authenticators) and messages.
+ Specification of encryption and checksum techniques, and the fields
+ related to them, appear in section 6.
+
+5.1. ASN.1 Distinguished Encoding Representation
+
+ All uses of ASN.1 in Kerberos shall use the Distinguished Encoding
+ Representation of the data elements as described in the X.509
+ specification, section 8.7 [8].
+
+5.2. ASN.1 Base Definitions
+
+ The following ASN.1 base definitions are used in the rest of this
+ section. Note that since the underscore character (_) is not
+ permitted in ASN.1 names, the hyphen (-) is used in its place for the
+ purposes of ASN.1 names.
+
+ Realm ::= GeneralString
+ PrincipalName ::= SEQUENCE {
+ name-type[0] INTEGER,
+ name-string[1] SEQUENCE OF GeneralString
+ }
+
+ Kerberos realms are encoded as GeneralStrings. Realms shall not
+ contain a character with the code 0 (the ASCII NUL). Most realms
+ will usually consist of several components separated by periods (.),
+ in the style of Internet Domain Names, or separated by slashes (/) in
+
+
+
+Kohl & Neuman [Page 38]
+
+RFC 1510 Kerberos September 1993
+
+
+ the style of X.500 names. Acceptable forms for realm names are
+ specified in section 7. A PrincipalName is a typed sequence of
+ components consisting of the following sub-fields:
+
+ name-type This field specifies the type of name that follows.
+ Pre-defined values for this field are
+ specified in section 7.2. The name-type should be
+ treated as a hint. Ignoring the name type, no two
+ names can be the same (i.e., at least one of the
+ components, or the realm, must be different).
+ This constraint may be eliminated in the future.
+
+ name-string This field encodes a sequence of components that
+ form a name, each component encoded as a General
+ String. Taken together, a PrincipalName and a Realm
+ form a principal identifier. Most PrincipalNames
+ will have only a few components (typically one or two).
+
+ KerberosTime ::= GeneralizedTime
+ -- Specifying UTC time zone (Z)
+
+ The timestamps used in Kerberos are encoded as GeneralizedTimes. An
+ encoding shall specify the UTC time zone (Z) and shall not include
+ any fractional portions of the seconds. It further shall not include
+ any separators. Example: The only valid format for UTC time 6
+ minutes, 27 seconds after 9 pm on 6 November 1985 is 19851106210627Z.
+
+ HostAddress ::= SEQUENCE {
+ addr-type[0] INTEGER,
+ address[1] OCTET STRING
+ }
+
+ HostAddresses ::= SEQUENCE OF SEQUENCE {
+ addr-type[0] INTEGER,
+ address[1] OCTET STRING
+ }
+
+
+ The host adddress encodings consists of two fields:
+
+ addr-type This field specifies the type of address that
+ follows. Pre-defined values for this field are
+ specified in section 8.1.
+
+
+ address This field encodes a single address of type addr-type.
+
+ The two forms differ slightly. HostAddress contains exactly one
+
+
+
+Kohl & Neuman [Page 39]
+
+RFC 1510 Kerberos September 1993
+
+
+ address; HostAddresses contains a sequence of possibly many
+ addresses.
+
+ AuthorizationData ::= SEQUENCE OF SEQUENCE {
+ ad-type[0] INTEGER,
+ ad-data[1] OCTET STRING
+ }
+
+
+ ad-data This field contains authorization data to be
+ interpreted according to the value of the
+ corresponding ad-type field.
+
+ ad-type This field specifies the format for the ad-data
+ subfield. All negative values are reserved for
+ local use. Non-negative values are reserved for
+ registered use.
+
+ APOptions ::= BIT STRING {
+ reserved(0),
+ use-session-key(1),
+ mutual-required(2)
+ }
+
+
+ TicketFlags ::= BIT STRING {
+ reserved(0),
+ forwardable(1),
+ forwarded(2),
+ proxiable(3),
+ proxy(4),
+ may-postdate(5),
+ postdated(6),
+ invalid(7),
+ renewable(8),
+ initial(9),
+ pre-authent(10),
+ hw-authent(11)
+ }
+
+ KDCOptions ::= BIT STRING {
+ reserved(0),
+ forwardable(1),
+ forwarded(2),
+ proxiable(3),
+ proxy(4),
+ allow-postdate(5),
+ postdated(6),
+
+
+
+Kohl & Neuman [Page 40]
+
+RFC 1510 Kerberos September 1993
+
+
+ unused7(7),
+ renewable(8),
+ unused9(9),
+ unused10(10),
+ unused11(11),
+ renewable-ok(27),
+ enc-tkt-in-skey(28),
+ renew(30),
+ validate(31)
+ }
+
+
+ LastReq ::= SEQUENCE OF SEQUENCE {
+ lr-type[0] INTEGER,
+ lr-value[1] KerberosTime
+ }
+
+ lr-type This field indicates how the following lr-value
+ field is to be interpreted. Negative values indicate
+ that the information pertains only to the
+ responding server. Non-negative values pertain to
+ all servers for the realm.
+
+ If the lr-type field is zero (0), then no information
+ is conveyed by the lr-value subfield. If the
+ absolute value of the lr-type field is one (1),
+ then the lr-value subfield is the time of last
+ initial request for a TGT. If it is two (2), then
+ the lr-value subfield is the time of last initial
+ request. If it is three (3), then the lr-value
+ subfield is the time of issue for the newest
+ ticket-granting ticket used. If it is four (4),
+ then the lr-value subfield is the time of the last
+ renewal. If it is five (5), then the lr-value
+ subfield is the time of last request (of any
+ type).
+
+ lr-value This field contains the time of the last request.
+ The time must be interpreted according to the contents
+ of the accompanying lr-type subfield.
+
+ See section 6 for the definitions of Checksum, ChecksumType,
+ EncryptedData, EncryptionKey, EncryptionType, and KeyType.
+
+
+
+
+
+
+
+
+Kohl & Neuman [Page 41]
+
+RFC 1510 Kerberos September 1993
+
+
+5.3. Tickets and Authenticators
+
+ This section describes the format and encryption parameters for
+ tickets and authenticators. When a ticket or authenticator is
+ included in a protocol message it is treated as an opaque object.
+
+5.3.1. Tickets
+
+ A ticket is a record that helps a client authenticate to a service.
+ A Ticket contains the following information:
+
+Ticket ::= [APPLICATION 1] SEQUENCE {
+ tkt-vno[0] INTEGER,
+ realm[1] Realm,
+ sname[2] PrincipalName,
+ enc-part[3] EncryptedData
+}
+-- Encrypted part of ticket
+EncTicketPart ::= [APPLICATION 3] SEQUENCE {
+ flags[0] TicketFlags,
+ key[1] EncryptionKey,
+ crealm[2] Realm,
+ cname[3] PrincipalName,
+ transited[4] TransitedEncoding,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ caddr[9] HostAddresses OPTIONAL,
+ authorization-data[10] AuthorizationData OPTIONAL
+}
+-- encoded Transited field
+TransitedEncoding ::= SEQUENCE {
+ tr-type[0] INTEGER, -- must be registered
+ contents[1] OCTET STRING
+}
+
+ The encoding of EncTicketPart is encrypted in the key shared by
+ Kerberos and the end server (the server's secret key). See section 6
+ for the format of the ciphertext.
+
+ tkt-vno This field specifies the version number for the ticket
+ format. This document describes version number 5.
+
+ realm This field specifies the realm that issued a ticket. It
+ also serves to identify the realm part of the server's
+ principal identifier. Since a Kerberos server can only
+ issue tickets for servers within its realm, the two will
+
+
+
+Kohl & Neuman [Page 42]
+
+RFC 1510 Kerberos September 1993
+
+
+ always be identical.
+
+ sname This field specifies the name part of the server's
+ identity.
+
+ enc-part This field holds the encrypted encoding of the
+ EncTicketPart sequence.
+
+ flags This field indicates which of various options were used or
+ requested when the ticket was issued. It is a bit-field,
+ where the selected options are indicated by the bit being
+ set (1), and the unselected options and reserved fields
+ being reset (0). Bit 0 is the most significant bit. The
+ encoding of the bits is specified in section 5.2. The
+ flags are described in more detail above in section 2. The
+ meanings of the flags are:
+
+ Bit(s) Name Description
+
+ 0 RESERVED Reserved for future expansion of this
+ field.
+
+ 1 FORWARDABLE The FORWARDABLE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. When set,
+ this flag tells the ticket-granting
+ server that it is OK to issue a new
+ ticket- granting ticket with a
+ different network address based on
+ the presented ticket.
+
+ 2 FORWARDED When set, this flag indicates that
+ the ticket has either been forwarded
+ or was issued based on authentication
+ involving a forwarded ticket-granting
+ ticket.
+
+ 3 PROXIABLE The PROXIABLE flag is normally only
+ interpreted by the TGS, and can be
+ ignored by end servers. The PROXIABLE
+ flag has an interpretation identical
+ to that of the FORWARDABLE flag,
+ except that the PROXIABLE flag tells
+ the ticket-granting server that only
+ non- ticket-granting tickets may be
+ issued with different network
+ addresses.
+
+
+
+
+Kohl & Neuman [Page 43]
+
+RFC 1510 Kerberos September 1993
+
+
+ 4 PROXY When set, this flag indicates that a
+ ticket is a proxy.
+
+ 5 MAY-POSTDATE The MAY-POSTDATE flag is normally
+ only interpreted by the TGS, and can
+ be ignored by end servers. This flag
+ tells the ticket-granting server that
+ a post- dated ticket may be issued
+ based on this ticket-granting ticket.
+
+ 6 POSTDATED This flag indicates that this ticket
+ has been postdated. The end-service
+ can check the authtime field to see
+ when the original authentication
+ occurred.
+
+ 7 INVALID This flag indicates that a ticket is
+ invalid, and it must be validated by
+ the KDC before use. Application
+ servers must reject tickets which
+ have this flag set.
+
+ 8 RENEWABLE The RENEWABLE flag is normally only
+ interpreted by the TGS, and can
+ usually be ignored by end servers
+ (some particularly careful servers
+ may wish to disallow renewable
+ tickets). A renewable ticket can be
+ used to obtain a replacement ticket
+ that expires at a later date.
+
+ 9 INITIAL This flag indicates that this ticket
+ was issued using the AS protocol, and
+ not issued based on a ticket-granting
+ ticket.
+
+ 10 PRE-AUTHENT This flag indicates that during
+ initial authentication, the client
+ was authenticated by the KDC before a
+ ticket was issued. The strength of
+ the preauthentication method is not
+ indicated, but is acceptable to the
+ KDC.
+
+ 11 HW-AUTHENT This flag indicates that the protocol
+ employed for initial authentication
+ required the use of hardware expected
+ to be possessed solely by the named
+
+
+
+Kohl & Neuman [Page 44]
+
+RFC 1510 Kerberos September 1993
+
+
+ client. The hardware authentication
+ method is selected by the KDC and the
+ strength of the method is not
+ indicated.
+
+ 12-31 RESERVED Reserved for future use.
+
+ key This field exists in the ticket and the KDC response and is
+ used to pass the session key from Kerberos to the
+ application server and the client. The field's encoding is
+ described in section 6.2.
+
+ crealm This field contains the name of the realm in which the
+ client is registered and in which initial authentication
+ took place.
+
+ cname This field contains the name part of the client's principal
+ identifier.
+
+ transited This field lists the names of the Kerberos realms that took
+ part in authenticating the user to whom this ticket was
+ issued. It does not specify the order in which the realms
+ were transited. See section 3.3.3.1 for details on how
+ this field encodes the traversed realms.
+
+ authtime This field indicates the time of initial authentication for
+ the named principal. It is the time of issue for the
+ original ticket on which this ticket is based. It is
+ included in the ticket to provide additional information to
+ the end service, and to provide the necessary information
+ for implementation of a `hot list' service at the KDC. An
+ end service that is particularly paranoid could refuse to
+ accept tickets for which the initial authentication
+ occurred "too far" in the past.
+
+ This field is also returned as part of the response from
+ the KDC. When returned as part of the response to initial
+ authentication (KRB_AS_REP), this is the current time on
+ the Kerberos server (It is NOT recommended that this time
+ value be used to adjust the workstation's clock since the
+ workstation cannot reliably determine that such a
+ KRB_AS_REP actually came from the proper KDC in a timely
+ manner.).
+
+ starttime This field in the ticket specifies the time after which the
+ ticket is valid. Together with endtime, this field
+ specifies the life of the ticket. If it is absent from
+ the ticket, its value should be treated as that of the
+
+
+
+Kohl & Neuman [Page 45]
+
+RFC 1510 Kerberos September 1993
+
+
+ authtime field.
+
+ endtime This field contains the time after which the ticket will
+ not be honored (its expiration time). Note that individual
+ services may place their own limits on the life of a ticket
+ and may reject tickets which have not yet expired. As
+ such, this is really an upper bound on the expiration time
+ for the ticket.
+
+ renew-till This field is only present in tickets that have the
+ RENEWABLE flag set in the flags field. It indicates the
+ maximum endtime that may be included in a renewal. It can
+ be thought of as the absolute expiration time for the
+ ticket, including all renewals.
+
+ caddr This field in a ticket contains zero (if omitted) or more
+ (if present) host addresses. These are the addresses from
+ which the ticket can be used. If there are no addresses,
+ the ticket can be used from any location. The decision
+ by the KDC to issue or by the end server to accept zero-
+ address tickets is a policy decision and is left to the
+ Kerberos and end-service administrators; they may refuse to
+ issue or accept such tickets. The suggested and default
+ policy, however, is that such tickets will only be issued
+ or accepted when additional information that can be used to
+ restrict the use of the ticket is included in the
+ authorization_data field. Such a ticket is a capability.
+
+ Network addresses are included in the ticket to make it
+ harder for an attacker to use stolen credentials. Because
+ the session key is not sent over the network in cleartext,
+ credentials can't be stolen simply by listening to the
+ network; an attacker has to gain access to the session key
+ (perhaps through operating system security breaches or a
+ careless user's unattended session) to make use of stolen
+ tickets.
+
+ It is important to note that the network address from which
+ a connection is received cannot be reliably determined.
+ Even if it could be, an attacker who has compromised the
+ client's workstation could use the credentials from there.
+ Including the network addresses only makes it more
+ difficult, not impossible, for an attacker to walk off with
+ stolen credentials and then use them from a "safe"
+ location.
+
+
+
+
+
+
+Kohl & Neuman [Page 46]
+
+RFC 1510 Kerberos September 1993
+
+
+ authorization-data The authorization-data field is used to pass
+ authorization data from the principal on whose behalf a
+ ticket was issued to the application service. If no
+ authorization data is included, this field will be left
+ out. The data in this field are specific to the end
+ service. It is expected that the field will contain the
+ names of service specific objects, and the rights to those
+ objects. The format for this field is described in section
+ 5.2. Although Kerberos is not concerned with the format of
+ the contents of the subfields, it does carry type
+ information (ad-type).
+
+ By using the authorization_data field, a principal is able
+ to issue a proxy that is valid for a specific purpose. For
+ example, a client wishing to print a file can obtain a file
+ server proxy to be passed to the print server. By
+ specifying the name of the file in the authorization_data
+ field, the file server knows that the print server can only
+ use the client's rights when accessing the particular file
+ to be printed.
+
+ It is interesting to note that if one specifies the
+ authorization-data field of a proxy and leaves the host
+ addresses blank, the resulting ticket and session key can
+ be treated as a capability. See [9] for some suggested
+ uses of this field.
+
+ The authorization-data field is optional and does not have
+ to be included in a ticket.
+
+5.3.2. Authenticators
+
+ An authenticator is a record sent with a ticket to a server to
+ certify the client's knowledge of the encryption key in the ticket,
+ to help the server detect replays, and to help choose a "true session
+ key" to use with the particular session. The encoding is encrypted
+ in the ticket's session key shared by the client and the server:
+
+-- Unencrypted authenticator
+Authenticator ::= [APPLICATION 2] SEQUENCE {
+ authenticator-vno[0] INTEGER,
+ crealm[1] Realm,
+ cname[2] PrincipalName,
+ cksum[3] Checksum OPTIONAL,
+ cusec[4] INTEGER,
+ ctime[5] KerberosTime,
+ subkey[6] EncryptionKey OPTIONAL,
+ seq-number[7] INTEGER OPTIONAL,
+
+
+
+Kohl & Neuman [Page 47]
+
+RFC 1510 Kerberos September 1993
+
+
+ authorization-data[8] AuthorizationData OPTIONAL
+ }
+
+ authenticator-vno This field specifies the version number for the
+ format of the authenticator. This document specifies
+ version 5.
+
+ crealm and cname These fields are the same as those described for the
+ ticket in section 5.3.1.
+
+ cksum This field contains a checksum of the the application data
+ that accompanies the KRB_AP_REQ.
+
+ cusec This field contains the microsecond part of the client's
+ timestamp. Its value (before encryption) ranges from 0 to
+ 999999. It often appears along with ctime. The two fields
+ are used together to specify a reasonably accurate
+ timestamp.
+
+ ctime This field contains the current time on the client's host.
+
+ subkey This field contains the client's choice for an encryption
+ key which is to be used to protect this specific
+ application session. Unless an application specifies
+ otherwise, if this field is left out the session key from
+ the ticket will be used.
+
+ seq-number This optional field includes the initial sequence number
+ to be used by the KRB_PRIV or KRB_SAFE messages when
+ sequence numbers are used to detect replays (It may also be
+ used by application specific messages). When included in
+ the authenticator this field specifies the initial sequence
+ number for messages from the client to the server. When
+ included in the AP-REP message, the initial sequence number
+ is that for messages from the server to the client. When
+ used in KRB_PRIV or KRB_SAFE messages, it is incremented by
+ one after each message is sent.
+
+ For sequence numbers to adequately support the detection of
+ replays they should be non-repeating, even across
+ connection boundaries. The initial sequence number should
+ be random and uniformly distributed across the full space
+ of possible sequence numbers, so that it cannot be guessed
+ by an attacker and so that it and the successive sequence
+ numbers do not repeat other sequences.
+
+
+
+
+
+
+Kohl & Neuman [Page 48]
+
+RFC 1510 Kerberos September 1993
+
+
+ authorization-data This field is the same as described for the ticket
+ in section 5.3.1. It is optional and will only appear when
+ additional restrictions are to be placed on the use of a
+ ticket, beyond those carried in the ticket itself.
+
+5.4. Specifications for the AS and TGS exchanges
+
+ This section specifies the format of the messages used in exchange
+ between the client and the Kerberos server. The format of possible
+ error messages appears in section 5.9.1.
+
+5.4.1. KRB_KDC_REQ definition
+
+ The KRB_KDC_REQ message has no type of its own. Instead, its type is
+ one of KRB_AS_REQ or KRB_TGS_REQ depending on whether the request is
+ for an initial ticket or an additional ticket. In either case, the
+ message is sent from the client to the Authentication Server to
+ request credentials for a service.
+
+The message fields are:
+
+AS-REQ ::= [APPLICATION 10] KDC-REQ
+TGS-REQ ::= [APPLICATION 12] KDC-REQ
+
+KDC-REQ ::= SEQUENCE {
+ pvno[1] INTEGER,
+ msg-type[2] INTEGER,
+ padata[3] SEQUENCE OF PA-DATA OPTIONAL,
+ req-body[4] KDC-REQ-BODY
+}
+
+PA-DATA ::= SEQUENCE {
+ padata-type[1] INTEGER,
+ padata-value[2] OCTET STRING,
+ -- might be encoded AP-REQ
+}
+
+KDC-REQ-BODY ::= SEQUENCE {
+ kdc-options[0] KDCOptions,
+ cname[1] PrincipalName OPTIONAL,
+ -- Used only in AS-REQ
+ realm[2] Realm, -- Server's realm
+ -- Also client's in AS-REQ
+ sname[3] PrincipalName OPTIONAL,
+ from[4] KerberosTime OPTIONAL,
+ till[5] KerberosTime,
+ rtime[6] KerberosTime OPTIONAL,
+ nonce[7] INTEGER,
+
+
+
+Kohl & Neuman [Page 49]
+
+RFC 1510 Kerberos September 1993
+
+
+ etype[8] SEQUENCE OF INTEGER, -- EncryptionType,
+ -- in preference order
+ addresses[9] HostAddresses OPTIONAL,
+ enc-authorization-data[10] EncryptedData OPTIONAL,
+ -- Encrypted AuthorizationData encoding
+ additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
+}
+
+ The fields in this message are:
+
+ pvno This field is included in each message, and specifies the
+ protocol version number. This document specifies protocol
+ version 5.
+
+ msg-type This field indicates the type of a protocol message. It
+ will almost always be the same as the application
+ identifier associated with a message. It is included to
+ make the identifier more readily accessible to the
+ application. For the KDC-REQ message, this type will be
+ KRB_AS_REQ or KRB_TGS_REQ.
+
+ padata The padata (pre-authentication data) field contains a of
+ authentication information which may be needed before
+ credentials can be issued or decrypted. In the case of
+ requests for additional tickets (KRB_TGS_REQ), this field
+ will include an element with padata-type of PA-TGS-REQ and
+ data of an authentication header (ticket-granting ticket
+ and authenticator). The checksum in the authenticator
+ (which must be collisionproof) is to be computed over the
+ KDC-REQ-BODY encoding. In most requests for initial
+ authentication (KRB_AS_REQ) and most replies (KDC-REP), the
+ padata field will be left out.
+
+ This field may also contain information needed by certain
+ extensions to the Kerberos protocol. For example, it might
+ be used to initially verify the identity of a client before
+ any response is returned. This is accomplished with a
+ padata field with padata-type equal to PA-ENC-TIMESTAMP and
+ padata-value defined as follows:
+
+ padata-type ::= PA-ENC-TIMESTAMP
+ padata-value ::= EncryptedData -- PA-ENC-TS-ENC
+
+ PA-ENC-TS-ENC ::= SEQUENCE {
+ patimestamp[0] KerberosTime, -- client's time
+ pausec[1] INTEGER OPTIONAL
+ }
+
+
+
+
+Kohl & Neuman [Page 50]
+
+RFC 1510 Kerberos September 1993
+
+
+ with patimestamp containing the client's time and pausec
+ containing the microseconds which may be omitted if a
+ client will not generate more than one request per second.
+ The ciphertext (padata-value) consists of the PA-ENC-TS-ENC
+ sequence, encrypted using the client's secret key.
+
+ The padata field can also contain information needed to
+ help the KDC or the client select the key needed for
+ generating or decrypting the response. This form of the
+ padata is useful for supporting the use of certain
+ "smartcards" with Kerberos. The details of such extensions
+ are beyond the scope of this specification. See [10] for
+ additional uses of this field.
+
+ padata-type The padata-type element of the padata field indicates the
+ way that the padata-value element is to be interpreted.
+ Negative values of padata-type are reserved for
+ unregistered use; non-negative values are used for a
+ registered interpretation of the element type.
+
+ req-body This field is a placeholder delimiting the extent of the
+ remaining fields. If a checksum is to be calculated over
+ the request, it is calculated over an encoding of the KDC-
+ REQ-BODY sequence which is enclosed within the req-body
+ field.
+
+ kdc-options This field appears in the KRB_AS_REQ and KRB_TGS_REQ
+ requests to the KDC and indicates the flags that the client
+ wants set on the tickets as well as other information that
+ is to modify the behavior of the KDC. Where appropriate,
+ the name of an option may be the same as the flag that is
+ set by that option. Although in most case, the bit in the
+ options field will be the same as that in the flags field,
+ this is not guaranteed, so it is not acceptable to simply
+ copy the options field to the flags field. There are
+ various checks that must be made before honoring an option
+ anyway.
+
+ The kdc_options field is a bit-field, where the selected
+ options are indicated by the bit being set (1), and the
+ unselected options and reserved fields being reset (0).
+ The encoding of the bits is specified in section 5.2. The
+ options are described in more detail above in section 2.
+ The meanings of the options are:
+
+
+
+
+
+
+
+Kohl & Neuman [Page 51]
+
+RFC 1510 Kerberos September 1993
+
+
+ Bit(s) Name Description
+
+ 0 RESERVED Reserved for future expansion of this
+ field.
+
+ 1 FORWARDABLE The FORWARDABLE option indicates that
+ the ticket to be issued is to have its
+ forwardable flag set. It may only be
+ set on the initial request, or in a
+ subsequent request if the ticket-
+ granting ticket on which it is based
+ is also forwardable.
+
+ 2 FORWARDED The FORWARDED option is only specified
+ in a request to the ticket-granting
+ server and will only be honored if the
+ ticket-granting ticket in the request
+ has its FORWARDABLE bit set. This
+ option indicates that this is a
+ request for forwarding. The
+ address(es) of the host from which the
+ resulting ticket is to be valid are
+ included in the addresses field of the
+ request.
+
+
+ 3 PROXIABLE The PROXIABLE option indicates that
+ the ticket to be issued is to have its
+ proxiable flag set. It may only be set
+ on the initial request, or in a
+ subsequent request if the ticket-
+ granting ticket on which it is based
+ is also proxiable.
+
+ 4 PROXY The PROXY option indicates that this
+ is a request for a proxy. This option
+ will only be honored if the ticket-
+ granting ticket in the request has its
+ PROXIABLE bit set. The address(es) of
+ the host from which the resulting
+ ticket is to be valid are included in
+ the addresses field of the request.
+
+ 5 ALLOW-POSTDATE The ALLOW-POSTDATE option indicates
+ that the ticket to be issued is to
+ have its MAY-POSTDATE flag set. It
+ may only be set on the initial
+ request, or in a subsequent request if
+
+
+
+Kohl & Neuman [Page 52]
+
+RFC 1510 Kerberos September 1993
+
+
+ the ticket-granting ticket on which it
+ is based also has its MAY-POSTDATE
+ flag set.
+
+ 6 POSTDATED The POSTDATED option indicates that
+ this is a request for a postdated
+ ticket. This option will only be
+ honored if the ticket-granting ticket
+ on which it is based has its MAY-
+ POSTDATE flag set. The resulting
+ ticket will also have its INVALID flag
+ set, and that flag may be reset by a
+ subsequent request to the KDC after
+ the starttime in the ticket has been
+ reached.
+
+ 7 UNUSED This option is presently unused.
+
+ 8 RENEWABLE The RENEWABLE option indicates that
+ the ticket to be issued is to have its
+ RENEWABLE flag set. It may only be
+ set on the initial request, or when
+ the ticket-granting ticket on which
+ the request is based is also
+ renewable. If this option is
+ requested, then the rtime field in the
+ request contains the desired absolute
+ expiration time for the ticket.
+
+ 9-26 RESERVED Reserved for future use.
+
+ 27 RENEWABLE-OK The RENEWABLE-OK option indicates that
+ a renewable ticket will be acceptable
+ if a ticket with the requested life
+ cannot otherwise be provided. If a
+ ticket with the requested life cannot
+ be provided, then a renewable ticket
+ may be issued with a renew-till equal
+ to the the requested endtime. The
+ value of the renew-till field may
+ still be limited by local limits, or
+ limits selected by the individual
+ principal or server.
+
+ 28 ENC-TKT-IN-SKEY This option is used only by the
+ ticket-granting service. The ENC-
+ TKT-IN-SKEY option indicates that the
+ ticket for the end server is to be
+
+
+
+Kohl & Neuman [Page 53]
+
+RFC 1510 Kerberos September 1993
+
+
+ encrypted in the session key from the
+ additional ticket-granting ticket
+ provided.
+
+ 29 RESERVED Reserved for future use.
+
+ 30 RENEW This option is used only by the
+ ticket-granting service. The RENEW
+ option indicates that the present
+ request is for a renewal. The ticket
+ provided is encrypted in the secret
+ key for the server on which it is
+ valid. This option will only be
+ honored if the ticket to be renewed
+ has its RENEWABLE flag set and if the
+ time in its renew till field has not
+ passed. The ticket to be renewed is
+ passed in the padata field as part of
+ the authentication header.
+
+ 31 VALIDATE This option is used only by the
+ ticket-granting service. The VALIDATE
+ option indicates that the request is
+ to validate a postdated ticket. It
+ will only be honored if the ticket
+ presented is postdated, presently has
+ its INVALID flag set, and would be
+ otherwise usable at this time. A
+ ticket cannot be validated before its
+ starttime. The ticket presented for
+ validation is encrypted in the key of
+ the server for which it is valid and
+ is passed in the padata field as part
+ of the authentication header.
+
+ cname and sname These fields are the same as those described for the
+ ticket in section 5.3.1. sname may only be absent when the
+ ENC-TKT-IN-SKEY option is specified. If absent, the name
+ of the server is taken from the name of the client in the
+ ticket passed as additional-tickets.
+
+ enc-authorization-data The enc-authorization-data, if present (and it
+ can only be present in the TGS_REQ form), is an encoding of
+ the desired authorization-data encrypted under the sub-
+ session key if present in the Authenticator, or
+ alternatively from the session key in the ticket-granting
+ ticket, both from the padata field in the KRB_AP_REQ.
+
+
+
+
+Kohl & Neuman [Page 54]
+
+RFC 1510 Kerberos September 1993
+
+
+ realm This field specifies the realm part of the server's
+ principal identifier. In the AS exchange, this is also the
+ realm part of the client's principal identifier.
+
+ from This field is included in the KRB_AS_REQ and KRB_TGS_REQ
+ ticket requests when the requested ticket is to be
+ postdated. It specifies the desired start time for the
+ requested ticket.
+
+ till This field contains the expiration date requested by the
+ client in a ticket request.
+
+ rtime This field is the requested renew-till time sent from a
+ client to the KDC in a ticket request. It is optional.
+
+ nonce This field is part of the KDC request and response. It it
+ intended to hold a random number generated by the client.
+ If the same number is included in the encrypted response
+ from the KDC, it provides evidence that the response is
+ fresh and has not been replayed by an attacker. Nonces
+ must never be re-used. Ideally, it should be gen erated
+ randomly, but if the correct time is known, it may suffice
+ (Note, however, that if the time is used as the nonce, one
+ must make sure that the workstation time is monotonically
+ increasing. If the time is ever reset backwards, there is
+ a small, but finite, probability that a nonce will be
+ reused.).
+
+ etype This field specifies the desired encryption algorithm to be
+ used in the response.
+
+ addresses This field is included in the initial request for tickets,
+ and optionally included in requests for additional tickets
+ from the ticket-granting server. It specifies the
+ addresses from which the requested ticket is to be valid.
+ Normally it includes the addresses for the client's host.
+ If a proxy is requested, this field will contain other
+ addresses. The contents of this field are usually copied
+ by the KDC into the caddr field of the resulting ticket.
+
+ additional-tickets Additional tickets may be optionally included in a
+ request to the ticket-granting server. If the ENC-TKT-IN-
+ SKEY option has been specified, then the session key from
+ the additional ticket will be used in place of the server's
+ key to encrypt the new ticket. If more than one option
+ which requires additional tickets has been specified, then
+ the additional tickets are used in the order specified by
+ the ordering of the options bits (see kdc-options, above).
+
+
+
+Kohl & Neuman [Page 55]
+
+RFC 1510 Kerberos September 1993
+
+
+ The application code will be either ten (10) or twelve (12) depending
+ on whether the request is for an initial ticket (AS-REQ) or for an
+ additional ticket (TGS-REQ).
+
+ The optional fields (addresses, authorization-data and additional-
+ tickets) are only included if necessary to perform the operation
+ specified in the kdc-options field.
+
+ It should be noted that in KRB_TGS_REQ, the protocol version number
+ appears twice and two different message types appear: the KRB_TGS_REQ
+ message contains these fields as does the authentication header
+ (KRB_AP_REQ) that is passed in the padata field.
+
+5.4.2. KRB_KDC_REP definition
+
+ The KRB_KDC_REP message format is used for the reply from the KDC for
+ either an initial (AS) request or a subsequent (TGS) request. There
+ is no message type for KRB_KDC_REP. Instead, the type will be either
+ KRB_AS_REP or KRB_TGS_REP. The key used to encrypt the ciphertext
+ part of the reply depends on the message type. For KRB_AS_REP, the
+ ciphertext is encrypted in the client's secret key, and the client's
+ key version number is included in the key version number for the
+ encrypted data. For KRB_TGS_REP, the ciphertext is encrypted in the
+ sub-session key from the Authenticator, or if absent, the session key
+ from the ticket-granting ticket used in the request. In that case,
+ no version number will be present in the EncryptedData sequence.
+
+ The KRB_KDC_REP message contains the following fields:
+
+ AS-REP ::= [APPLICATION 11] KDC-REP
+ TGS-REP ::= [APPLICATION 13] KDC-REP
+
+ KDC-REP ::= SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ padata[2] SEQUENCE OF PA-DATA OPTIONAL,
+ crealm[3] Realm,
+ cname[4] PrincipalName,
+ ticket[5] Ticket,
+ enc-part[6] EncryptedData
+ }
+
+ EncASRepPart ::= [APPLICATION 25[25]] EncKDCRepPart
+ EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
+
+ EncKDCRepPart ::= SEQUENCE {
+ key[0] EncryptionKey,
+ last-req[1] LastReq,
+
+
+
+Kohl & Neuman [Page 56]
+
+RFC 1510 Kerberos September 1993
+
+
+ nonce[2] INTEGER,
+ key-expiration[3] KerberosTime OPTIONAL,
+ flags[4] TicketFlags,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ srealm[9] Realm,
+ sname[10] PrincipalName,
+ caddr[11] HostAddresses OPTIONAL
+ }
+
+ NOTE: In EncASRepPart, the application code in the encrypted
+ part of a message provides an additional check that
+ the message was decrypted properly.
+
+ pvno and msg-type These fields are described above in section 5.4.1.
+ msg-type is either KRB_AS_REP or KRB_TGS_REP.
+
+ padata This field is described in detail in section 5.4.1. One
+ possible use for this field is to encode an alternate
+ "mix-in" string to be used with a string-to-key algorithm
+ (such as is described in section 6.3.2). This ability is
+ useful to ease transitions if a realm name needs to change
+ (e.g., when a company is acquired); in such a case all
+ existing password-derived entries in the KDC database would
+ be flagged as needing a special mix-in string until the
+ next password change.
+
+ crealm, cname, srealm and sname These fields are the same as those
+ described for the ticket in section 5.3.1.
+
+ ticket The newly-issued ticket, from section 5.3.1.
+
+ enc-part This field is a place holder for the ciphertext and related
+ information that forms the encrypted part of a message.
+ The description of the encrypted part of the message
+ follows each appearance of this field. The encrypted part
+ is encoded as described in section 6.1.
+
+ key This field is the same as described for the ticket in
+ section 5.3.1.
+
+ last-req This field is returned by the KDC and specifies the time(s)
+ of the last request by a principal. Depending on what
+ information is available, this might be the last time that
+ a request for a ticket-granting ticket was made, or the
+ last time that a request based on a ticket-granting ticket
+
+
+
+Kohl & Neuman [Page 57]
+
+RFC 1510 Kerberos September 1993
+
+
+ was successful. It also might cover all servers for a
+ realm, or just the particular server. Some implementations
+ may display this information to the user to aid in
+ discovering unauthorized use of one's identity. It is
+ similar in spirit to the last login time displayed when
+ logging into timesharing systems.
+
+ nonce This field is described above in section 5.4.1.
+
+ key-expiration The key-expiration field is part of the response from
+ the KDC and specifies the time that the client's secret key
+ is due to expire. The expiration might be the result of
+ password aging or an account expiration. This field will
+ usually be left out of the TGS reply since the response to
+ the TGS request is encrypted in a session key and no client
+ information need be retrieved from the KDC database. It is
+ up to the application client (usually the login program) to
+ take appropriate action (such as notifying the user) if the
+ expira tion time is imminent.
+
+ flags, authtime, starttime, endtime, renew-till and caddr These
+ fields are duplicates of those found in the encrypted
+ portion of the attached ticket (see section 5.3.1),
+ provided so the client may verify they match the intended
+ request and to assist in proper ticket caching. If the
+ message is of type KRB_TGS_REP, the caddr field will only
+ be filled in if the request was for a proxy or forwarded
+ ticket, or if the user is substituting a subset of the
+ addresses from the ticket granting ticket. If the client-
+ requested addresses are not present or not used, then the
+ addresses contained in the ticket will be the same as those
+ included in the ticket-granting ticket.
+
+5.5. Client/Server (CS) message specifications
+
+ This section specifies the format of the messages used for the
+ authentication of the client to the application server.
+
+5.5.1. KRB_AP_REQ definition
+
+ The KRB_AP_REQ message contains the Kerberos protocol version number,
+ the message type KRB_AP_REQ, an options field to indicate any options
+ in use, and the ticket and authenticator themselves. The KRB_AP_REQ
+ message is often referred to as the "authentication header".
+
+ AP-REQ ::= [APPLICATION 14] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+
+
+
+Kohl & Neuman [Page 58]
+
+RFC 1510 Kerberos September 1993
+
+
+ ap-options[2] APOptions,
+ ticket[3] Ticket,
+ authenticator[4] EncryptedData
+ }
+
+ APOptions ::= BIT STRING {
+ reserved(0),
+ use-session-key(1),
+ mutual-required(2)
+ }
+
+ pvno and msg-type These fields are described above in section 5.4.1.
+ msg-type is KRB_AP_REQ.
+
+ ap-options This field appears in the application request (KRB_AP_REQ)
+ and affects the way the request is processed. It is a
+ bit-field, where the selected options are indicated by the
+ bit being set (1), and the unselected options and reserved
+ fields being reset (0). The encoding of the bits is
+ specified in section 5.2. The meanings of the options are:
+
+ Bit(s) Name Description
+
+ 0 RESERVED Reserved for future expansion of
+ this field.
+
+ 1 USE-SESSION-KEYThe USE-SESSION-KEY option indicates
+ that the ticket the client is
+ presenting to a server is encrypted in
+ the session key from the server's
+ ticket-granting ticket. When this
+ option is not specified, the ticket is
+ encrypted in the server's secret key.
+
+ 2 MUTUAL-REQUIREDThe MUTUAL-REQUIRED option tells the
+ server that the client requires mutual
+ authentication, and that it must
+ respond with a KRB_AP_REP message.
+
+ 3-31 RESERVED Reserved for future use.
+
+ ticket This field is a ticket authenticating the client to the
+ server.
+
+ authenticator This contains the authenticator, which includes the
+ client's choice of a subkey. Its encoding is described in
+ section 5.3.2.
+
+
+
+
+Kohl & Neuman [Page 59]
+
+RFC 1510 Kerberos September 1993
+
+
+5.5.2. KRB_AP_REP definition
+
+ The KRB_AP_REP message contains the Kerberos protocol version number,
+ the message type, and an encrypted timestamp. The message is sent in
+ in response to an application request (KRB_AP_REQ) where the mutual
+ authentication option has been selected in the ap-options field.
+
+ AP-REP ::= [APPLICATION 15] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[2] EncryptedData
+ }
+
+ EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
+ ctime[0] KerberosTime,
+ cusec[1] INTEGER,
+ subkey[2] EncryptionKey OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL
+ }
+
+ NOTE: in EncAPRepPart, the application code in the encrypted part of
+ a message provides an additional check that the message was decrypted
+ properly.
+
+ The encoded EncAPRepPart is encrypted in the shared session key of
+ the ticket. The optional subkey field can be used in an
+ application-arranged negotiation to choose a per association session
+ key.
+
+ pvno and msg-type These fields are described above in section 5.4.1.
+ msg-type is KRB_AP_REP.
+
+ enc-part This field is described above in section 5.4.2.
+
+ ctime This field contains the current time on the client's host.
+
+ cusec This field contains the microsecond part of the client's
+ timestamp.
+
+ subkey This field contains an encryption key which is to be used
+ to protect this specific application session. See section
+ 3.2.6 for specifics on how this field is used to negotiate
+ a key. Unless an application specifies otherwise, if this
+ field is left out, the sub-session key from the
+ authenticator, or if also left out, the session key from
+ the ticket will be used.
+
+
+
+
+
+Kohl & Neuman [Page 60]
+
+RFC 1510 Kerberos September 1993
+
+
+5.5.3. Error message reply
+
+ If an error occurs while processing the application request, the
+ KRB_ERROR message will be sent in response. See section 5.9.1 for
+ the format of the error message. The cname and crealm fields may be
+ left out if the server cannot determine their appropriate values from
+ the corresponding KRB_AP_REQ message. If the authenticator was
+ decipherable, the ctime and cusec fields will contain the values from
+ it.
+
+5.6. KRB_SAFE message specification
+
+ This section specifies the format of a message that can be used by
+ either side (client or server) of an application to send a tamper-
+ proof message to its peer. It presumes that a session key has
+ previously been exchanged (for example, by using the
+ KRB_AP_REQ/KRB_AP_REP messages).
+
+5.6.1. KRB_SAFE definition
+
+ The KRB_SAFE message contains user data along with a collision-proof
+ checksum keyed with the session key. The message fields are:
+
+ KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ safe-body[2] KRB-SAFE-BODY,
+ cksum[3] Checksum
+ }
+
+ KRB-SAFE-BODY ::= SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress,
+ r-address[5] HostAddress OPTIONAL
+ }
+
+ pvno and msg-type These fields are described above in section 5.4.1.
+ msg-type is KRB_SAFE.
+
+ safe-body This field is a placeholder for the body of the KRB-SAFE
+ message. It is to be encoded separately and then have the
+ checksum computed over it, for use in the cksum field.
+
+ cksum This field contains the checksum of the application data.
+ Checksum details are described in section 6.4. The
+
+
+
+Kohl & Neuman [Page 61]
+
+RFC 1510 Kerberos September 1993
+
+
+ checksum is computed over the encoding of the KRB-SAFE-BODY
+ sequence.
+
+ user-data This field is part of the KRB_SAFE and KRB_PRIV messages
+ and contain the application specific data that is being
+ passed from the sender to the recipient.
+
+ timestamp This field is part of the KRB_SAFE and KRB_PRIV messages.
+ Its contents are the current time as known by the sender of
+ the message. By checking the timestamp, the recipient of
+ the message is able to make sure that it was recently
+ generated, and is not a replay.
+
+ usec This field is part of the KRB_SAFE and KRB_PRIV headers.
+ It contains the microsecond part of the timestamp.
+
+ seq-number This field is described above in section 5.3.2.
+
+ s-address This field specifies the address in use by the sender of
+ the message.
+
+ r-address This field specifies the address in use by the recipient of
+ the message. It may be omitted for some uses (such as
+ broadcast protocols), but the recipient may arbitrarily
+ reject such messages. This field along with s-address can
+ be used to help detect messages which have been incorrectly
+ or maliciously delivered to the wrong recipient.
+
+5.7. KRB_PRIV message specification
+
+ This section specifies the format of a message that can be used by
+ either side (client or server) of an application to securely and
+ privately send a message to its peer. It presumes that a session key
+ has previously been exchanged (for example, by using the
+ KRB_AP_REQ/KRB_AP_REP messages).
+
+5.7.1. KRB_PRIV definition
+
+ The KRB_PRIV message contains user data encrypted in the Session Key.
+ The message fields are:
+
+ KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[3] EncryptedData
+ }
+
+
+
+
+
+Kohl & Neuman [Page 62]
+
+RFC 1510 Kerberos September 1993
+
+
+ EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress, -- sender's addr
+ r-address[5] HostAddress OPTIONAL
+ -- recip's addr
+ }
+
+ NOTE: In EncKrbPrivPart, the application code in the encrypted part
+ of a message provides an additional check that the message was
+ decrypted properly.
+
+ pvno and msg-type These fields are described above in section 5.4.1.
+ msg-type is KRB_PRIV.
+
+ enc-part This field holds an encoding of the EncKrbPrivPart sequence
+ encrypted under the session key (If supported by the
+ encryption method in use, an initialization vector may be
+ passed to the encryption procedure, in order to achieve
+ proper cipher chaining. The initialization vector might
+ come from the last block of the ciphertext from the
+ previous KRB_PRIV message, but it is the application's
+ choice whether or not to use such an initialization vector.
+ If left out, the default initialization vector for the
+ encryption algorithm will be used.). This encrypted
+ encoding is used for the enc-part field of the KRB-PRIV
+ message. See section 6 for the format of the ciphertext.
+
+ user-data, timestamp, usec, s-address and r-address These fields are
+ described above in section 5.6.1.
+
+ seq-number This field is described above in section 5.3.2.
+
+5.8. KRB_CRED message specification
+
+ This section specifies the format of a message that can be used to
+ send Kerberos credentials from one principal to another. It is
+ presented here to encourage a common mechanism to be used by
+ applications when forwarding tickets or providing proxies to
+ subordinate servers. It presumes that a session key has already been
+ exchanged perhaps by using the KRB_AP_REQ/KRB_AP_REP messages.
+
+5.8.1. KRB_CRED definition
+
+ The KRB_CRED message contains a sequence of tickets to be sent and
+ information needed to use the tickets, including the session key from
+
+
+
+Kohl & Neuman [Page 63]
+
+RFC 1510 Kerberos September 1993
+
+
+ each. The information needed to use the tickets is encryped under an
+ encryption key previously exchanged. The message fields are:
+
+ KRB-CRED ::= [APPLICATION 22] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER, -- KRB_CRED
+ tickets[2] SEQUENCE OF Ticket,
+ enc-part[3] EncryptedData
+ }
+
+ EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
+ ticket-info[0] SEQUENCE OF KrbCredInfo,
+ nonce[1] INTEGER OPTIONAL,
+ timestamp[2] KerberosTime OPTIONAL,
+ usec[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+ }
+
+ KrbCredInfo ::= SEQUENCE {
+ key[0] EncryptionKey,
+ prealm[1] Realm OPTIONAL,
+ pname[2] PrincipalName OPTIONAL,
+ flags[3] TicketFlags OPTIONAL,
+ authtime[4] KerberosTime OPTIONAL,
+ starttime[5] KerberosTime OPTIONAL,
+ endtime[6] KerberosTime OPTIONAL
+ renew-till[7] KerberosTime OPTIONAL,
+ srealm[8] Realm OPTIONAL,
+ sname[9] PrincipalName OPTIONAL,
+ caddr[10] HostAddresses OPTIONAL
+ }
+
+
+ pvno and msg-type These fields are described above in section 5.4.1.
+ msg-type is KRB_CRED.
+
+ tickets
+ These are the tickets obtained from the KDC specifically
+ for use by the intended recipient. Successive tickets are
+ paired with the corresponding KrbCredInfo sequence from the
+ enc-part of the KRB-CRED message.
+
+ enc-part This field holds an encoding of the EncKrbCredPart sequence
+ encrypted under the session key shared between the sender
+ and the intended recipient. This encrypted encoding is
+ used for the enc-part field of the KRB-CRED message. See
+ section 6 for the format of the ciphertext.
+
+
+
+Kohl & Neuman [Page 64]
+
+RFC 1510 Kerberos September 1993
+
+
+ nonce If practical, an application may require the inclusion of a
+ nonce generated by the recipient of the message. If the
+ same value is included as the nonce in the message, it
+ provides evidence that the message is fresh and has not
+ been replayed by an attacker. A nonce must never be re-
+ used; it should be generated randomly by the recipient of
+ the message and provided to the sender of the mes sage in
+ an application specific manner.
+
+ timestamp and usec These fields specify the time that the KRB-CRED
+ message was generated. The time is used to provide
+ assurance that the message is fresh.
+
+ s-address and r-address These fields are described above in section
+ 5.6.1. They are used optionally to provide additional
+ assurance of the integrity of the KRB-CRED message.
+
+ key This field exists in the corresponding ticket passed by the
+ KRB-CRED message and is used to pass the session key from
+ the sender to the intended recipient. The field's encoding
+ is described in section 6.2.
+
+ The following fields are optional. If present, they can be
+ associated with the credentials in the remote ticket file. If left
+ out, then it is assumed that the recipient of the credentials already
+ knows their value.
+
+ prealm and pname The name and realm of the delegated principal
+ identity.
+
+ flags, authtime, starttime, endtime, renew-till, srealm, sname,
+ and caddr These fields contain the values of the
+ corresponding fields from the ticket found in the ticket
+ field. Descriptions of the fields are identical to the
+ descriptions in the KDC-REP message.
+
+5.9. Error message specification
+
+ This section specifies the format for the KRB_ERROR message. The
+ fields included in the message are intended to return as much
+ information as possible about an error. It is not expected that all
+ the information required by the fields will be available for all
+ types of errors. If the appropriate information is not available
+ when the message is composed, the corresponding field will be left
+ out of the message.
+
+ Note that since the KRB_ERROR message is not protected by any
+ encryption, it is quite possible for an intruder to synthesize or
+
+
+
+Kohl & Neuman [Page 65]
+
+RFC 1510 Kerberos September 1993
+
+
+ modify such a message. In particular, this means that the client
+ should not use any fields in this message for security-critical
+ purposes, such as setting a system clock or generating a fresh
+ authenticator. The message can be useful, however, for advising a
+ user on the reason for some failure.
+
+5.9.1. KRB_ERROR definition
+
+ The KRB_ERROR message consists of the following fields:
+
+ KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ctime[2] KerberosTime OPTIONAL,
+ cusec[3] INTEGER OPTIONAL,
+ stime[4] KerberosTime,
+ susec[5] INTEGER,
+ error-code[6] INTEGER,
+ crealm[7] Realm OPTIONAL,
+ cname[8] PrincipalName OPTIONAL,
+ realm[9] Realm, -- Correct realm
+ sname[10] PrincipalName, -- Correct name
+ e-text[11] GeneralString OPTIONAL,
+ e-data[12] OCTET STRING OPTIONAL
+ }
+
+ pvno and msg-type These fields are described above in section 5.4.1.
+ msg-type is KRB_ERROR.
+
+ ctime This field is described above in section 5.4.1.
+
+ cusec This field is described above in section 5.5.2.
+
+ stime This field contains the current time on the server. It is
+ of type KerberosTime.
+
+ susec This field contains the microsecond part of the server's
+ timestamp. Its value ranges from 0 to 999. It appears
+ along with stime. The two fields are used in conjunction to
+ specify a reasonably accurate timestamp.
+
+ error-code This field contains the error code returned by Kerberos or
+ the server when a request fails. To interpret the value of
+ this field see the list of error codes in section 8.
+ Implementations are encouraged to provide for national
+ language support in the display of error messages.
+
+ crealm, cname, srealm and sname These fields are described above in
+
+
+
+Kohl & Neuman [Page 66]
+
+RFC 1510 Kerberos September 1993
+
+
+ section 5.3.1.
+
+ e-text This field contains additional text to help explain the
+ error code associated with the failed request (for example,
+ it might include a principal name which was unknown).
+
+ e-data This field contains additional data about the error for use
+ by the application to help it recover from or handle the
+ error. If the errorcode is KDC_ERR_PREAUTH_REQUIRED, then
+ the e-data field will contain an encoding of a sequence of
+ padata fields, each corresponding to an acceptable pre-
+ authentication method and optionally containing data for
+ the method:
+
+ METHOD-DATA ::= SEQUENCE of PA-DATA
+
+ If the error-code is KRB_AP_ERR_METHOD, then the e-data field will
+ contain an encoding of the following sequence:
+
+ METHOD-DATA ::= SEQUENCE {
+ method-type[0] INTEGER,
+ method-data[1] OCTET STRING OPTIONAL
+ }
+
+ method-type will indicate the required alternate method; method-data
+ will contain any required additional information.
+
+6. Encryption and Checksum Specifications
+
+ The Kerberos protocols described in this document are designed to use
+ stream encryption ciphers, which can be simulated using commonly
+ available block encryption ciphers, such as the Data Encryption
+ Standard [11], in conjunction with block chaining and checksum
+ methods [12]. Encryption is used to prove the identities of the
+ network entities participating in message exchanges. The Key
+ Distribution Center for each realm is trusted by all principals
+ registered in that realm to store a secret key in confidence. Proof
+ of knowledge of this secret key is used to verify the authenticity of
+ a principal.
+
+ The KDC uses the principal's secret key (in the AS exchange) or a
+ shared session key (in the TGS exchange) to encrypt responses to
+ ticket requests; the ability to obtain the secret key or session key
+ implies the knowledge of the appropriate keys and the identity of the
+ KDC. The ability of a principal to decrypt the KDC response and
+ present a Ticket and a properly formed Authenticator (generated with
+ the session key from the KDC response) to a service verifies the
+ identity of the principal; likewise the ability of the service to
+
+
+
+Kohl & Neuman [Page 67]
+
+RFC 1510 Kerberos September 1993
+
+
+ extract the session key from the Ticket and prove its knowledge
+ thereof in a response verifies the identity of the service.
+
+ The Kerberos protocols generally assume that the encryption used is
+ secure from cryptanalysis; however, in some cases, the order of
+ fields in the encrypted portions of messages are arranged to minimize
+ the effects of poorly chosen keys. It is still important to choose
+ good keys. If keys are derived from user-typed passwords, those
+ passwords need to be well chosen to make brute force attacks more
+ difficult. Poorly chosen keys still make easy targets for intruders.
+
+ The following sections specify the encryption and checksum mechanisms
+ currently defined for Kerberos. The encodings, chaining, and padding
+ requirements for each are described. For encryption methods, it is
+ often desirable to place random information (often referred to as a
+ confounder) at the start of the message. The requirements for a
+ confounder are specified with each encryption mechanism.
+
+ Some encryption systems use a block-chaining method to improve the
+ the security characteristics of the ciphertext. However, these
+ chaining methods often don't provide an integrity check upon
+ decryption. Such systems (such as DES in CBC mode) must be augmented
+ with a checksum of the plaintext which can be verified at decryption
+ and used to detect any tampering or damage. Such checksums should be
+ good at detecting burst errors in the input. If any damage is
+ detected, the decryption routine is expected to return an error
+ indicating the failure of an integrity check. Each encryption type is
+ expected to provide and verify an appropriate checksum. The
+ specification of each encryption method sets out its checksum
+ requirements.
+
+ Finally, where a key is to be derived from a user's password, an
+ algorithm for converting the password to a key of the appropriate
+ type is included. It is desirable for the string to key function to
+ be one-way, and for the mapping to be different in different realms.
+ This is important because users who are registered in more than one
+ realm will often use the same password in each, and it is desirable
+ that an attacker compromising the Kerberos server in one realm not
+ obtain or derive the user's key in another.
+
+ For a discussion of the integrity characteristics of the candidate
+ encryption and checksum methods considered for Kerberos, the the
+ reader is referred to [13].
+
+6.1. Encryption Specifications
+
+ The following ASN.1 definition describes all encrypted messages. The
+ enc-part field which appears in the unencrypted part of messages in
+
+
+
+Kohl & Neuman [Page 68]
+
+RFC 1510 Kerberos September 1993
+
+
+ section 5 is a sequence consisting of an encryption type, an optional
+ key version number, and the ciphertext.
+
+ EncryptedData ::= SEQUENCE {
+ etype[0] INTEGER, -- EncryptionType
+ kvno[1] INTEGER OPTIONAL,
+ cipher[2] OCTET STRING -- ciphertext
+ }
+
+ etype This field identifies which encryption algorithm was used
+ to encipher the cipher. Detailed specifications for
+ selected encryption types appear later in this section.
+
+ kvno This field contains the version number of the key under
+ which data is encrypted. It is only present in messages
+ encrypted under long lasting keys, such as principals'
+ secret keys.
+
+ cipher This field contains the enciphered text, encoded as an
+ OCTET STRING.
+
+ The cipher field is generated by applying the specified encryption
+ algorithm to data composed of the message and algorithm-specific
+ inputs. Encryption mechanisms defined for use with Kerberos must
+ take sufficient measures to guarantee the integrity of the plaintext,
+ and we recommend they also take measures to protect against
+ precomputed dictionary attacks. If the encryption algorithm is not
+ itself capable of doing so, the protections can often be enhanced by
+ adding a checksum and a confounder.
+
+ The suggested format for the data to be encrypted includes a
+ confounder, a checksum, the encoded plaintext, and any necessary
+ padding. The msg-seq field contains the part of the protocol message
+ described in section 5 which is to be encrypted. The confounder,
+ checksum, and padding are all untagged and untyped, and their length
+ is exactly sufficient to hold the appropriate item. The type and
+ length is implicit and specified by the particular encryption type
+ being used (etype). The format for the data to be encrypted is
+ described in the following diagram:
+
+ +-----------+----------+-------------+-----+
+ |confounder | check | msg-seq | pad |
+ +-----------+----------+-------------+-----+
+
+ The format cannot be described in ASN.1, but for those who prefer an
+ ASN.1-like notation:
+
+
+
+
+
+Kohl & Neuman [Page 69]
+
+RFC 1510 Kerberos September 1993
+
+
+CipherText ::= ENCRYPTED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(conf_length) OPTIONAL,
+ check[1] UNTAGGED OCTET STRING(checksum_length) OPTIONAL,
+ msg-seq[2] MsgSequence,
+ pad UNTAGGED OCTET STRING(pad_length) OPTIONAL
+}
+
+ In the above specification, UNTAGGED OCTET STRING(length) is the
+ notation for an octet string with its tag and length removed. It is
+ not a valid ASN.1 type. The tag bits and length must be removed from
+ the confounder since the purpose of the confounder is so that the
+ message starts with random data, but the tag and its length are
+ fixed. For other fields, the length and tag would be redundant if
+ they were included because they are specified by the encryption type.
+
+ One generates a random confounder of the appropriate length, placing
+ it in confounder; zeroes out check; calculates the appropriate
+ checksum over confounder, check, and msg-seq, placing the result in
+ check; adds the necessary padding; then encrypts using the specified
+ encryption type and the appropriate key.
+
+ Unless otherwise specified, a definition of an encryption algorithm
+ that specifies a checksum, a length for the confounder field, or an
+ octet boundary for padding uses this ciphertext format (The ordering
+ of the fields in the CipherText is important. Additionally, messages
+ encoded in this format must include a length as part of the msg-seq
+ field. This allows the recipient to verify that the message has not
+ been truncated. Without a length, an attacker could use a chosen
+ plaintext attack to generate a message which could be truncated,
+ while leaving the checksum intact. Note that if the msg-seq is an
+ encoding of an ASN.1 SEQUENCE or OCTET STRING, then the length is
+ part of that encoding.). Those fields which are not specified will be
+ omitted.
+
+ In the interest of allowing all implementations using a particular
+ encryption type to communicate with all others using that type, the
+ specification of an encryption type defines any checksum that is
+ needed as part of the encryption process. If an alternative checksum
+ is to be used, a new encryption type must be defined.
+
+ Some cryptosystems require additional information beyond the key and
+ the data to be encrypted. For example, DES, when used in cipher-
+ block-chaining mode, requires an initialization vector. If required,
+ the description for each encryption type must specify the source of
+ such additional information.
+
+
+
+
+
+
+Kohl & Neuman [Page 70]
+
+RFC 1510 Kerberos September 1993
+
+
+6.2. Encryption Keys
+
+ The sequence below shows the encoding of an encryption key:
+
+ EncryptionKey ::= SEQUENCE {
+ keytype[0] INTEGER,
+ keyvalue[1] OCTET STRING
+ }
+
+ keytype This field specifies the type of encryption key that
+ follows in the keyvalue field. It will almost always
+ correspond to the encryption algorithm used to generate the
+ EncryptedData, though more than one algorithm may use the
+ same type of key (the mapping is many to one). This might
+ happen, for example, if the encryption algorithm uses an
+ alternate checksum algorithm for an integrity check, or a
+ different chaining mechanism.
+
+ keyvalue This field contains the key itself, encoded as an octet
+ string.
+
+ All negative values for the encryption key type are reserved for
+ local use. All non-negative values are reserved for officially
+ assigned type fields and interpretations.
+
+6.3. Encryption Systems
+
+6.3.1. The NULL Encryption System (null)
+
+ If no encryption is in use, the encryption system is said to be the
+ NULL encryption system. In the NULL encryption system there is no
+ checksum, confounder or padding. The ciphertext is simply the
+ plaintext. The NULL Key is used by the null encryption system and is
+ zero octets in length, with keytype zero (0).
+
+6.3.2. DES in CBC mode with a CRC-32 checksum (des-cbc-crc)
+
+ The des-cbc-crc encryption mode encrypts information under the Data
+ Encryption Standard [11] using the cipher block chaining mode [12].
+ A CRC-32 checksum (described in ISO 3309 [14]) is applied to the
+ confounder and message sequence (msg-seq) and placed in the cksum
+ field. DES blocks are 8 bytes. As a result, the data to be
+ encrypted (the concatenation of confounder, checksum, and message)
+ must be padded to an 8 byte boundary before encryption. The details
+ of the encryption of this data are identical to those for the des-
+ cbc-md5 encryption mode.
+
+ Note that, since the CRC-32 checksum is not collisionproof, an
+
+
+
+Kohl & Neuman [Page 71]
+
+RFC 1510 Kerberos September 1993
+
+
+ attacker could use a probabilistic chosenplaintext attack to generate
+ a valid message even if a confounder is used [13]. The use of
+ collision-proof checksums is recommended for environments where such
+ attacks represent a significant threat. The use of the CRC-32 as the
+ checksum for ticket or authenticator is no longer mandated as an
+ interoperability requirement for Kerberos Version 5 Specification 1
+ (See section 9.1 for specific details).
+
+6.3.3. DES in CBC mode with an MD4 checksum (des-cbc-md4)
+
+ The des-cbc-md4 encryption mode encrypts information under the Data
+ Encryption Standard [11] using the cipher block chaining mode [12].
+ An MD4 checksum (described in [15]) is applied to the confounder and
+ message sequence (msg-seq) and placed in the cksum field. DES blocks
+ are 8 bytes. As a result, the data to be encrypted (the
+ concatenation of confounder, checksum, and message) must be padded to
+ an 8 byte boundary before encryption. The details of the encryption
+ of this data are identical to those for the descbc-md5 encryption
+ mode.
+
+6.3.4. DES in CBC mode with an MD5 checksum (des-cbc-md5)
+
+ The des-cbc-md5 encryption mode encrypts information under the Data
+ Encryption Standard [11] using the cipher block chaining mode [12].
+ An MD5 checksum (described in [16]) is applied to the confounder and
+ message sequence (msg-seq) and placed in the cksum field. DES blocks
+ are 8 bytes. As a result, the data to be encrypted (the
+ concatenation of confounder, checksum, and message) must be padded to
+ an 8 byte boundary before encryption.
+
+ Plaintext and DES ciphtertext are encoded as 8-octet blocks which are
+ concatenated to make the 64-bit inputs for the DES algorithms. The
+ first octet supplies the 8 most significant bits (with the octet's
+ MSbit used as the DES input block's MSbit, etc.), the second octet
+ the next 8 bits, ..., and the eighth octet supplies the 8 least
+ significant bits.
+
+ Encryption under DES using cipher block chaining requires an
+ additional input in the form of an initialization vector. Unless
+ otherwise specified, zero should be used as the initialization
+ vector. Kerberos' use of DES requires an 8-octet confounder.
+
+ The DES specifications identify some "weak" and "semiweak" keys;
+ those keys shall not be used for encrypting messages for use in
+ Kerberos. Additionally, because of the way that keys are derived for
+ the encryption of checksums, keys shall not be used that yield "weak"
+ or "semi-weak" keys when eXclusive-ORed with the constant
+ F0F0F0F0F0F0F0F0.
+
+
+
+Kohl & Neuman [Page 72]
+
+RFC 1510 Kerberos September 1993
+
+
+ A DES key is 8 octets of data, with keytype one (1). This consists
+ of 56 bits of key, and 8 parity bits (one per octet). The key is
+ encoded as a series of 8 octets written in MSB-first order. The bits
+ within the key are also encoded in MSB order. For example, if the
+ encryption key is:
+ (B1,B2,...,B7,P1,B8,...,B14,P2,B15,...,B49,P7,B50,...,B56,P8) where
+ B1,B2,...,B56 are the key bits in MSB order, and P1,P2,...,P8 are the
+ parity bits, the first octet of the key would be B1,B2,...,B7,P1
+ (with B1 as the MSbit). [See the FIPS 81 introduction for
+ reference.]
+
+ To generate a DES key from a text string (password), the text string
+ normally must have the realm and each component of the principal's
+ name appended(In some cases, it may be necessary to use a different
+ "mix-in" string for compatibility reasons; see the discussion of
+ padata in section 5.4.2.), then padded with ASCII nulls to an 8 byte
+ boundary. This string is then fan-folded and eXclusive-ORed with
+ itself to form an 8 byte DES key. The parity is corrected on the
+ key, and it is used to generate a DES CBC checksum on the initial
+ string (with the realm and name appended). Next, parity is corrected
+ on the CBC checksum. If the result matches a "weak" or "semiweak"
+ key as described in the DES specification, it is eXclusive-ORed with
+ the constant 00000000000000F0. Finally, the result is returned as
+ the key. Pseudocode follows:
+
+ string_to_key(string,realm,name) {
+ odd = 1;
+ s = string + realm;
+ for(each component in name) {
+ s = s + component;
+ }
+ tempkey = NULL;
+ pad(s); /* with nulls to 8 byte boundary */
+ for(8byteblock in s) {
+ if(odd == 0) {
+ odd = 1;
+ reverse(8byteblock)
+ }
+ else odd = 0;
+ tempkey = tempkey XOR 8byteblock;
+ }
+ fixparity(tempkey);
+ key = DES-CBC-check(s,tempkey);
+ fixparity(key);
+ if(is_weak_key_key(key))
+ key = key XOR 0xF0;
+ return(key);
+ }
+
+
+
+Kohl & Neuman [Page 73]
+
+RFC 1510 Kerberos September 1993
+
+
+6.4. Checksums
+
+ The following is the ASN.1 definition used for a checksum:
+
+ Checksum ::= SEQUENCE {
+ cksumtype[0] INTEGER,
+ checksum[1] OCTET STRING
+ }
+
+ cksumtype This field indicates the algorithm used to generate the
+ accompanying checksum.
+
+ checksum This field contains the checksum itself, encoded
+ as an octet string.
+
+ Detailed specification of selected checksum types appear later in
+ this section. Negative values for the checksum type are reserved for
+ local use. All non-negative values are reserved for officially
+ assigned type fields and interpretations.
+
+ Checksums used by Kerberos can be classified by two properties:
+ whether they are collision-proof, and whether they are keyed. It is
+ infeasible to find two plaintexts which generate the same checksum
+ value for a collision-proof checksum. A key is required to perturb
+ or initialize the algorithm in a keyed checksum. To prevent
+ message-stream modification by an active attacker, unkeyed checksums
+ should only be used when the checksum and message will be
+ subsequently encrypted (e.g., the checksums defined as part of the
+ encryption algorithms covered earlier in this section). Collision-
+ proof checksums can be made tamper-proof as well if the checksum
+ value is encrypted before inclusion in a message. In such cases, the
+ composition of the checksum and the encryption algorithm must be
+ considered a separate checksum algorithm (e.g., RSA-MD5 encrypted
+ using DES is a new checksum algorithm of type RSA-MD5-DES). For most
+ keyed checksums, as well as for the encrypted forms of collisionproof
+ checksums, Kerberos prepends a confounder before the checksum is
+ calculated.
+
+6.4.1. The CRC-32 Checksum (crc32)
+
+ The CRC-32 checksum calculates a checksum based on a cyclic
+ redundancy check as described in ISO 3309 [14]. The resulting
+ checksum is four (4) octets in length. The CRC-32 is neither keyed
+ nor collision-proof. The use of this checksum is not recommended.
+ An attacker using a probabilistic chosen-plaintext attack as
+ described in [13] might be able to generate an alternative message
+ that satisfies the checksum. The use of collision-proof checksums is
+ recommended for environments where such attacks represent a
+
+
+
+Kohl & Neuman [Page 74]
+
+RFC 1510 Kerberos September 1993
+
+
+ significant threat.
+
+6.4.2. The RSA MD4 Checksum (rsa-md4)
+
+ The RSA-MD4 checksum calculates a checksum using the RSA MD4
+ algorithm [15]. The algorithm takes as input an input message of
+ arbitrary length and produces as output a 128-bit (16 octet)
+ checksum. RSA-MD4 is believed to be collision-proof.
+
+6.4.3. RSA MD4 Cryptographic Checksum Using DES (rsa-md4des)
+
+ The RSA-MD4-DES checksum calculates a keyed collisionproof checksum
+ by prepending an 8 octet confounder before the text, applying the RSA
+ MD4 checksum algorithm, and encrypting the confounder and the
+ checksum using DES in cipher-block-chaining (CBC) mode using a
+ variant of the key, where the variant is computed by eXclusive-ORing
+ the key with the constant F0F0F0F0F0F0F0F0 (A variant of the key is
+ used to limit the use of a key to a particular function, separating
+ the functions of generating a checksum from other encryption
+ performed using the session key. The constant F0F0F0F0F0F0F0F0 was
+ chosen because it maintains key parity. The properties of DES
+ precluded the use of the complement. The same constant is used for
+ similar purpose in the Message Integrity Check in the Privacy
+ Enhanced Mail standard.). The initialization vector should be zero.
+ The resulting checksum is 24 octets long (8 octets of which are
+ redundant). This checksum is tamper-proof and believed to be
+ collision-proof.
+
+ The DES specifications identify some "weak keys"; those keys shall
+ not be used for generating RSA-MD4 checksums for use in Kerberos.
+
+ The format for the checksum is described in the following diagram:
+
+ +--+--+--+--+--+--+--+--
+ | des-cbc(confounder
+ +--+--+--+--+--+--+--+--
+
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ rsa-md4(confounder+msg),key=var(key),iv=0) |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+ The format cannot be described in ASN.1, but for those who prefer an
+ ASN.1-like notation:
+
+ rsa-md4-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(16)
+ }
+
+
+
+Kohl & Neuman [Page 75]
+
+RFC 1510 Kerberos September 1993
+
+
+6.4.4. The RSA MD5 Checksum (rsa-md5)
+
+ The RSA-MD5 checksum calculates a checksum using the RSA MD5
+ algorithm [16]. The algorithm takes as input an input message of
+ arbitrary length and produces as output a 128-bit (16 octet)
+ checksum. RSA-MD5 is believed to be collision-proof.
+
+6.4.5. RSA MD5 Cryptographic Checksum Using DES (rsa-md5des)
+
+ The RSA-MD5-DES checksum calculates a keyed collisionproof checksum
+ by prepending an 8 octet confounder before the text, applying the RSA
+ MD5 checksum algorithm, and encrypting the confounder and the
+ checksum using DES in cipher-block-chaining (CBC) mode using a
+ variant of the key, where the variant is computed by eXclusive-ORing
+ the key with the constant F0F0F0F0F0F0F0F0. The initialization
+ vector should be zero. The resulting checksum is 24 octets long (8
+ octets of which are redundant). This checksum is tamper-proof and
+ believed to be collision-proof.
+
+ The DES specifications identify some "weak keys"; those keys shall
+ not be used for encrypting RSA-MD5 checksums for use in Kerberos.
+
+ The format for the checksum is described in the following diagram:
+
+ +--+--+--+--+--+--+--+--
+ | des-cbc(confounder
+ +--+--+--+--+--+--+--+--
+
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ rsa-md5(confounder+msg),key=var(key),iv=0) |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+ The format cannot be described in ASN.1, but for those who prefer an
+ ASN.1-like notation:
+
+ rsa-md5-des-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(16)
+ }
+
+6.4.6. DES cipher-block chained checksum (des-mac)
+
+ The DES-MAC checksum is computed by prepending an 8 octet confounder
+ to the plaintext, performing a DES CBC-mode encryption on the result
+ using the key and an initialization vector of zero, taking the last
+ block of the ciphertext, prepending the same confounder and
+ encrypting the pair using DES in cipher-block-chaining (CBC) mode
+ using a a variant of the key, where the variant is computed by
+
+
+
+Kohl & Neuman [Page 76]
+
+RFC 1510 Kerberos September 1993
+
+
+ eXclusive-ORing the key with the constant F0F0F0F0F0F0F0F0. The
+ initialization vector should be zero. The resulting checksum is 128
+ bits (16 octets) long, 64 bits of which are redundant. This checksum
+ is tamper-proof and collision-proof.
+
+ The format for the checksum is described in the following diagram:
+
+ +--+--+--+--+--+--+--+--
+ | des-cbc(confounder
+ +--+--+--+--+--+--+--+--
+
+ +-----+-----+-----+-----+-----+-----+-----+-----+
+ des-mac(conf+msg,iv=0,key),key=var(key),iv=0) |
+ +-----+-----+-----+-----+-----+-----+-----+-----+
+
+ The format cannot be described in ASN.1, but for those who prefer an
+ ASN.1-like notation:
+
+ des-mac-checksum ::= ENCRYPTED UNTAGGED SEQUENCE {
+ confounder[0] UNTAGGED OCTET STRING(8),
+ check[1] UNTAGGED OCTET STRING(8)
+ }
+
+ The DES specifications identify some "weak" and "semiweak" keys;
+ those keys shall not be used for generating DES-MAC checksums for use
+ in Kerberos, nor shall a key be used whose veriant is "weak" or
+ "semi-weak".
+
+6.4.7. RSA MD4 Cryptographic Checksum Using DES alternative
+ (rsa-md4-des-k)
+
+ The RSA-MD4-DES-K checksum calculates a keyed collision-proof
+ checksum by applying the RSA MD4 checksum algorithm and encrypting
+ the results using DES in cipherblock-chaining (CBC) mode using a DES
+ key as both key and initialization vector. The resulting checksum is
+ 16 octets long. This checksum is tamper-proof and believed to be
+ collision-proof. Note that this checksum type is the old method for
+ encoding the RSA-MD4-DES checksum and it is no longer recommended.
+
+6.4.8. DES cipher-block chained checksum alternative (desmac-k)
+
+ The DES-MAC-K checksum is computed by performing a DES CBC-mode
+ encryption of the plaintext, and using the last block of the
+ ciphertext as the checksum value. It is keyed with an encryption key
+ and an initialization vector; any uses which do not specify an
+ additional initialization vector will use the key as both key and
+ initialization vector. The resulting checksum is 64 bits (8 octets)
+ long. This checksum is tamper-proof and collision-proof. Note that
+
+
+
+Kohl & Neuman [Page 77]
+
+RFC 1510 Kerberos September 1993
+
+
+ this checksum type is the old method for encoding the DESMAC checksum
+ and it is no longer recommended.
+
+ The DES specifications identify some "weak keys"; those keys shall
+ not be used for generating DES-MAC checksums for use in Kerberos.
+
+7. Naming Constraints
+
+7.1. Realm Names
+
+ Although realm names are encoded as GeneralStrings and although a
+ realm can technically select any name it chooses, interoperability
+ across realm boundaries requires agreement on how realm names are to
+ be assigned, and what information they imply.
+
+ To enforce these conventions, each realm must conform to the
+ conventions itself, and it must require that any realms with which
+ inter-realm keys are shared also conform to the conventions and
+ require the same from its neighbors.
+
+ There are presently four styles of realm names: domain, X500, other,
+ and reserved. Examples of each style follow:
+
+ domain: host.subdomain.domain (example)
+ X500: C=US/O=OSF (example)
+ other: NAMETYPE:rest/of.name=without-restrictions (example)
+ reserved: reserved, but will not conflict with above
+
+ Domain names must look like domain names: they consist of components
+ separated by periods (.) and they contain neither colons (:) nor
+ slashes (/).
+
+ X.500 names contain an equal (=) and cannot contain a colon (:)
+ before the equal. The realm names for X.500 names will be string
+ representations of the names with components separated by slashes.
+ Leading and trailing slashes will not be included.
+
+ Names that fall into the other category must begin with a prefix that
+ contains no equal (=) or period (.) and the prefix must be followed
+ by a colon (:) and the rest of the name. All prefixes must be
+ assigned before they may be used. Presently none are assigned.
+
+ The reserved category includes strings which do not fall into the
+ first three categories. All names in this category are reserved. It
+ is unlikely that names will be assigned to this category unless there
+ is a very strong argument for not using the "other" category.
+
+ These rules guarantee that there will be no conflicts between the
+
+
+
+Kohl & Neuman [Page 78]
+
+RFC 1510 Kerberos September 1993
+
+
+ various name styles. The following additional constraints apply to
+ the assignment of realm names in the domain and X.500 categories: the
+ name of a realm for the domain or X.500 formats must either be used
+ by the organization owning (to whom it was assigned) an Internet
+ domain name or X.500 name, or in the case that no such names are
+ registered, authority to use a realm name may be derived from the
+ authority of the parent realm. For example, if there is no domain
+ name for E40.MIT.EDU, then the administrator of the MIT.EDU realm can
+ authorize the creation of a realm with that name.
+
+ This is acceptable because the organization to which the parent is
+ assigned is presumably the organization authorized to assign names to
+ its children in the X.500 and domain name systems as well. If the
+ parent assigns a realm name without also registering it in the domain
+ name or X.500 hierarchy, it is the parent's responsibility to make
+ sure that there will not in the future exists a name identical to the
+ realm name of the child unless it is assigned to the same entity as
+ the realm name.
+
+7.2. Principal Names
+
+ As was the case for realm names, conventions are needed to ensure
+ that all agree on what information is implied by a principal name.
+ The name-type field that is part of the principal name indicates the
+ kind of information implied by the name. The name-type should be
+ treated as a hint. Ignoring the name type, no two names can be the
+ same (i.e., at least one of the components, or the realm, must be
+ different). This constraint may be eliminated in the future. The
+ following name types are defined:
+
+ name-type value meaning
+ NT-UNKNOWN 0 Name type not known
+ NT-PRINCIPAL 1 Just the name of the principal as in
+ DCE, or for users
+ NT-SRV-INST 2 Service and other unique instance (krbtgt)
+ NT-SRV-HST 3 Service with host name as instance
+ (telnet, rcommands)
+ NT-SRV-XHST 4 Service with host as remaining components
+ NT-UID 5 Unique ID
+
+ When a name implies no information other than its uniqueness at a
+ particular time the name type PRINCIPAL should be used. The
+ principal name type should be used for users, and it might also be
+ used for a unique server. If the name is a unique machine generated
+ ID that is guaranteed never to be reassigned then the name type of
+ UID should be used (note that it is generally a bad idea to reassign
+ names of any type since stale entries might remain in access control
+ lists).
+
+
+
+Kohl & Neuman [Page 79]
+
+RFC 1510 Kerberos September 1993
+
+
+ If the first component of a name identifies a service and the
+ remaining components identify an instance of the service in a server
+ specified manner, then the name type of SRV-INST should be used. An
+ example of this name type is the Kerberos ticket-granting ticket
+ which has a first component of krbtgt and a second component
+ identifying the realm for which the ticket is valid.
+
+ If instance is a single component following the service name and the
+ instance identifies the host on which the server is running, then the
+ name type SRV-HST should be used. This type is typically used for
+ Internet services such as telnet and the Berkeley R commands. If the
+ separate components of the host name appear as successive components
+ following the name of the service, then the name type SRVXHST should
+ be used. This type might be used to identify servers on hosts with
+ X.500 names where the slash (/) might otherwise be ambiguous.
+
+ A name type of UNKNOWN should be used when the form of the name is
+ not known. When comparing names, a name of type UNKNOWN will match
+ principals authenticated with names of any type. A principal
+ authenticated with a name of type UNKNOWN, however, will only match
+ other names of type UNKNOWN.
+
+ Names of any type with an initial component of "krbtgt" are reserved
+ for the Kerberos ticket granting service. See section 8.2.3 for the
+ form of such names.
+
+7.2.1. Name of server principals
+
+ The principal identifier for a server on a host will generally be
+ composed of two parts: (1) the realm of the KDC with which the server
+ is registered, and (2) a two-component name of type NT-SRV-HST if the
+ host name is an Internet domain name or a multi-component name of
+ type NT-SRV-XHST if the name of the host is of a form such as X.500
+ that allows slash (/) separators. The first component of the two- or
+ multi-component name will identify the service and the latter
+ components will identify the host. Where the name of the host is not
+ case sensitive (for example, with Internet domain names) the name of
+ the host must be lower case. For services such as telnet and the
+ Berkeley R commands which run with system privileges, the first
+ component will be the string "host" instead of a service specific
+ identifier.
+
+8. Constants and other defined values
+
+8.1. Host address types
+
+ All negative values for the host address type are reserved for local
+ use. All non-negative values are reserved for officially assigned
+
+
+
+Kohl & Neuman [Page 80]
+
+RFC 1510 Kerberos September 1993
+
+
+ type fields and interpretations.
+
+ The values of the types for the following addresses are chosen to
+ match the defined address family constants in the Berkeley Standard
+ Distributions of Unix. They can be found in <sys/socket.h> with
+ symbolic names AF_xxx (where xxx is an abbreviation of the address
+ family name).
+
+
+ Internet addresses
+
+ Internet addresses are 32-bit (4-octet) quantities, encoded in MSB
+ order. The type of internet addresses is two (2).
+
+ CHAOSnet addresses
+
+ CHAOSnet addresses are 16-bit (2-octet) quantities, encoded in MSB
+ order. The type of CHAOSnet addresses is five (5).
+
+ ISO addresses
+
+ ISO addresses are variable-length. The type of ISO addresses is
+ seven (7).
+
+ Xerox Network Services (XNS) addresses
+
+ XNS addresses are 48-bit (6-octet) quantities, encoded in MSB
+ order. The type of XNS addresses is six (6).
+
+ AppleTalk Datagram Delivery Protocol (DDP) addresses
+
+ AppleTalk DDP addresses consist of an 8-bit node number and a 16-
+ bit network number. The first octet of the address is the node
+ number; the remaining two octets encode the network number in MSB
+ order. The type of AppleTalk DDP addresses is sixteen (16).
+
+ DECnet Phase IV addresses
+
+ DECnet Phase IV addresses are 16-bit addresses, encoded in LSB
+ order. The type of DECnet Phase IV addresses is twelve (12).
+
+8.2. KDC messages
+
+8.2.1. IP transport
+
+ When contacting a Kerberos server (KDC) for a KRB_KDC_REQ request
+ using IP transport, the client shall send a UDP datagram containing
+ only an encoding of the request to port 88 (decimal) at the KDC's IP
+
+
+
+Kohl & Neuman [Page 81]
+
+RFC 1510 Kerberos September 1993
+
+
+ address; the KDC will respond with a reply datagram containing only
+ an encoding of the reply message (either a KRB_ERROR or a
+ KRB_KDC_REP) to the sending port at the sender's IP address.
+
+8.2.2. OSI transport
+
+ During authentication of an OSI client to and OSI server, the mutual
+ authentication of an OSI server to an OSI client, the transfer of
+ credentials from an OSI client to an OSI server, or during exchange
+ of private or integrity checked messages, Kerberos protocol messages
+ may be treated as opaque objects and the type of the authentication
+ mechanism will be:
+
+ OBJECT IDENTIFIER ::= {iso (1), org(3), dod(5),internet(1),
+ security(5), kerberosv5(2)}
+
+ Depending on the situation, the opaque object will be an
+ authentication header (KRB_AP_REQ), an authentication reply
+ (KRB_AP_REP), a safe message (KRB_SAFE), a private message
+ (KRB_PRIV), or a credentials message (KRB_CRED). The opaque data
+ contains an application code as specified in the ASN.1 description
+ for each message. The application code may be used by Kerberos to
+ determine the message type.
+
+8.2.3. Name of the TGS
+
+ The principal identifier of the ticket-granting service shall be
+ composed of three parts: (1) the realm of the KDC issuing the TGS
+ ticket (2) a two-part name of type NT-SRVINST, with the first part
+ "krbtgt" and the second part the name of the realm which will accept
+ the ticket-granting ticket. For example, a ticket-granting ticket
+ issued by the ATHENA.MIT.EDU realm to be used to get tickets from the
+ ATHENA.MIT.EDU KDC has a principal identifier of "ATHENA.MIT.EDU"
+ (realm), ("krbtgt", "ATHENA.MIT.EDU") (name). A ticket-granting
+ ticket issued by the ATHENA.MIT.EDU realm to be used to get tickets
+ from the MIT.EDU realm has a principal identifier of "ATHENA.MIT.EDU"
+ (realm), ("krbtgt", "MIT.EDU") (name).
+
+8.3. Protocol constants and associated values
+
+ The following tables list constants used in the protocol and defines
+ their meanings.
+
+
+
+
+
+
+
+
+
+Kohl & Neuman [Page 82]
+
+RFC 1510 Kerberos September 1993
+
+
+---------------+-----------+----------+----------------+---------------
+Encryption type|etype value|block size|minimum pad size|confounder size
+---------------+-----------+----------+----------------+---------------
+NULL 0 1 0 0
+des-cbc-crc 1 8 4 8
+des-cbc-md4 2 8 0 8
+des-cbc-md5 3 8 0 8
+
+-------------------------------+-------------------+-------------
+Checksum type |sumtype value |checksum size
+-------------------------------+-------------------+-------------
+CRC32 1 4
+rsa-md4 2 16
+rsa-md4-des 3 24
+des-mac 4 16
+des-mac-k 5 8
+rsa-md4-des-k 6 16
+rsa-md5 7 16
+rsa-md5-des 8 24
+
+-------------------------------+-----------------
+padata type |padata-type value
+-------------------------------+-----------------
+PA-TGS-REQ 1
+PA-ENC-TIMESTAMP 2
+PA-PW-SALT 3
+
+-------------------------------+-------------
+authorization data type |ad-type value
+-------------------------------+-------------
+reserved values 0-63
+OSF-DCE 64
+SESAME 65
+
+-------------------------------+-----------------
+alternate authentication type |method-type value
+-------------------------------+-----------------
+reserved values 0-63
+ATT-CHALLENGE-RESPONSE 64
+
+-------------------------------+-------------
+transited encoding type |tr-type value
+-------------------------------+-------------
+DOMAIN-X500-COMPRESS 1
+reserved values all others
+
+
+
+
+
+
+Kohl & Neuman [Page 83]
+
+RFC 1510 Kerberos September 1993
+
+
+--------------+-------+-----------------------------------------
+Label |Value |Meaning or MIT code
+--------------+-------+-----------------------------------------
+
+pvno 5 current Kerberos protocol version number
+
+message types
+
+KRB_AS_REQ 10 Request for initial authentication
+KRB_AS_REP 11 Response to KRB_AS_REQ request
+KRB_TGS_REQ 12 Request for authentication based on TGT
+KRB_TGS_REP 13 Response to KRB_TGS_REQ request
+KRB_AP_REQ 14 application request to server
+KRB_AP_REP 15 Response to KRB_AP_REQ_MUTUAL
+KRB_SAFE 20 Safe (checksummed) application message
+KRB_PRIV 21 Private (encrypted) application message
+KRB_CRED 22 Private (encrypted) message to forward
+ credentials
+KRB_ERROR 30 Error response
+
+name types
+
+KRB_NT_UNKNOWN 0 Name type not known
+KRB_NT_PRINCIPAL 1 Just the name of the principal as in DCE, or
+ for users
+KRB_NT_SRV_INST 2 Service and other unique instance (krbtgt)
+KRB_NT_SRV_HST 3 Service with host name as instance (telnet,
+ rcommands)
+KRB_NT_SRV_XHST 4 Service with host as remaining components
+KRB_NT_UID 5 Unique ID
+
+error codes
+
+KDC_ERR_NONE 0 No error
+KDC_ERR_NAME_EXP 1 Client's entry in database has
+ expired
+KDC_ERR_SERVICE_EXP 2 Server's entry in database has
+ expired
+KDC_ERR_BAD_PVNO 3 Requested protocol version number
+ not supported
+KDC_ERR_C_OLD_MAST_KVNO 4 Client's key encrypted in old
+ master key
+KDC_ERR_S_OLD_MAST_KVNO 5 Server's key encrypted in old
+ master key
+KDC_ERR_C_PRINCIPAL_UNKNOWN 6 Client not found in Kerberos database
+KDC_ERR_S_PRINCIPAL_UNKNOWN 7 Server not found in Kerberos database
+KDC_ERR_PRINCIPAL_NOT_UNIQUE 8 Multiple principal entries in
+ database
+
+
+
+Kohl & Neuman [Page 84]
+
+RFC 1510 Kerberos September 1993
+
+
+KDC_ERR_NULL_KEY 9 The client or server has a null key
+KDC_ERR_CANNOT_POSTDATE 10 Ticket not eligible for postdating
+KDC_ERR_NEVER_VALID 11 Requested start time is later than
+ end time
+KDC_ERR_POLICY 12 KDC policy rejects request
+KDC_ERR_BADOPTION 13 KDC cannot accommodate requested
+ option
+KDC_ERR_ETYPE_NOSUPP 14 KDC has no support for encryption
+ type
+KDC_ERR_SUMTYPE_NOSUPP 15 KDC has no support for checksum type
+KDC_ERR_PADATA_TYPE_NOSUPP 16 KDC has no support for padata type
+KDC_ERR_TRTYPE_NOSUPP 17 KDC has no support for transited type
+KDC_ERR_CLIENT_REVOKED 18 Clients credentials have been revoked
+KDC_ERR_SERVICE_REVOKED 19 Credentials for server have been
+ revoked
+KDC_ERR_TGT_REVOKED 20 TGT has been revoked
+KDC_ERR_CLIENT_NOTYET 21 Client not yet valid - try again
+ later
+KDC_ERR_SERVICE_NOTYET 22 Server not yet valid - try again
+ later
+KDC_ERR_KEY_EXPIRED 23 Password has expired - change
+ password to reset
+KDC_ERR_PREAUTH_FAILED 24 Pre-authentication information
+ was invalid
+KDC_ERR_PREAUTH_REQUIRED 25 Additional pre-authentication
+ required*
+KRB_AP_ERR_BAD_INTEGRITY 31 Integrity check on decrypted field
+ failed
+KRB_AP_ERR_TKT_EXPIRED 32 Ticket expired
+KRB_AP_ERR_TKT_NYV 33 Ticket not yet valid
+KRB_AP_ERR_REPEAT 34 Request is a replay
+KRB_AP_ERR_NOT_US 35 The ticket isn't for us
+KRB_AP_ERR_BADMATCH 36 Ticket and authenticator don't match
+KRB_AP_ERR_SKEW 37 Clock skew too great
+KRB_AP_ERR_BADADDR 38 Incorrect net address
+KRB_AP_ERR_BADVERSION 39 Protocol version mismatch
+KRB_AP_ERR_MSG_TYPE 40 Invalid msg type
+KRB_AP_ERR_MODIFIED 41 Message stream modified
+KRB_AP_ERR_BADORDER 42 Message out of order
+KRB_AP_ERR_BADKEYVER 44 Specified version of key is not
+ available
+KRB_AP_ERR_NOKEY 45 Service key not available
+KRB_AP_ERR_MUT_FAIL 46 Mutual authentication failed
+KRB_AP_ERR_BADDIRECTION 47 Incorrect message direction
+KRB_AP_ERR_METHOD 48 Alternative authentication method
+ required*
+KRB_AP_ERR_BADSEQ 49 Incorrect sequence number in message
+KRB_AP_ERR_INAPP_CKSUM 50 Inappropriate type of checksum in
+
+
+
+Kohl & Neuman [Page 85]
+
+RFC 1510 Kerberos September 1993
+
+
+ message
+KRB_ERR_GENERIC 60 Generic error (description in e-text)
+KRB_ERR_FIELD_TOOLONG 61 Field is too long for this
+ implementation
+
+ *This error carries additional information in the e-data field. The
+ contents of the e-data field for this message is described in section
+ 5.9.1.
+
+9. Interoperability requirements
+
+ Version 5 of the Kerberos protocol supports a myriad of options.
+ Among these are multiple encryption and checksum types, alternative
+ encoding schemes for the transited field, optional mechanisms for
+ pre-authentication, the handling of tickets with no addresses,
+ options for mutual authentication, user to user authentication,
+ support for proxies, forwarding, postdating, and renewing tickets,
+ the format of realm names, and the handling of authorization data.
+
+ In order to ensure the interoperability of realms, it is necessary to
+ define a minimal configuration which must be supported by all
+ implementations. This minimal configuration is subject to change as
+ technology does. For example, if at some later date it is discovered
+ that one of the required encryption or checksum algorithms is not
+ secure, it will be replaced.
+
+9.1. Specification 1
+
+ This section defines the first specification of these options.
+ Implementations which are configured in this way can be said to
+ support Kerberos Version 5 Specification 1 (5.1).
+
+ Encryption and checksum methods
+
+ The following encryption and checksum mechanisms must be supported.
+ Implementations may support other mechanisms as well, but the
+ additional mechanisms may only be used when communicating with
+ principals known to also support them: Encryption: DES-CBC-MD5
+ Checksums: CRC-32, DES-MAC, DES-MAC-K, and DES-MD5
+
+ Realm Names
+
+ All implementations must understand hierarchical realms in both the
+ Internet Domain and the X.500 style. When a ticket granting ticket
+ for an unknown realm is requested, the KDC must be able to determine
+ the names of the intermediate realms between the KDCs realm and the
+ requested realm.
+
+
+
+
+Kohl & Neuman [Page 86]
+
+RFC 1510 Kerberos September 1993
+
+
+ Transited field encoding
+
+ DOMAIN-X500-COMPRESS (described in section 3.3.3.1) must be
+ supported. Alternative encodings may be supported, but they may be
+ used only when that encoding is supported by ALL intermediate realms.
+
+ Pre-authentication methods
+
+ The TGS-REQ method must be supported. The TGS-REQ method is not used
+ on the initial request. The PA-ENC-TIMESTAMP method must be supported
+ by clients but whether it is enabled by default may be determined on
+ a realm by realm basis. If not used in the initial request and the
+ error KDC_ERR_PREAUTH_REQUIRED is returned specifying PA-ENCTIMESTAMP
+ as an acceptable method, the client should retry the initial request
+ using the PA-ENC-TIMESTAMP preauthentication method. Servers need not
+ support the PAENC-TIMESTAMP method, but if not supported the server
+ should ignore the presence of PA-ENC-TIMESTAMP pre-authentication in
+ a request.
+
+ Mutual authentication
+
+ Mutual authentication (via the KRB_AP_REP message) must be supported.
+
+ Ticket addresses and flags
+
+ All KDC's must pass on tickets that carry no addresses (i.e., if a
+ TGT contains no addresses, the KDC will return derivative tickets),
+ but each realm may set its own policy for issuing such tickets, and
+ each application server will set its own policy with respect to
+ accepting them. By default, servers should not accept them.
+
+ Proxies and forwarded tickets must be supported. Individual realms
+ and application servers can set their own policy on when such tickets
+ will be accepted.
+
+ All implementations must recognize renewable and postdated tickets,
+ but need not actually implement them. If these options are not
+ supported, the starttime and endtime in the ticket shall specify a
+ ticket's entire useful life. When a postdated ticket is decoded by a
+ server, all implementations shall make the presence of the postdated
+ flag visible to the calling server.
+
+ User-to-user authentication
+
+ Support for user to user authentication (via the ENC-TKTIN-SKEY KDC
+ option) must be provided by implementations, but individual realms
+ may decide as a matter of policy to reject such requests on a per-
+ principal or realm-wide basis.
+
+
+
+Kohl & Neuman [Page 87]
+
+RFC 1510 Kerberos September 1993
+
+
+ Authorization data
+
+ Implementations must pass all authorization data subfields from
+ ticket-granting tickets to any derivative tickets unless directed to
+ suppress a subfield as part of the definition of that registered
+ subfield type (it is never incorrect to pass on a subfield, and no
+ registered subfield types presently specify suppression at the KDC).
+
+ Implementations must make the contents of any authorization data
+ subfields available to the server when a ticket is used.
+ Implementations are not required to allow clients to specify the
+ contents of the authorization data fields.
+
+9.2. Recommended KDC values
+
+ Following is a list of recommended values for a KDC implementation,
+ based on the list of suggested configuration constants (see section
+ 4.4).
+
+ minimum lifetime 5 minutes
+
+ maximum renewable lifetime 1 week
+
+ maximum ticket lifetime 1 day
+
+ empty addresses only when suitable restrictions appear
+ in authorization data
+
+ proxiable, etc. Allowed.
+
+10. Acknowledgments
+
+ Early versions of this document, describing version 4 of the
+ protocol, were written by Jennifer Steiner (formerly at Project
+ Athena); these drafts provided an excellent starting point for this
+ current version 5 specification. Many people in the Internet
+ community have contributed ideas and suggested protocol changes for
+ version 5. Notable contributions came from Ted Anderson, Steve
+ Bellovin and Michael Merritt [17], Daniel Bernstein, Mike Burrows,
+ Donald Davis, Ravi Ganesan, Morrie Gasser, Virgil Gligor, Bill
+ Griffeth, Mark Lillibridge, Mark Lomas, Steve Lunt, Piers McMahon,
+ Joe Pato, William Sommerfeld, Stuart Stubblebine, Ralph Swick, Ted
+ T'so, and Stanley Zanarotti. Many others commented and helped shape
+ this specification into its current form.
+
+
+
+
+
+
+
+Kohl & Neuman [Page 88]
+
+RFC 1510 Kerberos September 1993
+
+
+11. References
+
+ [1] Miller, S., Neuman, C., Schiller, J., and J. Saltzer, "Section
+ E.2.1: Kerberos Authentication and Authorization System",
+ M.I.T. Project Athena, Cambridge, Massachusetts, December 21,
+ 1987.
+
+ [2] Steiner, J., Neuman, C., and J. Schiller, "Kerberos: An
+ Authentication Service for Open Network Systems", pp. 191-202 in
+ Usenix Conference Proceedings, Dallas, Texas, February, 1988.
+
+ [3] Needham, R., and M. Schroeder, "Using Encryption for
+ Authentication in Large Networks of Computers", Communications
+ of the ACM, Vol. 21 (12), pp. 993-999, December 1978.
+
+ [4] Denning, D., and G. Sacco, "Time stamps in Key Distribution
+ Protocols", Communications of the ACM, Vol. 24 (8), pp. 533-536,
+ August 1981.
+
+ [5] Kohl, J., Neuman, C., and T. Ts'o, "The Evolution of the
+ Kerberos Authentication Service", in an IEEE Computer Society
+ Text soon to be published, June 1992.
+
+ [6] Davis, D., and R. Swick, "Workstation Services and Kerberos
+ Authentication at Project Athena", Technical Memorandum TM-424,
+ MIT Laboratory for Computer Science, February 1990.
+
+ [7] Levine, P., Gretzinger, M, Diaz, J., Sommerfeld, W., and K.
+ Raeburn, "Section E.1: Service Management System, M.I.T.
+ Project Athena, Cambridge, Mas sachusetts (1987).
+
+ [8] CCITT, Recommendation X.509: The Directory Authentication
+ Framework, December 1988.
+
+ [9] Neuman, C., "Proxy-Based Authorization and Accounting for
+ Distributed Systems," in Proceedings of the 13th International
+ Conference on Distributed Computing Systems", Pittsburgh, PA,
+ May 1993.
+
+ [10] Pato, J., "Using Pre-Authentication to Avoid Password Guessing
+ Attacks", Open Software Foundation DCE Request for Comments 26,
+ December 1992.
+
+ [11] National Bureau of Standards, U.S. Department of Commerce, "Data
+ Encryption Standard", Federal Information Processing Standards
+ Publication 46, Washington, DC (1977).
+
+
+
+
+
+Kohl & Neuman [Page 89]
+
+RFC 1510 Kerberos September 1993
+
+
+ [12] National Bureau of Standards, U.S. Department of Commerce, "DES
+ Modes of Operation", Federal Information Processing Standards
+ Publication 81, Springfield, VA, December 1980.
+
+ [13] Stubblebine S., and V. Gligor, "On Message Integrity in
+ Cryptographic Protocols", in Proceedings of the IEEE Symposium
+ on Research in Security and Privacy, Oakland, California, May
+ 1992.
+
+ [14] International Organization for Standardization, "ISO Information
+ Processing Systems - Data Communication High-Level Data Link
+ Control Procedure - Frame Structure", IS 3309, October 1984, 3rd
+ Edition.
+
+ [15] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1320, MIT
+ Laboratory for Computer Science, April 1992.
+
+ [16] Rivest, R., "The MD5 Message Digest Algorithm", RFC 1321, MIT
+ Laboratory for Computer Science, April 1992.
+
+ [17] Bellovin S., and M. Merritt, "Limitations of the Kerberos
+ Authentication System", Computer Communications Review, Vol.
+ 20(5), pp. 119-132, October 1990.
+
+12. Security Considerations
+
+ Security issues are discussed throughout this memo.
+
+13. Authors' Addresses
+
+ John Kohl
+ Digital Equipment Corporation
+ 110 Spit Brook Road, M/S ZKO3-3/U14
+ Nashua, NH 03062
+
+ Phone: 603-881-2481
+ EMail: jtkohl@zk3.dec.com
+
+
+ B. Clifford Neuman
+ USC/Information Sciences Institute
+ 4676 Admiralty Way #1001
+ Marina del Rey, CA 90292-6695
+
+ Phone: 310-822-1511
+ EMail: bcn@isi.edu
+
+
+
+
+
+Kohl & Neuman [Page 90]
+
+RFC 1510 Kerberos September 1993
+
+
+A. Pseudo-code for protocol processing
+
+ This appendix provides pseudo-code describing how the messages are to
+ be constructed and interpreted by clients and servers.
+
+A.1. KRB_AS_REQ generation
+ request.pvno := protocol version; /* pvno = 5 */
+ request.msg-type := message type; /* type = KRB_AS_REQ */
+
+ if(pa_enc_timestamp_required) then
+ request.padata.padata-type = PA-ENC-TIMESTAMP;
+ get system_time;
+ padata-body.patimestamp,pausec = system_time;
+ encrypt padata-body into request.padata.padata-value
+ using client.key; /* derived from password */
+ endif
+
+ body.kdc-options := users's preferences;
+ body.cname := user's name;
+ body.realm := user's realm;
+ body.sname := service's name; /* usually "krbtgt",
+ "localrealm" */
+ if (body.kdc-options.POSTDATED is set) then
+ body.from := requested starting time;
+ else
+ omit body.from;
+ endif
+ body.till := requested end time;
+ if (body.kdc-options.RENEWABLE is set) then
+ body.rtime := requested final renewal time;
+ endif
+ body.nonce := random_nonce();
+ body.etype := requested etypes;
+ if (user supplied addresses) then
+ body.addresses := user's addresses;
+ else
+ omit body.addresses;
+ endif
+ omit body.enc-authorization-data;
+ request.req-body := body;
+
+ kerberos := lookup(name of local kerberos server (or servers));
+ send(packet,kerberos);
+
+ wait(for response);
+ if (timed_out) then
+ retry or use alternate server;
+ endif
+
+
+
+Kohl & Neuman [Page 91]
+
+RFC 1510 Kerberos September 1993
+
+
+A.2. KRB_AS_REQ verification and KRB_AS_REP generation
+ decode message into req;
+
+ client := lookup(req.cname,req.realm);
+ server := lookup(req.sname,req.realm);
+ get system_time;
+ kdc_time := system_time.seconds;
+
+ if (!client) then
+ /* no client in Database */
+ error_out(KDC_ERR_C_PRINCIPAL_UNKNOWN);
+ endif
+ if (!server) then
+ /* no server in Database */
+ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
+ endif
+
+ if(client.pa_enc_timestamp_required and
+ pa_enc_timestamp not present) then
+ error_out(KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP));
+ endif
+
+ if(pa_enc_timestamp present) then
+ decrypt req.padata-value into decrypted_enc_timestamp
+ using client.key;
+ using auth_hdr.authenticator.subkey;
+ if (decrypt_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ if(decrypted_enc_timestamp is not within allowable
+ skew) then error_out(KDC_ERR_PREAUTH_FAILED);
+ endif
+ if(decrypted_enc_timestamp and usec is replay)
+ error_out(KDC_ERR_PREAUTH_FAILED);
+ endif
+ add decrypted_enc_timestamp and usec to replay cache;
+ endif
+
+ use_etype := first supported etype in req.etypes;
+
+ if (no support for req.etypes) then
+ error_out(KDC_ERR_ETYPE_NOSUPP);
+ endif
+
+ new_tkt.vno := ticket version; /* = 5 */
+ new_tkt.sname := req.sname;
+ new_tkt.srealm := req.srealm;
+ reset all flags in new_tkt.flags;
+
+
+
+
+Kohl & Neuman [Page 92]
+
+RFC 1510 Kerberos September 1993
+
+
+ /* It should be noted that local policy may affect the */
+ /* processing of any of these flags. For example, some */
+ /* realms may refuse to issue renewable tickets */
+
+ if (req.kdc-options.FORWARDABLE is set) then
+ set new_tkt.flags.FORWARDABLE;
+ endif
+ if (req.kdc-options.PROXIABLE is set) then
+ set new_tkt.flags.PROXIABLE;
+ endif
+ if (req.kdc-options.ALLOW-POSTDATE is set) then
+ set new_tkt.flags.ALLOW-POSTDATE;
+ endif
+ if ((req.kdc-options.RENEW is set) or
+ (req.kdc-options.VALIDATE is set) or
+ (req.kdc-options.PROXY is set) or
+ (req.kdc-options.FORWARDED is set) or
+ (req.kdc-options.ENC-TKT-IN-SKEY is set)) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+ new_tkt.session := random_session_key();
+ new_tkt.cname := req.cname;
+ new_tkt.crealm := req.crealm;
+ new_tkt.transited := empty_transited_field();
+
+ new_tkt.authtime := kdc_time;
+
+ if (req.kdc-options.POSTDATED is set) then
+ if (against_postdate_policy(req.from)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ set new_tkt.flags.INVALID;
+ new_tkt.starttime := req.from;
+ else
+ omit new_tkt.starttime; /* treated as authtime when
+ omitted */
+ endif
+ if (req.till = 0) then
+ till := infinity;
+ else
+ till := req.till;
+ endif
+
+ new_tkt.endtime := min(till,
+ new_tkt.starttime+client.max_life,
+ new_tkt.starttime+server.max_life,
+ new_tkt.starttime+max_life_for_realm);
+
+
+
+Kohl & Neuman [Page 93]
+
+RFC 1510 Kerberos September 1993
+
+
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (new_tkt.endtime < req.till)) then
+ /* we set the RENEWABLE option for later processing */
+ set req.kdc-options.RENEWABLE;
+ req.rtime := req.till;
+ endif
+
+ if (req.rtime = 0) then
+ rtime := infinity;
+ else
+ rtime := req.rtime;
+ endif
+
+ if (req.kdc-options.RENEWABLE is set) then
+ set new_tkt.flags.RENEWABLE;
+ new_tkt.renew-till := min(rtime,
+ new_tkt.starttime+client.max_rlife,
+ new_tkt.starttime+server.max_rlife,
+ new_tkt.starttime+max_rlife_for_realm);
+ else
+ omit new_tkt.renew-till; /* only present if RENEWABLE */
+ endif
+
+ if (req.addresses) then
+ new_tkt.caddr := req.addresses;
+ else
+ omit new_tkt.caddr;
+ endif
+
+ new_tkt.authorization_data := empty_authorization_data();
+
+ encode to-be-encrypted part of ticket into OCTET STRING;
+ new_tkt.enc-part := encrypt OCTET STRING
+ using etype_for_key(server.key), server.key, server.p_kvno;
+
+
+ /* Start processing the response */
+
+ resp.pvno := 5;
+ resp.msg-type := KRB_AS_REP;
+ resp.cname := req.cname;
+ resp.crealm := req.realm;
+ resp.ticket := new_tkt;
+
+ resp.key := new_tkt.session;
+ resp.last-req := fetch_last_request_info(client);
+ resp.nonce := req.nonce;
+ resp.key-expiration := client.expiration;
+
+
+
+Kohl & Neuman [Page 94]
+
+RFC 1510 Kerberos September 1993
+
+
+ resp.flags := new_tkt.flags;
+
+ resp.authtime := new_tkt.authtime;
+ resp.starttime := new_tkt.starttime;
+ resp.endtime := new_tkt.endtime;
+
+ if (new_tkt.flags.RENEWABLE) then
+ resp.renew-till := new_tkt.renew-till;
+ endif
+
+ resp.realm := new_tkt.realm;
+ resp.sname := new_tkt.sname;
+
+ resp.caddr := new_tkt.caddr;
+
+ encode body of reply into OCTET STRING;
+
+ resp.enc-part := encrypt OCTET STRING
+ using use_etype, client.key, client.p_kvno;
+ send(resp);
+
+A.3. KRB_AS_REP verification
+ decode response into resp;
+
+ if (resp.msg-type = KRB_ERROR) then
+ if(error = KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP))
+ then set pa_enc_timestamp_required;
+ goto KRB_AS_REQ;
+ endif
+ process_error(resp);
+ return;
+ endif
+
+ /* On error, discard the response, and zero the session key */
+ /* from the response immediately */
+
+ key = get_decryption_key(resp.enc-part.kvno, resp.enc-part.etype,
+ resp.padata);
+ unencrypted part of resp := decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and key;
+ zero(key);
+
+ if (common_as_rep_tgs_rep_checks fail) then
+ destroy resp.key;
+ return error;
+ endif
+
+ if near(resp.princ_exp) then
+
+
+
+Kohl & Neuman [Page 95]
+
+RFC 1510 Kerberos September 1993
+
+
+ print(warning message);
+ endif
+ save_for_later(ticket,session,client,server,times,flags);
+
+A.4. KRB_AS_REP and KRB_TGS_REP common checks
+ if (decryption_error() or
+ (req.cname != resp.cname) or
+ (req.realm != resp.crealm) or
+ (req.sname != resp.sname) or
+ (req.realm != resp.realm) or
+ (req.nonce != resp.nonce) or
+ (req.addresses != resp.caddr)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ /* make sure no flags are set that shouldn't be, and that */
+ /* all that should be are set */
+ if (!check_flags_for_compatability(req.kdc-options,resp.flags))
+ then destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ if ((req.from = 0) and
+ (resp.starttime is not within allowable skew)) then
+ destroy resp.key;
+ return KRB_AP_ERR_SKEW;
+ endif
+ if ((req.from != 0) and (req.from != resp.starttime)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+ if ((req.till != 0) and (resp.endtime > req.till)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+
+ if ((req.kdc-options.RENEWABLE is set) and
+ (req.rtime != 0) and (resp.renew-till > req.rtime)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+ endif
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (resp.flags.RENEWABLE) and
+ (req.till != 0) and
+ (resp.renew-till > req.till)) then
+ destroy resp.key;
+ return KRB_AP_ERR_MODIFIED;
+
+
+
+Kohl & Neuman [Page 96]
+
+RFC 1510 Kerberos September 1993
+
+
+ endif
+
+A.5. KRB_TGS_REQ generation
+ /* Note that make_application_request might have to */
+ /* recursivly call this routine to get the appropriate */
+ /* ticket-granting ticket */
+
+ request.pvno := protocol version; /* pvno = 5 */
+ request.msg-type := message type; /* type = KRB_TGS_REQ */
+
+ body.kdc-options := users's preferences;
+ /* If the TGT is not for the realm of the end-server */
+ /* then the sname will be for a TGT for the end-realm */
+ /* and the realm of the requested ticket (body.realm) */
+ /* will be that of the TGS to which the TGT we are */
+ /* sending applies */
+ body.sname := service's name;
+ body.realm := service's realm;
+
+ if (body.kdc-options.POSTDATED is set) then
+ body.from := requested starting time;
+ else
+ omit body.from;
+ endif
+ body.till := requested end time;
+ if (body.kdc-options.RENEWABLE is set) then
+ body.rtime := requested final renewal time;
+ endif
+ body.nonce := random_nonce();
+ body.etype := requested etypes;
+ if (user supplied addresses) then
+ body.addresses := user's addresses;
+ else
+ omit body.addresses;
+ endif
+
+ body.enc-authorization-data := user-supplied data;
+ if (body.kdc-options.ENC-TKT-IN-SKEY) then
+ body.additional-tickets_ticket := second TGT;
+ endif
+
+ request.req-body := body;
+ check := generate_checksum (req.body,checksumtype);
+
+ request.padata[0].padata-type := PA-TGS-REQ;
+ request.padata[0].padata-value := create a KRB_AP_REQ using
+ the TGT and checksum
+
+
+
+
+Kohl & Neuman [Page 97]
+
+RFC 1510 Kerberos September 1993
+
+
+ /* add in any other padata as required/supplied */
+
+ kerberos := lookup(name of local kerberose server (or servers));
+ send(packet,kerberos);
+
+ wait(for response);
+ if (timed_out) then
+ retry or use alternate server;
+ endif
+
+A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation
+ /* note that reading the application request requires first
+ determining the server for which a ticket was issued, and
+ choosing the correct key for decryption. The name of the
+ server appears in the plaintext part of the ticket. */
+
+ if (no KRB_AP_REQ in req.padata) then
+ error_out(KDC_ERR_PADATA_TYPE_NOSUPP);
+ endif
+ verify KRB_AP_REQ in req.padata;
+
+ /* Note that the realm in which the Kerberos server is
+ operating is determined by the instance from the
+ ticket-granting ticket. The realm in the ticket-granting
+ ticket is the realm under which the ticket granting ticket was
+ issued. It is possible for a single Kerberos server to
+ support more than one realm. */
+
+ auth_hdr := KRB_AP_REQ;
+ tgt := auth_hdr.ticket;
+
+ if (tgt.sname is not a TGT for local realm and is not
+ req.sname) then error_out(KRB_AP_ERR_NOT_US);
+
+ realm := realm_tgt_is_for(tgt);
+
+ decode remainder of request;
+
+ if (auth_hdr.authenticator.cksum is missing) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+ if (auth_hdr.authenticator.cksum type is not supported) then
+ error_out(KDC_ERR_SUMTYPE_NOSUPP);
+ endif
+ if (auth_hdr.authenticator.cksum is not both collision-proof
+ and keyed) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+
+
+
+Kohl & Neuman [Page 98]
+
+RFC 1510 Kerberos September 1993
+
+
+ set computed_checksum := checksum(req);
+ if (computed_checksum != auth_hdr.authenticatory.cksum) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ server := lookup(req.sname,realm);
+
+ if (!server) then
+ if (is_foreign_tgt_name(server)) then
+ server := best_intermediate_tgs(server);
+ else
+ /* no server in Database */
+ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
+ endif
+ endif
+
+ session := generate_random_session_key();
+
+
+ use_etype := first supported etype in req.etypes;
+
+ if (no support for req.etypes) then
+ error_out(KDC_ERR_ETYPE_NOSUPP);
+ endif
+
+ new_tkt.vno := ticket version; /* = 5 */
+ new_tkt.sname := req.sname;
+ new_tkt.srealm := realm;
+ reset all flags in new_tkt.flags;
+
+ /* It should be noted that local policy may affect the */
+ /* processing of any of these flags. For example, some */
+ /* realms may refuse to issue renewable tickets */
+
+ new_tkt.caddr := tgt.caddr;
+ resp.caddr := NULL; /* We only include this if they change */
+ if (req.kdc-options.FORWARDABLE is set) then
+ if (tgt.flags.FORWARDABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.FORWARDABLE;
+ endif
+ if (req.kdc-options.FORWARDED is set) then
+ if (tgt.flags.FORWARDABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.FORWARDED;
+ new_tkt.caddr := req.addresses;
+
+
+
+Kohl & Neuman [Page 99]
+
+RFC 1510 Kerberos September 1993
+
+
+ resp.caddr := req.addresses;
+ endif
+ if (tgt.flags.FORWARDED is set) then
+ set new_tkt.flags.FORWARDED;
+ endif
+
+ if (req.kdc-options.PROXIABLE is set) then
+ if (tgt.flags.PROXIABLE is reset)
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.PROXIABLE;
+ endif
+ if (req.kdc-options.PROXY is set) then
+ if (tgt.flags.PROXIABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.PROXY;
+ new_tkt.caddr := req.addresses;
+ resp.caddr := req.addresses;
+ endif
+
+ if (req.kdc-options.POSTDATE is set) then
+ if (tgt.flags.POSTDATE is reset)
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.POSTDATE;
+ endif
+ if (req.kdc-options.POSTDATED is set) then
+ if (tgt.flags.POSTDATE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ set new_tkt.flags.POSTDATED;
+ set new_tkt.flags.INVALID;
+ if (against_postdate_policy(req.from)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ new_tkt.starttime := req.from;
+ endif
+
+
+ if (req.kdc-options.VALIDATE is set) then
+ if (tgt.flags.INVALID is reset) then
+ error_out(KDC_ERR_POLICY);
+ endif
+ if (tgt.starttime > kdc_time) then
+ error_out(KRB_AP_ERR_NYV);
+ endif
+ if (check_hot_list(tgt)) then
+
+
+
+Kohl & Neuman [Page 100]
+
+RFC 1510 Kerberos September 1993
+
+
+ error_out(KRB_AP_ERR_REPEAT);
+ endif
+ tkt := tgt;
+ reset new_tkt.flags.INVALID;
+ endif
+
+ if (req.kdc-options.(any flag except ENC-TKT-IN-SKEY, RENEW,
+ and those already processed) is set) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+
+ new_tkt.authtime := tgt.authtime;
+
+ if (req.kdc-options.RENEW is set) then
+ /* Note that if the endtime has already passed, the ticket */
+ /* would have been rejected in the initial authentication */
+ /* stage, so there is no need to check again here */
+ if (tgt.flags.RENEWABLE is reset) then
+ error_out(KDC_ERR_BADOPTION);
+ endif
+ if (tgt.renew-till >= kdc_time) then
+ error_out(KRB_AP_ERR_TKT_EXPIRED);
+ endif
+ tkt := tgt;
+ new_tkt.starttime := kdc_time;
+ old_life := tgt.endttime - tgt.starttime;
+ new_tkt.endtime := min(tgt.renew-till,
+ new_tkt.starttime + old_life);
+ else
+ new_tkt.starttime := kdc_time;
+ if (req.till = 0) then
+ till := infinity;
+ else
+ till := req.till;
+ endif
+ new_tkt.endtime := min(till,
+ new_tkt.starttime+client.max_life,
+ new_tkt.starttime+server.max_life,
+ new_tkt.starttime+max_life_for_realm,
+ tgt.endtime);
+
+ if ((req.kdc-options.RENEWABLE-OK is set) and
+ (new_tkt.endtime < req.till) and
+ (tgt.flags.RENEWABLE is set) then
+ /* we set the RENEWABLE option for later */
+ /* processing */
+ set req.kdc-options.RENEWABLE;
+ req.rtime := min(req.till, tgt.renew-till);
+
+
+
+Kohl & Neuman [Page 101]
+
+RFC 1510 Kerberos September 1993
+
+
+ endif
+ endif
+
+ if (req.rtime = 0) then
+ rtime := infinity;
+ else
+ rtime := req.rtime;
+ endif
+
+ if ((req.kdc-options.RENEWABLE is set) and
+ (tgt.flags.RENEWABLE is set)) then
+ set new_tkt.flags.RENEWABLE;
+ new_tkt.renew-till := min(rtime,
+ new_tkt.starttime+client.max_rlife,
+ new_tkt.starttime+server.max_rlife,
+ new_tkt.starttime+max_rlife_for_realm,
+ tgt.renew-till);
+ else
+ new_tkt.renew-till := OMIT;
+ /* leave the renew-till field out */
+ endif
+ if (req.enc-authorization-data is present) then
+ decrypt req.enc-authorization-data
+ into decrypted_authorization_data
+ using auth_hdr.authenticator.subkey;
+ if (decrypt_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ endif
+ new_tkt.authorization_data :=
+ req.auth_hdr.ticket.authorization_data +
+ decrypted_authorization_data;
+
+ new_tkt.key := session;
+ new_tkt.crealm := tgt.crealm;
+ new_tkt.cname := req.auth_hdr.ticket.cname;
+
+ if (realm_tgt_is_for(tgt) := tgt.realm) then
+ /* tgt issued by local realm */
+ new_tkt.transited := tgt.transited;
+ else
+ /* was issued for this realm by some other realm */
+ if (tgt.transited.tr-type not supported) then
+ error_out(KDC_ERR_TRTYPE_NOSUPP);
+ endif
+ new_tkt.transited
+ := compress_transited(tgt.transited + tgt.realm)
+ endif
+
+
+
+Kohl & Neuman [Page 102]
+
+RFC 1510 Kerberos September 1993
+
+
+ encode encrypted part of new_tkt into OCTET STRING;
+ if (req.kdc-options.ENC-TKT-IN-SKEY is set) then
+ if (server not specified) then
+ server = req.second_ticket.client;
+ endif
+ if ((req.second_ticket is not a TGT) or
+ (req.second_ticket.client != server)) then
+ error_out(KDC_ERR_POLICY);
+ endif
+
+ new_tkt.enc-part := encrypt OCTET STRING using
+ using etype_for_key(second-ticket.key),
+ second-ticket.key;
+ else
+ new_tkt.enc-part := encrypt OCTET STRING
+ using etype_for_key(server.key), server.key,
+ server.p_kvno;
+ endif
+
+ resp.pvno := 5;
+ resp.msg-type := KRB_TGS_REP;
+ resp.crealm := tgt.crealm;
+ resp.cname := tgt.cname;
+ resp.ticket := new_tkt;
+
+ resp.key := session;
+ resp.nonce := req.nonce;
+ resp.last-req := fetch_last_request_info(client);
+ resp.flags := new_tkt.flags;
+
+ resp.authtime := new_tkt.authtime;
+ resp.starttime := new_tkt.starttime;
+ resp.endtime := new_tkt.endtime;
+
+ omit resp.key-expiration;
+
+ resp.sname := new_tkt.sname;
+ resp.realm := new_tkt.realm;
+
+ if (new_tkt.flags.RENEWABLE) then
+ resp.renew-till := new_tkt.renew-till;
+ endif
+
+
+ encode body of reply into OCTET STRING;
+
+ if (req.padata.authenticator.subkey)
+ resp.enc-part := encrypt OCTET STRING using use_etype,
+
+
+
+Kohl & Neuman [Page 103]
+
+RFC 1510 Kerberos September 1993
+
+
+ req.padata.authenticator.subkey;
+ else resp.enc-part := encrypt OCTET STRING
+ using use_etype, tgt.key;
+
+ send(resp);
+
+A.7. KRB_TGS_REP verification
+ decode response into resp;
+
+ if (resp.msg-type = KRB_ERROR) then
+ process_error(resp);
+ return;
+ endif
+
+ /* On error, discard the response, and zero the session key from
+ the response immediately */
+
+ if (req.padata.authenticator.subkey)
+ unencrypted part of resp :=
+ decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and subkey;
+ else unencrypted part of resp :=
+ decode of decrypt of resp.enc-part
+ using resp.enc-part.etype and tgt's session key;
+ if (common_as_rep_tgs_rep_checks fail) then
+ destroy resp.key;
+ return error;
+ endif
+
+ check authorization_data as necessary;
+ save_for_later(ticket,session,client,server,times,flags);
+
+A.8. Authenticator generation
+ body.authenticator-vno := authenticator vno; /* = 5 */
+ body.cname, body.crealm := client name;
+ if (supplying checksum) then
+ body.cksum := checksum;
+ endif
+ get system_time;
+ body.ctime, body.cusec := system_time;
+ if (selecting sub-session key) then
+ select sub-session key;
+ body.subkey := sub-session key;
+ endif
+ if (using sequence numbers) then
+ select initial sequence number;
+ body.seq-number := initial sequence;
+ endif
+
+
+
+Kohl & Neuman [Page 104]
+
+RFC 1510 Kerberos September 1993
+
+
+A.9. KRB_AP_REQ generation
+ obtain ticket and session_key from cache;
+
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_AP_REQ */
+
+ if (desired(MUTUAL_AUTHENTICATION)) then
+ set packet.ap-options.MUTUAL-REQUIRED;
+ else
+ reset packet.ap-options.MUTUAL-REQUIRED;
+ endif
+ if (using session key for ticket) then
+ set packet.ap-options.USE-SESSION-KEY;
+ else
+ reset packet.ap-options.USE-SESSION-KEY;
+ endif
+ packet.ticket := ticket; /* ticket */
+ generate authenticator;
+ encode authenticator into OCTET STRING;
+ encrypt OCTET STRING into packet.authenticator
+ using session_key;
+
+A.10. KRB_AP_REQ verification
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_AP_REQ) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ if (packet.ticket.tkt_vno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.ap_options.USE-SESSION-KEY is set) then
+ retrieve session key from ticket-granting ticket for
+ packet.ticket.{sname,srealm,enc-part.etype};
+ else
+ retrieve service key for
+ packet.ticket.{sname,srealm,enc-part.etype,enc-part.skvno};
+ endif
+ if (no_key_available) then
+ if (cannot_find_specified_skvno) then
+ error_out(KRB_AP_ERR_BADKEYVER);
+ else
+ error_out(KRB_AP_ERR_NOKEY);
+ endif
+
+
+
+Kohl & Neuman [Page 105]
+
+RFC 1510 Kerberos September 1993
+
+
+ endif
+ decrypt packet.ticket.enc-part into decr_ticket
+ using retrieved key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ decrypt packet.authenticator into decr_authenticator
+ using decr_ticket.key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if (decr_authenticator.{cname,crealm} !=
+ decr_ticket.{cname,crealm}) then
+ error_out(KRB_AP_ERR_BADMATCH);
+ endif
+ if (decr_ticket.caddr is present) then
+ if (sender_address(packet) is not in decr_ticket.caddr)
+ then error_out(KRB_AP_ERR_BADADDR);
+ endif
+ elseif (application requires addresses) then
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (not in_clock_skew(decr_authenticator.ctime,
+ decr_authenticator.cusec)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(decr_authenticator.{ctime,cusec,cname,crealm}))
+ then error_out(KRB_AP_ERR_REPEAT);
+ endif
+ save_identifier(decr_authenticator.{ctime,cusec,cname,crealm});
+ get system_time;
+ if ((decr_ticket.starttime-system_time > CLOCK_SKEW) or
+ (decr_ticket.flags.INVALID is set)) then
+ /* it hasn't yet become valid */
+ error_out(KRB_AP_ERR_TKT_NYV);
+ endif
+ if (system_time-decr_ticket.endtime > CLOCK_SKEW) then
+ error_out(KRB_AP_ERR_TKT_EXPIRED);
+ endif
+ /* caller must check decr_ticket.flags for any pertinent */
+ /* details */
+ return(OK, decr_ticket, packet.ap_options.MUTUAL-REQUIRED);
+
+A.11. KRB_AP_REP generation
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_AP_REP */
+ body.ctime := packet.ctime;
+ body.cusec := packet.cusec;
+
+
+
+Kohl & Neuman [Page 106]
+
+RFC 1510 Kerberos September 1993
+
+
+ if (selecting sub-session key) then
+ select sub-session key;
+ body.subkey := sub-session key;
+ endif
+ if (using sequence numbers) then
+ select initial sequence number;
+ body.seq-number := initial sequence;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part;
+
+A.12. KRB_AP_REP verification
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_AP_REP) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ cleartext := decrypt(packet.enc-part)
+ using ticket's session key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if (cleartext.ctime != authenticator.ctime) then
+ error_out(KRB_AP_ERR_MUT_FAIL);
+ endif
+ if (cleartext.cusec != authenticator.cusec) then
+ error_out(KRB_AP_ERR_MUT_FAIL);
+ endif
+ if (cleartext.subkey is present) then
+ save cleartext.subkey for future use;
+ endif
+ if (cleartext.seq-number is present) then
+ save cleartext.seq-number for future verifications;
+ endif
+ return(AUTHENTICATION_SUCCEEDED);
+
+A.13. KRB_SAFE generation
+ collect user data in buffer;
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_SAFE */
+
+
+
+Kohl & Neuman [Page 107]
+
+RFC 1510 Kerberos September 1993
+
+
+ body.user-data := buffer; /* DATA */
+ if (using timestamp) then
+ get system_time;
+ body.timestamp, body.usec := system_time;
+ endif
+ if (using sequence numbers) then
+ body.seq-number := sequence number;
+ endif
+ body.s-address := sender host addresses;
+ if (only one recipient) then
+ body.r-address := recipient host address;
+ endif
+ checksum.cksumtype := checksum type;
+ compute checksum over body;
+ checksum.checksum := checksum value; /* checksum.checksum */
+ packet.cksum := checksum;
+ packet.safe-body := body;
+
+A.14. KRB_SAFE verification
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_SAFE) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+ if (packet.checksum.cksumtype is not both collision-proof
+ and keyed) then
+ error_out(KRB_AP_ERR_INAPP_CKSUM);
+ endif
+ if (safe_priv_common_checks_ok(packet)) then
+ set computed_checksum := checksum(packet.body);
+ if (computed_checksum != packet.checksum) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+ return (packet, PACKET_IS_GENUINE);
+ else
+ return common_checks_error;
+ endif
+
+A.15. KRB_SAFE and KRB_PRIV common checks
+ if (packet.s-address != O/S_sender(packet)) then
+ /* O/S report of sender not who claims to have sent it */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if ((packet.r-address is present) and
+ (packet.r-address != local_host_address)) then
+
+
+
+Kohl & Neuman [Page 108]
+
+RFC 1510 Kerberos September 1993
+
+
+ /* was not sent to proper place */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if (((packet.timestamp is present) and
+ (not in_clock_skew(packet.timestamp,packet.usec))) or
+ (packet.timestamp is not present and timestamp expected))
+ then error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(packet.timestamp,packet.usec,packet.s-address))
+ then error_out(KRB_AP_ERR_REPEAT);
+ endif
+ if (((packet.seq-number is present) and
+ ((not in_sequence(packet.seq-number)))) or
+ (packet.seq-number is not present and sequence expected))
+ then error_out(KRB_AP_ERR_BADORDER);
+ endif
+ if (packet.timestamp not present and
+ packet.seq-number not present) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ save_identifier(packet.{timestamp,usec,s-address},
+ sender_principal(packet));
+
+ return PACKET_IS_OK;
+
+A.16. KRB_PRIV generation
+ collect user data in buffer;
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_PRIV */
+
+ packet.enc-part.etype := encryption type;
+
+ body.user-data := buffer;
+ if (using timestamp) then
+ get system_time;
+ body.timestamp, body.usec := system_time;
+ endif
+ if (using sequence numbers) then
+ body.seq-number := sequence number;
+ endif
+ body.s-address := sender host addresses;
+ if (only one recipient) then
+ body.r-address := recipient host address;
+ endif
+
+
+
+
+Kohl & Neuman [Page 109]
+
+RFC 1510 Kerberos September 1993
+
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part.cipher;
+
+A.17. KRB_PRIV verification
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_PRIV) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+
+ cleartext := decrypt(packet.enc-part) using negotiated key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+
+ if (safe_priv_common_checks_ok(cleartext)) then
+ return(cleartext.DATA, PACKET_IS_GENUINE_AND_UNMODIFIED);
+ else
+ return common_checks_error;
+ endif
+
+A.18. KRB_CRED generation
+ invoke KRB_TGS; /* obtain tickets to be provided to peer */
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_CRED */
+
+ for (tickets[n] in tickets to be forwarded) do
+ packet.tickets[n] = tickets[n].ticket;
+ done
+
+ packet.enc-part.etype := encryption type;
+
+ for (ticket[n] in tickets to be forwarded) do
+ body.ticket-info[n].key = tickets[n].session;
+ body.ticket-info[n].prealm = tickets[n].crealm;
+ body.ticket-info[n].pname = tickets[n].cname;
+ body.ticket-info[n].flags = tickets[n].flags;
+ body.ticket-info[n].authtime = tickets[n].authtime;
+ body.ticket-info[n].starttime = tickets[n].starttime;
+ body.ticket-info[n].endtime = tickets[n].endtime;
+ body.ticket-info[n].renew-till = tickets[n].renew-till;
+
+
+
+Kohl & Neuman [Page 110]
+
+RFC 1510 Kerberos September 1993
+
+
+ body.ticket-info[n].srealm = tickets[n].srealm;
+ body.ticket-info[n].sname = tickets[n].sname;
+ body.ticket-info[n].caddr = tickets[n].caddr;
+ done
+
+ get system_time;
+ body.timestamp, body.usec := system_time;
+
+ if (using nonce) then
+ body.nonce := nonce;
+ endif
+
+ if (using s-address) then
+ body.s-address := sender host addresses;
+ endif
+ if (limited recipients) then
+ body.r-address := recipient host address;
+ endif
+
+ encode body into OCTET STRING;
+
+ select encryption type;
+ encrypt OCTET STRING into packet.enc-part.cipher
+ using negotiated encryption key;
+
+A.19. KRB_CRED verification
+ receive packet;
+ if (packet.pvno != 5) then
+ either process using other protocol spec
+ or error_out(KRB_AP_ERR_BADVERSION);
+ endif
+ if (packet.msg-type != KRB_CRED) then
+ error_out(KRB_AP_ERR_MSG_TYPE);
+ endif
+
+ cleartext := decrypt(packet.enc-part) using negotiated key;
+ if (decryption_error()) then
+ error_out(KRB_AP_ERR_BAD_INTEGRITY);
+ endif
+ if ((packet.r-address is present or required) and
+ (packet.s-address != O/S_sender(packet)) then
+ /* O/S report of sender not who claims to have sent it */
+ error_out(KRB_AP_ERR_BADADDR);
+ endif
+ if ((packet.r-address is present) and
+ (packet.r-address != local_host_address)) then
+ /* was not sent to proper place */
+ error_out(KRB_AP_ERR_BADADDR);
+
+
+
+Kohl & Neuman [Page 111]
+
+RFC 1510 Kerberos September 1993
+
+
+ endif
+ if (not in_clock_skew(packet.timestamp,packet.usec)) then
+ error_out(KRB_AP_ERR_SKEW);
+ endif
+ if (repeated(packet.timestamp,packet.usec,packet.s-address))
+ then error_out(KRB_AP_ERR_REPEAT);
+ endif
+ if (packet.nonce is required or present) and
+ (packet.nonce != expected-nonce) then
+ error_out(KRB_AP_ERR_MODIFIED);
+ endif
+
+ for (ticket[n] in tickets that were forwarded) do
+ save_for_later(ticket[n],key[n],principal[n],
+ server[n],times[n],flags[n]);
+ return
+
+A.20. KRB_ERROR generation
+
+ /* assemble packet: */
+ packet.pvno := protocol version; /* 5 */
+ packet.msg-type := message type; /* KRB_ERROR */
+
+ get system_time;
+ packet.stime, packet.susec := system_time;
+ packet.realm, packet.sname := server name;
+
+ if (client time available) then
+ packet.ctime, packet.cusec := client_time;
+ endif
+ packet.error-code := error code;
+ if (client name available) then
+ packet.cname, packet.crealm := client name;
+ endif
+ if (error text available) then
+ packet.e-text := error text;
+ endif
+ if (error data available) then
+ packet.e-data := error data;
+ endif
+
+
+
+
+
+
+
+
+
+
+
+Kohl & Neuman [Page 112]
+ \ No newline at end of file
diff --git a/crypto/heimdal/doc/standardisation/rfc1750.txt b/crypto/heimdal/doc/standardisation/rfc1750.txt
new file mode 100644
index 000000000000..56d478c7eef4
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/rfc1750.txt
@@ -0,0 +1,1683 @@
+
+
+
+
+
+
+Network Working Group D. Eastlake, 3rd
+Request for Comments: 1750 DEC
+Category: Informational S. Crocker
+ Cybercash
+ J. Schiller
+ MIT
+ December 1994
+
+
+ Randomness Recommendations for Security
+
+Status of this Memo
+
+ This memo provides information for the Internet community. This memo
+ does not specify an Internet standard of any kind. Distribution of
+ this memo is unlimited.
+
+Abstract
+
+ Security systems today are built on increasingly strong cryptographic
+ algorithms that foil pattern analysis attempts. However, the security
+ of these systems is dependent on generating secret quantities for
+ passwords, cryptographic keys, and similar quantities. The use of
+ pseudo-random processes to generate secret quantities can result in
+ pseudo-security. The sophisticated attacker of these security
+ systems may find it easier to reproduce the environment that produced
+ the secret quantities, searching the resulting small set of
+ possibilities, than to locate the quantities in the whole of the
+ number space.
+
+ Choosing random quantities to foil a resourceful and motivated
+ adversary is surprisingly difficult. This paper points out many
+ pitfalls in using traditional pseudo-random number generation
+ techniques for choosing such quantities. It recommends the use of
+ truly random hardware techniques and shows that the existing hardware
+ on many systems can be used for this purpose. It provides
+ suggestions to ameliorate the problem when a hardware solution is not
+ available. And it gives examples of how large such quantities need
+ to be for some particular applications.
+
+
+
+
+
+
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 1]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+Acknowledgements
+
+ Comments on this document that have been incorporated were received
+ from (in alphabetic order) the following:
+
+ David M. Balenson (TIS)
+ Don Coppersmith (IBM)
+ Don T. Davis (consultant)
+ Carl Ellison (Stratus)
+ Marc Horowitz (MIT)
+ Christian Huitema (INRIA)
+ Charlie Kaufman (IRIS)
+ Steve Kent (BBN)
+ Hal Murray (DEC)
+ Neil Haller (Bellcore)
+ Richard Pitkin (DEC)
+ Tim Redmond (TIS)
+ Doug Tygar (CMU)
+
+Table of Contents
+
+ 1. Introduction........................................... 3
+ 2. Requirements........................................... 4
+ 3. Traditional Pseudo-Random Sequences.................... 5
+ 4. Unpredictability....................................... 7
+ 4.1 Problems with Clocks and Serial Numbers............... 7
+ 4.2 Timing and Content of External Events................ 8
+ 4.3 The Fallacy of Complex Manipulation.................. 8
+ 4.4 The Fallacy of Selection from a Large Database....... 9
+ 5. Hardware for Randomness............................... 10
+ 5.1 Volume Required...................................... 10
+ 5.2 Sensitivity to Skew.................................. 10
+ 5.2.1 Using Stream Parity to De-Skew..................... 11
+ 5.2.2 Using Transition Mappings to De-Skew............... 12
+ 5.2.3 Using FFT to De-Skew............................... 13
+ 5.2.4 Using Compression to De-Skew....................... 13
+ 5.3 Existing Hardware Can Be Used For Randomness......... 14
+ 5.3.1 Using Existing Sound/Video Input................... 14
+ 5.3.2 Using Existing Disk Drives......................... 14
+ 6. Recommended Non-Hardware Strategy..................... 14
+ 6.1 Mixing Functions..................................... 15
+ 6.1.1 A Trivial Mixing Function.......................... 15
+ 6.1.2 Stronger Mixing Functions.......................... 16
+ 6.1.3 Diff-Hellman as a Mixing Function.................. 17
+ 6.1.4 Using a Mixing Function to Stretch Random Bits..... 17
+ 6.1.5 Other Factors in Choosing a Mixing Function........ 18
+ 6.2 Non-Hardware Sources of Randomness................... 19
+ 6.3 Cryptographically Strong Sequences................... 19
+
+
+
+Eastlake, Crocker & Schiller [Page 2]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ 6.3.1 Traditional Strong Sequences....................... 20
+ 6.3.2 The Blum Blum Shub Sequence Generator.............. 21
+ 7. Key Generation Standards.............................. 22
+ 7.1 US DoD Recommendations for Password Generation....... 23
+ 7.2 X9.17 Key Generation................................. 23
+ 8. Examples of Randomness Required....................... 24
+ 8.1 Password Generation................................. 24
+ 8.2 A Very High Security Cryptographic Key............... 25
+ 8.2.1 Effort per Key Trial............................... 25
+ 8.2.2 Meet in the Middle Attacks......................... 26
+ 8.2.3 Other Considerations............................... 26
+ 9. Conclusion............................................ 27
+ 10. Security Considerations.............................. 27
+ References............................................... 28
+ Authors' Addresses....................................... 30
+
+1. Introduction
+
+ Software cryptography is coming into wider use. Systems like
+ Kerberos, PEM, PGP, etc. are maturing and becoming a part of the
+ network landscape [PEM]. These systems provide substantial
+ protection against snooping and spoofing. However, there is a
+ potential flaw. At the heart of all cryptographic systems is the
+ generation of secret, unguessable (i.e., random) numbers.
+
+ For the present, the lack of generally available facilities for
+ generating such unpredictable numbers is an open wound in the design
+ of cryptographic software. For the software developer who wants to
+ build a key or password generation procedure that runs on a wide
+ range of hardware, the only safe strategy so far has been to force
+ the local installation to supply a suitable routine to generate
+ random numbers. To say the least, this is an awkward, error-prone
+ and unpalatable solution.
+
+ It is important to keep in mind that the requirement is for data that
+ an adversary has a very low probability of guessing or determining.
+ This will fail if pseudo-random data is used which only meets
+ traditional statistical tests for randomness or which is based on
+ limited range sources, such as clocks. Frequently such random
+ quantities are determinable by an adversary searching through an
+ embarrassingly small space of possibilities.
+
+ This informational document suggests techniques for producing random
+ quantities that will be resistant to such attack. It recommends that
+ future systems include hardware random number generation or provide
+ access to existing hardware that can be used for this purpose. It
+ suggests methods for use if such hardware is not available. And it
+ gives some estimates of the number of random bits required for sample
+
+
+
+Eastlake, Crocker & Schiller [Page 3]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ applications.
+
+2. Requirements
+
+ Probably the most commonly encountered randomness requirement today
+ is the user password. This is usually a simple character string.
+ Obviously, if a password can be guessed, it does not provide
+ security. (For re-usable passwords, it is desirable that users be
+ able to remember the password. This may make it advisable to use
+ pronounceable character strings or phrases composed on ordinary
+ words. But this only affects the format of the password information,
+ not the requirement that the password be very hard to guess.)
+
+ Many other requirements come from the cryptographic arena.
+ Cryptographic techniques can be used to provide a variety of services
+ including confidentiality and authentication. Such services are
+ based on quantities, traditionally called "keys", that are unknown to
+ and unguessable by an adversary.
+
+ In some cases, such as the use of symmetric encryption with the one
+ time pads [CRYPTO*] or the US Data Encryption Standard [DES], the
+ parties who wish to communicate confidentially and/or with
+ authentication must all know the same secret key. In other cases,
+ using what are called asymmetric or "public key" cryptographic
+ techniques, keys come in pairs. One key of the pair is private and
+ must be kept secret by one party, the other is public and can be
+ published to the world. It is computationally infeasible to
+ determine the private key from the public key [ASYMMETRIC, CRYPTO*].
+
+ The frequency and volume of the requirement for random quantities
+ differs greatly for different cryptographic systems. Using pure RSA
+ [CRYPTO*], random quantities are required when the key pair is
+ generated, but thereafter any number of messages can be signed
+ without any further need for randomness. The public key Digital
+ Signature Algorithm that has been proposed by the US National
+ Institute of Standards and Technology (NIST) requires good random
+ numbers for each signature. And encrypting with a one time pad, in
+ principle the strongest possible encryption technique, requires a
+ volume of randomness equal to all the messages to be processed.
+
+ In most of these cases, an adversary can try to determine the
+ "secret" key by trial and error. (This is possible as long as the
+ key is enough smaller than the message that the correct key can be
+ uniquely identified.) The probability of an adversary succeeding at
+ this must be made acceptably low, depending on the particular
+ application. The size of the space the adversary must search is
+ related to the amount of key "information" present in the information
+ theoretic sense [SHANNON]. This depends on the number of different
+
+
+
+Eastlake, Crocker & Schiller [Page 4]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ secret values possible and the probability of each value as follows:
+
+ -----
+ \
+ Bits-of-info = \ - p * log ( p )
+ / i 2 i
+ /
+ -----
+
+ where i varies from 1 to the number of possible secret values and p
+ sub i is the probability of the value numbered i. (Since p sub i is
+ less than one, the log will be negative so each term in the sum will
+ be non-negative.)
+
+ If there are 2^n different values of equal probability, then n bits
+ of information are present and an adversary would, on the average,
+ have to try half of the values, or 2^(n-1) , before guessing the
+ secret quantity. If the probability of different values is unequal,
+ then there is less information present and fewer guesses will, on
+ average, be required by an adversary. In particular, any values that
+ the adversary can know are impossible, or are of low probability, can
+ be initially ignored by an adversary, who will search through the
+ more probable values first.
+
+ For example, consider a cryptographic system that uses 56 bit keys.
+ If these 56 bit keys are derived by using a fixed pseudo-random
+ number generator that is seeded with an 8 bit seed, then an adversary
+ needs to search through only 256 keys (by running the pseudo-random
+ number generator with every possible seed), not the 2^56 keys that
+ may at first appear to be the case. Only 8 bits of "information" are
+ in these 56 bit keys.
+
+3. Traditional Pseudo-Random Sequences
+
+ Most traditional sources of random numbers use deterministic sources
+ of "pseudo-random" numbers. These typically start with a "seed"
+ quantity and use numeric or logical operations to produce a sequence
+ of values.
+
+ [KNUTH] has a classic exposition on pseudo-random numbers.
+ Applications he mentions are simulation of natural phenomena,
+ sampling, numerical analysis, testing computer programs, decision
+ making, and games. None of these have the same characteristics as
+ the sort of security uses we are talking about. Only in the last two
+ could there be an adversary trying to find the random quantity.
+ However, in these cases, the adversary normally has only a single
+ chance to use a guessed value. In guessing passwords or attempting
+ to break an encryption scheme, the adversary normally has many,
+
+
+
+Eastlake, Crocker & Schiller [Page 5]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ perhaps unlimited, chances at guessing the correct value and should
+ be assumed to be aided by a computer.
+
+ For testing the "randomness" of numbers, Knuth suggests a variety of
+ measures including statistical and spectral. These tests check
+ things like autocorrelation between different parts of a "random"
+ sequence or distribution of its values. They could be met by a
+ constant stored random sequence, such as the "random" sequence
+ printed in the CRC Standard Mathematical Tables [CRC].
+
+ A typical pseudo-random number generation technique, known as a
+ linear congruence pseudo-random number generator, is modular
+ arithmetic where the N+1th value is calculated from the Nth value by
+
+ V = ( V * a + b )(Mod c)
+ N+1 N
+
+ The above technique has a strong relationship to linear shift
+ register pseudo-random number generators, which are well understood
+ cryptographically [SHIFT*]. In such generators bits are introduced
+ at one end of a shift register as the Exclusive Or (binary sum
+ without carry) of bits from selected fixed taps into the register.
+
+ For example:
+
+ +----+ +----+ +----+ +----+
+ | B | <-- | B | <-- | B | <-- . . . . . . <-- | B | <-+
+ | 0 | | 1 | | 2 | | n | |
+ +----+ +----+ +----+ +----+ |
+ | | | |
+ | | V +-----+
+ | V +----------------> | |
+ V +-----------------------------> | XOR |
+ +---------------------------------------------------> | |
+ +-----+
+
+
+ V = ( ( V * 2 ) + B .xor. B ... )(Mod 2^n)
+ N+1 N 0 2
+
+ The goodness of traditional pseudo-random number generator algorithms
+ is measured by statistical tests on such sequences. Carefully chosen
+ values of the initial V and a, b, and c or the placement of shift
+ register tap in the above simple processes can produce excellent
+ statistics.
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 6]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ These sequences may be adequate in simulations (Monte Carlo
+ experiments) as long as the sequence is orthogonal to the structure
+ of the space being explored. Even there, subtle patterns may cause
+ problems. However, such sequences are clearly bad for use in
+ security applications. They are fully predictable if the initial
+ state is known. Depending on the form of the pseudo-random number
+ generator, the sequence may be determinable from observation of a
+ short portion of the sequence [CRYPTO*, STERN]. For example, with
+ the generators above, one can determine V(n+1) given knowledge of
+ V(n). In fact, it has been shown that with these techniques, even if
+ only one bit of the pseudo-random values is released, the seed can be
+ determined from short sequences.
+
+ Not only have linear congruent generators been broken, but techniques
+ are now known for breaking all polynomial congruent generators
+ [KRAWCZYK].
+
+4. Unpredictability
+
+ Randomness in the traditional sense described in section 3 is NOT the
+ same as the unpredictability required for security use.
+
+ For example, use of a widely available constant sequence, such as
+ that from the CRC tables, is very weak against an adversary. Once
+ they learn of or guess it, they can easily break all security, future
+ and past, based on the sequence [CRC]. Yet the statistical
+ properties of these tables are good.
+
+ The following sections describe the limitations of some randomness
+ generation techniques and sources.
+
+4.1 Problems with Clocks and Serial Numbers
+
+ Computer clocks, or similar operating system or hardware values,
+ provide significantly fewer real bits of unpredictability than might
+ appear from their specifications.
+
+ Tests have been done on clocks on numerous systems and it was found
+ that their behavior can vary widely and in unexpected ways. One
+ version of an operating system running on one set of hardware may
+ actually provide, say, microsecond resolution in a clock while a
+ different configuration of the "same" system may always provide the
+ same lower bits and only count in the upper bits at much lower
+ resolution. This means that successive reads on the clock may
+ produce identical values even if enough time has passed that the
+ value "should" change based on the nominal clock resolution. There
+ are also cases where frequently reading a clock can produce
+ artificial sequential values because of extra code that checks for
+
+
+
+Eastlake, Crocker & Schiller [Page 7]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ the clock being unchanged between two reads and increases it by one!
+ Designing portable application code to generate unpredictable numbers
+ based on such system clocks is particularly challenging because the
+ system designer does not always know the properties of the system
+ clocks that the code will execute on.
+
+ Use of a hardware serial number such as an Ethernet address may also
+ provide fewer bits of uniqueness than one would guess. Such
+ quantities are usually heavily structured and subfields may have only
+ a limited range of possible values or values easily guessable based
+ on approximate date of manufacture or other data. For example, it is
+ likely that most of the Ethernet cards installed on Digital Equipment
+ Corporation (DEC) hardware within DEC were manufactured by DEC
+ itself, which significantly limits the range of built in addresses.
+
+ Problems such as those described above related to clocks and serial
+ numbers make code to produce unpredictable quantities difficult if
+ the code is to be ported across a variety of computer platforms and
+ systems.
+
+4.2 Timing and Content of External Events
+
+ It is possible to measure the timing and content of mouse movement,
+ key strokes, and similar user events. This is a reasonable source of
+ unguessable data with some qualifications. On some machines, inputs
+ such as key strokes are buffered. Even though the user's inter-
+ keystroke timing may have sufficient variation and unpredictability,
+ there might not be an easy way to access that variation. Another
+ problem is that no standard method exists to sample timing details.
+ This makes it hard to build standard software intended for
+ distribution to a large range of machines based on this technique.
+
+ The amount of mouse movement or the keys actually hit are usually
+ easier to access than timings but may yield less unpredictability as
+ the user may provide highly repetitive input.
+
+ Other external events, such as network packet arrival times, can also
+ be used with care. In particular, the possibility of manipulation of
+ such times by an adversary must be considered.
+
+4.3 The Fallacy of Complex Manipulation
+
+ One strategy which may give a misleading appearance of
+ unpredictability is to take a very complex algorithm (or an excellent
+ traditional pseudo-random number generator with good statistical
+ properties) and calculate a cryptographic key by starting with the
+ current value of a computer system clock as the seed. An adversary
+ who knew roughly when the generator was started would have a
+
+
+
+Eastlake, Crocker & Schiller [Page 8]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ relatively small number of seed values to test as they would know
+ likely values of the system clock. Large numbers of pseudo-random
+ bits could be generated but the search space an adversary would need
+ to check could be quite small.
+
+ Thus very strong and/or complex manipulation of data will not help if
+ the adversary can learn what the manipulation is and there is not
+ enough unpredictability in the starting seed value. Even if they can
+ not learn what the manipulation is, they may be able to use the
+ limited number of results stemming from a limited number of seed
+ values to defeat security.
+
+ Another serious strategy error is to assume that a very complex
+ pseudo-random number generation algorithm will produce strong random
+ numbers when there has been no theory behind or analysis of the
+ algorithm. There is a excellent example of this fallacy right near
+ the beginning of chapter 3 in [KNUTH] where the author describes a
+ complex algorithm. It was intended that the machine language program
+ corresponding to the algorithm would be so complicated that a person
+ trying to read the code without comments wouldn't know what the
+ program was doing. Unfortunately, actual use of this algorithm
+ showed that it almost immediately converged to a single repeated
+ value in one case and a small cycle of values in another case.
+
+ Not only does complex manipulation not help you if you have a limited
+ range of seeds but blindly chosen complex manipulation can destroy
+ the randomness in a good seed!
+
+4.4 The Fallacy of Selection from a Large Database
+
+ Another strategy that can give a misleading appearance of
+ unpredictability is selection of a quantity randomly from a database
+ and assume that its strength is related to the total number of bits
+ in the database. For example, typical USENET servers as of this date
+ process over 35 megabytes of information per day. Assume a random
+ quantity was selected by fetching 32 bytes of data from a random
+ starting point in this data. This does not yield 32*8 = 256 bits
+ worth of unguessability. Even after allowing that much of the data
+ is human language and probably has more like 2 or 3 bits of
+ information per byte, it doesn't yield 32*2.5 = 80 bits of
+ unguessability. For an adversary with access to the same 35
+ megabytes the unguessability rests only on the starting point of the
+ selection. That is, at best, about 25 bits of unguessability in this
+ case.
+
+ The same argument applies to selecting sequences from the data on a
+ CD ROM or Audio CD recording or any other large public database. If
+ the adversary has access to the same database, this "selection from a
+
+
+
+Eastlake, Crocker & Schiller [Page 9]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ large volume of data" step buys very little. However, if a selection
+ can be made from data to which the adversary has no access, such as
+ system buffers on an active multi-user system, it may be of some
+ help.
+
+5. Hardware for Randomness
+
+ Is there any hope for strong portable randomness in the future?
+ There might be. All that's needed is a physical source of
+ unpredictable numbers.
+
+ A thermal noise or radioactive decay source and a fast, free-running
+ oscillator would do the trick directly [GIFFORD]. This is a trivial
+ amount of hardware, and could easily be included as a standard part
+ of a computer system's architecture. Furthermore, any system with a
+ spinning disk or the like has an adequate source of randomness
+ [DAVIS]. All that's needed is the common perception among computer
+ vendors that this small additional hardware and the software to
+ access it is necessary and useful.
+
+5.1 Volume Required
+
+ How much unpredictability is needed? Is it possible to quantify the
+ requirement in, say, number of random bits per second?
+
+ The answer is not very much is needed. For DES, the key is 56 bits
+ and, as we show in an example in Section 8, even the highest security
+ system is unlikely to require a keying material of over 200 bits. If
+ a series of keys are needed, it can be generated from a strong random
+ seed using a cryptographically strong sequence as explained in
+ Section 6.3. A few hundred random bits generated once a day would be
+ enough using such techniques. Even if the random bits are generated
+ as slowly as one per second and it is not possible to overlap the
+ generation process, it should be tolerable in high security
+ applications to wait 200 seconds occasionally.
+
+ These numbers are trivial to achieve. It could be done by a person
+ repeatedly tossing a coin. Almost any hardware process is likely to
+ be much faster.
+
+5.2 Sensitivity to Skew
+
+ Is there any specific requirement on the shape of the distribution of
+ the random numbers? The good news is the distribution need not be
+ uniform. All that is needed is a conservative estimate of how non-
+ uniform it is to bound performance. Two simple techniques to de-skew
+ the bit stream are given below and stronger techniques are mentioned
+ in Section 6.1.2 below.
+
+
+
+Eastlake, Crocker & Schiller [Page 10]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+5.2.1 Using Stream Parity to De-Skew
+
+ Consider taking a sufficiently long string of bits and map the string
+ to "zero" or "one". The mapping will not yield a perfectly uniform
+ distribution, but it can be as close as desired. One mapping that
+ serves the purpose is to take the parity of the string. This has the
+ advantages that it is robust across all degrees of skew up to the
+ estimated maximum skew and is absolutely trivial to implement in
+ hardware.
+
+ The following analysis gives the number of bits that must be sampled:
+
+ Suppose the ratio of ones to zeros is 0.5 + e : 0.5 - e, where e is
+ between 0 and 0.5 and is a measure of the "eccentricity" of the
+ distribution. Consider the distribution of the parity function of N
+ bit samples. The probabilities that the parity will be one or zero
+ will be the sum of the odd or even terms in the binomial expansion of
+ (p + q)^N, where p = 0.5 + e, the probability of a one, and q = 0.5 -
+ e, the probability of a zero.
+
+ These sums can be computed easily as
+
+ N N
+ 1/2 * ( ( p + q ) + ( p - q ) )
+ and
+ N N
+ 1/2 * ( ( p + q ) - ( p - q ) ).
+
+ (Which one corresponds to the probability the parity will be 1
+ depends on whether N is odd or even.)
+
+ Since p + q = 1 and p - q = 2e, these expressions reduce to
+
+ N
+ 1/2 * [1 + (2e) ]
+ and
+ N
+ 1/2 * [1 - (2e) ].
+
+ Neither of these will ever be exactly 0.5 unless e is zero, but we
+ can bring them arbitrarily close to 0.5. If we want the
+ probabilities to be within some delta d of 0.5, i.e. then
+
+ N
+ ( 0.5 + ( 0.5 * (2e) ) ) < 0.5 + d.
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 11]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ Solving for N yields N > log(2d)/log(2e). (Note that 2e is less than
+ 1, so its log is negative. Division by a negative number reverses
+ the sense of an inequality.)
+
+ The following table gives the length of the string which must be
+ sampled for various degrees of skew in order to come within 0.001 of
+ a 50/50 distribution.
+
+ +---------+--------+-------+
+ | Prob(1) | e | N |
+ +---------+--------+-------+
+ | 0.5 | 0.00 | 1 |
+ | 0.6 | 0.10 | 4 |
+ | 0.7 | 0.20 | 7 |
+ | 0.8 | 0.30 | 13 |
+ | 0.9 | 0.40 | 28 |
+ | 0.95 | 0.45 | 59 |
+ | 0.99 | 0.49 | 308 |
+ +---------+--------+-------+
+
+ The last entry shows that even if the distribution is skewed 99% in
+ favor of ones, the parity of a string of 308 samples will be within
+ 0.001 of a 50/50 distribution.
+
+5.2.2 Using Transition Mappings to De-Skew
+
+ Another technique, originally due to von Neumann [VON NEUMANN], is to
+ examine a bit stream as a sequence of non-overlapping pairs. You
+ could then discard any 00 or 11 pairs found, interpret 01 as a 0 and
+ 10 as a 1. Assume the probability of a 1 is 0.5+e and the
+ probability of a 0 is 0.5-e where e is the eccentricity of the source
+ and described in the previous section. Then the probability of each
+ pair is as follows:
+
+ +------+-----------------------------------------+
+ | pair | probability |
+ +------+-----------------------------------------+
+ | 00 | (0.5 - e)^2 = 0.25 - e + e^2 |
+ | 01 | (0.5 - e)*(0.5 + e) = 0.25 - e^2 |
+ | 10 | (0.5 + e)*(0.5 - e) = 0.25 - e^2 |
+ | 11 | (0.5 + e)^2 = 0.25 + e + e^2 |
+ +------+-----------------------------------------+
+
+ This technique will completely eliminate any bias but at the expense
+ of taking an indeterminate number of input bits for any particular
+ desired number of output bits. The probability of any particular
+ pair being discarded is 0.5 + 2e^2 so the expected number of input
+ bits to produce X output bits is X/(0.25 - e^2).
+
+
+
+Eastlake, Crocker & Schiller [Page 12]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ This technique assumes that the bits are from a stream where each bit
+ has the same probability of being a 0 or 1 as any other bit in the
+ stream and that bits are not correlated, i.e., that the bits are
+ identical independent distributions. If alternate bits were from two
+ correlated sources, for example, the above analysis breaks down.
+
+ The above technique also provides another illustration of how a
+ simple statistical analysis can mislead if one is not always on the
+ lookout for patterns that could be exploited by an adversary. If the
+ algorithm were mis-read slightly so that overlapping successive bits
+ pairs were used instead of non-overlapping pairs, the statistical
+ analysis given is the same; however, instead of provided an unbiased
+ uncorrelated series of random 1's and 0's, it instead produces a
+ totally predictable sequence of exactly alternating 1's and 0's.
+
+5.2.3 Using FFT to De-Skew
+
+ When real world data consists of strongly biased or correlated bits,
+ it may still contain useful amounts of randomness. This randomness
+ can be extracted through use of the discrete Fourier transform or its
+ optimized variant, the FFT.
+
+ Using the Fourier transform of the data, strong correlations can be
+ discarded. If adequate data is processed and remaining correlations
+ decay, spectral lines approaching statistical independence and
+ normally distributed randomness can be produced [BRILLINGER].
+
+5.2.4 Using Compression to De-Skew
+
+ Reversible compression techniques also provide a crude method of de-
+ skewing a skewed bit stream. This follows directly from the
+ definition of reversible compression and the formula in Section 2
+ above for the amount of information in a sequence. Since the
+ compression is reversible, the same amount of information must be
+ present in the shorter output than was present in the longer input.
+ By the Shannon information equation, this is only possible if, on
+ average, the probabilities of the different shorter sequences are
+ more uniformly distributed than were the probabilities of the longer
+ sequences. Thus the shorter sequences are de-skewed relative to the
+ input.
+
+ However, many compression techniques add a somewhat predicatable
+ preface to their output stream and may insert such a sequence again
+ periodically in their output or otherwise introduce subtle patterns
+ of their own. They should be considered only a rough technique
+ compared with those described above or in Section 6.1.2. At a
+ minimum, the beginning of the compressed sequence should be skipped
+ and only later bits used for applications requiring random bits.
+
+
+
+Eastlake, Crocker & Schiller [Page 13]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+5.3 Existing Hardware Can Be Used For Randomness
+
+ As described below, many computers come with hardware that can, with
+ care, be used to generate truly random quantities.
+
+5.3.1 Using Existing Sound/Video Input
+
+ Increasingly computers are being built with inputs that digitize some
+ real world analog source, such as sound from a microphone or video
+ input from a camera. Under appropriate circumstances, such input can
+ provide reasonably high quality random bits. The "input" from a
+ sound digitizer with no source plugged in or a camera with the lens
+ cap on, if the system has enough gain to detect anything, is
+ essentially thermal noise.
+
+ For example, on a SPARCstation, one can read from the /dev/audio
+ device with nothing plugged into the microphone jack. Such data is
+ essentially random noise although it should not be trusted without
+ some checking in case of hardware failure. It will, in any case,
+ need to be de-skewed as described elsewhere.
+
+ Combining this with compression to de-skew one can, in UNIXese,
+ generate a huge amount of medium quality random data by doing
+
+ cat /dev/audio | compress - >random-bits-file
+
+5.3.2 Using Existing Disk Drives
+
+ Disk drives have small random fluctuations in their rotational speed
+ due to chaotic air turbulence [DAVIS]. By adding low level disk seek
+ time instrumentation to a system, a series of measurements can be
+ obtained that include this randomness. Such data is usually highly
+ correlated so that significant processing is needed, including FFT
+ (see section 5.2.3). Nevertheless experimentation has shown that,
+ with such processing, disk drives easily produce 100 bits a minute or
+ more of excellent random data.
+
+ Partly offsetting this need for processing is the fact that disk
+ drive failure will normally be rapidly noticed. Thus, problems with
+ this method of random number generation due to hardware failure are
+ very unlikely.
+
+6. Recommended Non-Hardware Strategy
+
+ What is the best overall strategy for meeting the requirement for
+ unguessable random numbers in the absence of a reliable hardware
+ source? It is to obtain random input from a large number of
+ uncorrelated sources and to mix them with a strong mixing function.
+
+
+
+Eastlake, Crocker & Schiller [Page 14]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ Such a function will preserve the randomness present in any of the
+ sources even if other quantities being combined are fixed or easily
+ guessable. This may be advisable even with a good hardware source as
+ hardware can also fail, though this should be weighed against any
+ increase in the chance of overall failure due to added software
+ complexity.
+
+6.1 Mixing Functions
+
+ A strong mixing function is one which combines two or more inputs and
+ produces an output where each output bit is a different complex non-
+ linear function of all the input bits. On average, changing any
+ input bit will change about half the output bits. But because the
+ relationship is complex and non-linear, no particular output bit is
+ guaranteed to change when any particular input bit is changed.
+
+ Consider the problem of converting a stream of bits that is skewed
+ towards 0 or 1 to a shorter stream which is more random, as discussed
+ in Section 5.2 above. This is simply another case where a strong
+ mixing function is desired, mixing the input bits to produce a
+ smaller number of output bits. The technique given in Section 5.2.1
+ of using the parity of a number of bits is simply the result of
+ successively Exclusive Or'ing them which is examined as a trivial
+ mixing function immediately below. Use of stronger mixing functions
+ to extract more of the randomness in a stream of skewed bits is
+ examined in Section 6.1.2.
+
+6.1.1 A Trivial Mixing Function
+
+ A trivial example for single bit inputs is the Exclusive Or function,
+ which is equivalent to addition without carry, as show in the table
+ below. This is a degenerate case in which the one output bit always
+ changes for a change in either input bit. But, despite its
+ simplicity, it will still provide a useful illustration.
+
+ +-----------+-----------+----------+
+ | input 1 | input 2 | output |
+ +-----------+-----------+----------+
+ | 0 | 0 | 0 |
+ | 0 | 1 | 1 |
+ | 1 | 0 | 1 |
+ | 1 | 1 | 0 |
+ +-----------+-----------+----------+
+
+ If inputs 1 and 2 are uncorrelated and combined in this fashion then
+ the output will be an even better (less skewed) random bit than the
+ inputs. If we assume an "eccentricity" e as defined in Section 5.2
+ above, then the output eccentricity relates to the input eccentricity
+
+
+
+Eastlake, Crocker & Schiller [Page 15]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ as follows:
+
+ e = 2 * e * e
+ output input 1 input 2
+
+ Since e is never greater than 1/2, the eccentricity is always
+ improved except in the case where at least one input is a totally
+ skewed constant. This is illustrated in the following table where
+ the top and left side values are the two input eccentricities and the
+ entries are the output eccentricity:
+
+ +--------+--------+--------+--------+--------+--------+--------+
+ | e | 0.00 | 0.10 | 0.20 | 0.30 | 0.40 | 0.50 |
+ +--------+--------+--------+--------+--------+--------+--------+
+ | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |
+ | 0.10 | 0.00 | 0.02 | 0.04 | 0.06 | 0.08 | 0.10 |
+ | 0.20 | 0.00 | 0.04 | 0.08 | 0.12 | 0.16 | 0.20 |
+ | 0.30 | 0.00 | 0.06 | 0.12 | 0.18 | 0.24 | 0.30 |
+ | 0.40 | 0.00 | 0.08 | 0.16 | 0.24 | 0.32 | 0.40 |
+ | 0.50 | 0.00 | 0.10 | 0.20 | 0.30 | 0.40 | 0.50 |
+ +--------+--------+--------+--------+--------+--------+--------+
+
+ However, keep in mind that the above calculations assume that the
+ inputs are not correlated. If the inputs were, say, the parity of
+ the number of minutes from midnight on two clocks accurate to a few
+ seconds, then each might appear random if sampled at random intervals
+ much longer than a minute. Yet if they were both sampled and
+ combined with xor, the result would be zero most of the time.
+
+6.1.2 Stronger Mixing Functions
+
+ The US Government Data Encryption Standard [DES] is an example of a
+ strong mixing function for multiple bit quantities. It takes up to
+ 120 bits of input (64 bits of "data" and 56 bits of "key") and
+ produces 64 bits of output each of which is dependent on a complex
+ non-linear function of all input bits. Other strong encryption
+ functions with this characteristic can also be used by considering
+ them to mix all of their key and data input bits.
+
+ Another good family of mixing functions are the "message digest" or
+ hashing functions such as The US Government Secure Hash Standard
+ [SHS] and the MD2, MD4, MD5 [MD2, MD4, MD5] series. These functions
+ all take an arbitrary amount of input and produce an output mixing
+ all the input bits. The MD* series produce 128 bits of output and SHS
+ produces 160 bits.
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 16]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ Although the message digest functions are designed for variable
+ amounts of input, DES and other encryption functions can also be used
+ to combine any number of inputs. If 64 bits of output is adequate,
+ the inputs can be packed into a 64 bit data quantity and successive
+ 56 bit keys, padding with zeros if needed, which are then used to
+ successively encrypt using DES in Electronic Codebook Mode [DES
+ MODES]. If more than 64 bits of output are needed, use more complex
+ mixing. For example, if inputs are packed into three quantities, A,
+ B, and C, use DES to encrypt A with B as a key and then with C as a
+ key to produce the 1st part of the output, then encrypt B with C and
+ then A for more output and, if necessary, encrypt C with A and then B
+ for yet more output. Still more output can be produced by reversing
+ the order of the keys given above to stretch things. The same can be
+ done with the hash functions by hashing various subsets of the input
+ data to produce multiple outputs. But keep in mind that it is
+ impossible to get more bits of "randomness" out than are put in.
+
+ An example of using a strong mixing function would be to reconsider
+ the case of a string of 308 bits each of which is biased 99% towards
+ zero. The parity technique given in Section 5.2.1 above reduced this
+ to one bit with only a 1/1000 deviance from being equally likely a
+ zero or one. But, applying the equation for information given in
+ Section 2, this 308 bit sequence has 5 bits of information in it.
+ Thus hashing it with SHS or MD5 and taking the bottom 5 bits of the
+ result would yield 5 unbiased random bits as opposed to the single
+ bit given by calculating the parity of the string.
+
+6.1.3 Diffie-Hellman as a Mixing Function
+
+ Diffie-Hellman exponential key exchange is a technique that yields a
+ shared secret between two parties that can be made computationally
+ infeasible for a third party to determine even if they can observe
+ all the messages between the two communicating parties. This shared
+ secret is a mixture of initial quantities generated by each of them
+ [D-H]. If these initial quantities are random, then the shared
+ secret contains the combined randomness of them both, assuming they
+ are uncorrelated.
+
+6.1.4 Using a Mixing Function to Stretch Random Bits
+
+ While it is not necessary for a mixing function to produce the same
+ or fewer bits than its inputs, mixing bits cannot "stretch" the
+ amount of random unpredictability present in the inputs. Thus four
+ inputs of 32 bits each where there is 12 bits worth of
+ unpredicatability (such as 4,096 equally probable values) in each
+ input cannot produce more than 48 bits worth of unpredictable output.
+ The output can be expanded to hundreds or thousands of bits by, for
+ example, mixing with successive integers, but the clever adversary's
+
+
+
+Eastlake, Crocker & Schiller [Page 17]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ search space is still 2^48 possibilities. Furthermore, mixing to
+ fewer bits than are input will tend to strengthen the randomness of
+ the output the way using Exclusive Or to produce one bit from two did
+ above.
+
+ The last table in Section 6.1.1 shows that mixing a random bit with a
+ constant bit with Exclusive Or will produce a random bit. While this
+ is true, it does not provide a way to "stretch" one random bit into
+ more than one. If, for example, a random bit is mixed with a 0 and
+ then with a 1, this produces a two bit sequence but it will always be
+ either 01 or 10. Since there are only two possible values, there is
+ still only the one bit of original randomness.
+
+6.1.5 Other Factors in Choosing a Mixing Function
+
+ For local use, DES has the advantages that it has been widely tested
+ for flaws, is widely documented, and is widely implemented with
+ hardware and software implementations available all over the world
+ including source code available by anonymous FTP. The SHS and MD*
+ family are younger algorithms which have been less tested but there
+ is no particular reason to believe they are flawed. Both MD5 and SHS
+ were derived from the earlier MD4 algorithm. They all have source
+ code available by anonymous FTP [SHS, MD2, MD4, MD5].
+
+ DES and SHS have been vouched for the the US National Security Agency
+ (NSA) on the basis of criteria that primarily remain secret. While
+ this is the cause of much speculation and doubt, investigation of DES
+ over the years has indicated that NSA involvement in modifications to
+ its design, which originated with IBM, was primarily to strengthen
+ it. No concealed or special weakness has been found in DES. It is
+ almost certain that the NSA modification to MD4 to produce the SHS
+ similarly strengthened the algorithm, possibly against threats not
+ yet known in the public cryptographic community.
+
+ DES, SHS, MD4, and MD5 are royalty free for all purposes. MD2 has
+ been freely licensed only for non-profit use in connection with
+ Privacy Enhanced Mail [PEM]. Between the MD* algorithms, some people
+ believe that, as with "Goldilocks and the Three Bears", MD2 is strong
+ but too slow, MD4 is fast but too weak, and MD5 is just right.
+
+ Another advantage of the MD* or similar hashing algorithms over
+ encryption algorithms is that they are not subject to the same
+ regulations imposed by the US Government prohibiting the unlicensed
+ export or import of encryption/decryption software and hardware. The
+ same should be true of DES rigged to produce an irreversible hash
+ code but most DES packages are oriented to reversible encryption.
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 18]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+6.2 Non-Hardware Sources of Randomness
+
+ The best source of input for mixing would be a hardware randomness
+ such as disk drive timing affected by air turbulence, audio input
+ with thermal noise, or radioactive decay. However, if that is not
+ available there are other possibilities. These include system
+ clocks, system or input/output buffers, user/system/hardware/network
+ serial numbers and/or addresses and timing, and user input.
+ Unfortunately, any of these sources can produce limited or
+ predicatable values under some circumstances.
+
+ Some of the sources listed above would be quite strong on multi-user
+ systems where, in essence, each user of the system is a source of
+ randomness. However, on a small single user system, such as a
+ typical IBM PC or Apple Macintosh, it might be possible for an
+ adversary to assemble a similar configuration. This could give the
+ adversary inputs to the mixing process that were sufficiently
+ correlated to those used originally as to make exhaustive search
+ practical.
+
+ The use of multiple random inputs with a strong mixing function is
+ recommended and can overcome weakness in any particular input. For
+ example, the timing and content of requested "random" user keystrokes
+ can yield hundreds of random bits but conservative assumptions need
+ to be made. For example, assuming a few bits of randomness if the
+ inter-keystroke interval is unique in the sequence up to that point
+ and a similar assumption if the key hit is unique but assuming that
+ no bits of randomness are present in the initial key value or if the
+ timing or key value duplicate previous values. The results of mixing
+ these timings and characters typed could be further combined with
+ clock values and other inputs.
+
+ This strategy may make practical portable code to produce good random
+ numbers for security even if some of the inputs are very weak on some
+ of the target systems. However, it may still fail against a high
+ grade attack on small single user systems, especially if the
+ adversary has ever been able to observe the generation process in the
+ past. A hardware based random source is still preferable.
+
+6.3 Cryptographically Strong Sequences
+
+ In cases where a series of random quantities must be generated, an
+ adversary may learn some values in the sequence. In general, they
+ should not be able to predict other values from the ones that they
+ know.
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 19]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ The correct technique is to start with a strong random seed, take
+ cryptographically strong steps from that seed [CRYPTO2, CRYPTO3], and
+ do not reveal the complete state of the generator in the sequence
+ elements. If each value in the sequence can be calculated in a fixed
+ way from the previous value, then when any value is compromised, all
+ future values can be determined. This would be the case, for
+ example, if each value were a constant function of the previously
+ used values, even if the function were a very strong, non-invertible
+ message digest function.
+
+ It should be noted that if your technique for generating a sequence
+ of key values is fast enough, it can trivially be used as the basis
+ for a confidentiality system. If two parties use the same sequence
+ generating technique and start with the same seed material, they will
+ generate identical sequences. These could, for example, be xor'ed at
+ one end with data being send, encrypting it, and xor'ed with this
+ data as received, decrypting it due to the reversible properties of
+ the xor operation.
+
+6.3.1 Traditional Strong Sequences
+
+ A traditional way to achieve a strong sequence has been to have the
+ values be produced by hashing the quantities produced by
+ concatenating the seed with successive integers or the like and then
+ mask the values obtained so as to limit the amount of generator state
+ available to the adversary.
+
+ It may also be possible to use an "encryption" algorithm with a
+ random key and seed value to encrypt and feedback some or all of the
+ output encrypted value into the value to be encrypted for the next
+ iteration. Appropriate feedback techniques will usually be
+ recommended with the encryption algorithm. An example is shown below
+ where shifting and masking are used to combine the cypher output
+ feedback. This type of feedback is recommended by the US Government
+ in connection with DES [DES MODES].
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 20]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ +---------------+
+ | V |
+ | | n |
+ +--+------------+
+ | | +---------+
+ | +---------> | | +-----+
+ +--+ | Encrypt | <--- | Key |
+ | +-------- | | +-----+
+ | | +---------+
+ V V
+ +------------+--+
+ | V | |
+ | n+1 |
+ +---------------+
+
+ Note that if a shift of one is used, this is the same as the shift
+ register technique described in Section 3 above but with the all
+ important difference that the feedback is determined by a complex
+ non-linear function of all bits rather than a simple linear or
+ polynomial combination of output from a few bit position taps.
+
+ It has been shown by Donald W. Davies that this sort of shifted
+ partial output feedback significantly weakens an algorithm compared
+ will feeding all of the output bits back as input. In particular,
+ for DES, repeated encrypting a full 64 bit quantity will give an
+ expected repeat in about 2^63 iterations. Feeding back anything less
+ than 64 (and more than 0) bits will give an expected repeat in
+ between 2**31 and 2**32 iterations!
+
+ To predict values of a sequence from others when the sequence was
+ generated by these techniques is equivalent to breaking the
+ cryptosystem or inverting the "non-invertible" hashing involved with
+ only partial information available. The less information revealed
+ each iteration, the harder it will be for an adversary to predict the
+ sequence. Thus it is best to use only one bit from each value. It
+ has been shown that in some cases this makes it impossible to break a
+ system even when the cryptographic system is invertible and can be
+ broken if all of each generated value was revealed.
+
+6.3.2 The Blum Blum Shub Sequence Generator
+
+ Currently the generator which has the strongest public proof of
+ strength is called the Blum Blum Shub generator after its inventors
+ [BBS]. It is also very simple and is based on quadratic residues.
+ It's only disadvantage is that is is computationally intensive
+ compared with the traditional techniques give in 6.3.1 above. This
+ is not a serious draw back if it is used for moderately infrequent
+ purposes, such as generating session keys.
+
+
+
+Eastlake, Crocker & Schiller [Page 21]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ Simply choose two large prime numbers, say p and q, which both have
+ the property that you get a remainder of 3 if you divide them by 4.
+ Let n = p * q. Then you choose a random number x relatively prime to
+ n. The initial seed for the generator and the method for calculating
+ subsequent values are then
+
+ 2
+ s = ( x )(Mod n)
+ 0
+
+ 2
+ s = ( s )(Mod n)
+ i+1 i
+
+ You must be careful to use only a few bits from the bottom of each s.
+ It is always safe to use only the lowest order bit. If you use no
+ more than the
+
+ log ( log ( s ) )
+ 2 2 i
+
+ low order bits, then predicting any additional bits from a sequence
+ generated in this manner is provable as hard as factoring n. As long
+ as the initial x is secret, you can even make n public if you want.
+
+ An intersting characteristic of this generator is that you can
+ directly calculate any of the s values. In particular
+
+ i
+ ( ( 2 )(Mod (( p - 1 ) * ( q - 1 )) ) )
+ s = ( s )(Mod n)
+ i 0
+
+ This means that in applications where many keys are generated in this
+ fashion, it is not necessary to save them all. Each key can be
+ effectively indexed and recovered from that small index and the
+ initial s and n.
+
+7. Key Generation Standards
+
+ Several public standards are now in place for the generation of keys.
+ Two of these are described below. Both use DES but any equally
+ strong or stronger mixing function could be substituted.
+
+
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 22]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+7.1 US DoD Recommendations for Password Generation
+
+ The United States Department of Defense has specific recommendations
+ for password generation [DoD]. They suggest using the US Data
+ Encryption Standard [DES] in Output Feedback Mode [DES MODES] as
+ follows:
+
+ use an initialization vector determined from
+ the system clock,
+ system ID,
+ user ID, and
+ date and time;
+ use a key determined from
+ system interrupt registers,
+ system status registers, and
+ system counters; and,
+ as plain text, use an external randomly generated 64 bit
+ quantity such as 8 characters typed in by a system
+ administrator.
+
+ The password can then be calculated from the 64 bit "cipher text"
+ generated in 64-bit Output Feedback Mode. As many bits as are needed
+ can be taken from these 64 bits and expanded into a pronounceable
+ word, phrase, or other format if a human being needs to remember the
+ password.
+
+7.2 X9.17 Key Generation
+
+ The American National Standards Institute has specified a method for
+ generating a sequence of keys as follows:
+
+ s is the initial 64 bit seed
+ 0
+
+ g is the sequence of generated 64 bit key quantities
+ n
+
+ k is a random key reserved for generating this key sequence
+
+ t is the time at which a key is generated to as fine a resolution
+ as is available (up to 64 bits).
+
+ DES ( K, Q ) is the DES encryption of quantity Q with key K
+
+
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 23]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ g = DES ( k, DES ( k, t ) .xor. s )
+ n n
+
+ s = DES ( k, DES ( k, t ) .xor. g )
+ n+1 n
+
+ If g sub n is to be used as a DES key, then every eighth bit should
+ be adjusted for parity for that use but the entire 64 bit unmodified
+ g should be used in calculating the next s.
+
+8. Examples of Randomness Required
+
+ Below are two examples showing rough calculations of needed
+ randomness for security. The first is for moderate security
+ passwords while the second assumes a need for a very high security
+ cryptographic key.
+
+8.1 Password Generation
+
+ Assume that user passwords change once a year and it is desired that
+ the probability that an adversary could guess the password for a
+ particular account be less than one in a thousand. Further assume
+ that sending a password to the system is the only way to try a
+ password. Then the crucial question is how often an adversary can
+ try possibilities. Assume that delays have been introduced into a
+ system so that, at most, an adversary can make one password try every
+ six seconds. That's 600 per hour or about 15,000 per day or about
+ 5,000,000 tries in a year. Assuming any sort of monitoring, it is
+ unlikely someone could actually try continuously for a year. In
+ fact, even if log files are only checked monthly, 500,000 tries is
+ more plausible before the attack is noticed and steps taken to change
+ passwords and make it harder to try more passwords.
+
+ To have a one in a thousand chance of guessing the password in
+ 500,000 tries implies a universe of at least 500,000,000 passwords or
+ about 2^29. Thus 29 bits of randomness are needed. This can probably
+ be achieved using the US DoD recommended inputs for password
+ generation as it has 8 inputs which probably average over 5 bits of
+ randomness each (see section 7.1). Using a list of 1000 words, the
+ password could be expressed as a three word phrase (1,000,000,000
+ possibilities) or, using case insensitive letters and digits, six
+ would suffice ((26+10)^6 = 2,176,782,336 possibilities).
+
+ For a higher security password, the number of bits required goes up.
+ To decrease the probability by 1,000 requires increasing the universe
+ of passwords by the same factor which adds about 10 bits. Thus to
+ have only a one in a million chance of a password being guessed under
+ the above scenario would require 39 bits of randomness and a password
+
+
+
+Eastlake, Crocker & Schiller [Page 24]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ that was a four word phrase from a 1000 word list or eight
+ letters/digits. To go to a one in 10^9 chance, 49 bits of randomness
+ are needed implying a five word phrase or ten letter/digit password.
+
+ In a real system, of course, there are also other factors. For
+ example, the larger and harder to remember passwords are, the more
+ likely users are to write them down resulting in an additional risk
+ of compromise.
+
+8.2 A Very High Security Cryptographic Key
+
+ Assume that a very high security key is needed for symmetric
+ encryption / decryption between two parties. Assume an adversary can
+ observe communications and knows the algorithm being used. Within
+ the field of random possibilities, the adversary can try key values
+ in hopes of finding the one in use. Assume further that brute force
+ trial of keys is the best the adversary can do.
+
+8.2.1 Effort per Key Trial
+
+ How much effort will it take to try each key? For very high security
+ applications it is best to assume a low value of effort. Even if it
+ would clearly take tens of thousands of computer cycles or more to
+ try a single key, there may be some pattern that enables huge blocks
+ of key values to be tested with much less effort per key. Thus it is
+ probably best to assume no more than a couple hundred cycles per key.
+ (There is no clear lower bound on this as computers operate in
+ parallel on a number of bits and a poor encryption algorithm could
+ allow many keys or even groups of keys to be tested in parallel.
+ However, we need to assume some value and can hope that a reasonably
+ strong algorithm has been chosen for our hypothetical high security
+ task.)
+
+ If the adversary can command a highly parallel processor or a large
+ network of work stations, 2*10^10 cycles per second is probably a
+ minimum assumption for availability today. Looking forward just a
+ couple years, there should be at least an order of magnitude
+ improvement. Thus assuming 10^9 keys could be checked per second or
+ 3.6*10^11 per hour or 6*10^13 per week or 2.4*10^14 per month is
+ reasonable. This implies a need for a minimum of 51 bits of
+ randomness in keys to be sure they cannot be found in a month. Even
+ then it is possible that, a few years from now, a highly determined
+ and resourceful adversary could break the key in 2 weeks (on average
+ they need try only half the keys).
+
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 25]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+8.2.2 Meet in the Middle Attacks
+
+ If chosen or known plain text and the resulting encrypted text are
+ available, a "meet in the middle" attack is possible if the structure
+ of the encryption algorithm allows it. (In a known plain text
+ attack, the adversary knows all or part of the messages being
+ encrypted, possibly some standard header or trailer fields. In a
+ chosen plain text attack, the adversary can force some chosen plain
+ text to be encrypted, possibly by "leaking" an exciting text that
+ would then be sent by the adversary over an encrypted channel.)
+
+ An oversimplified explanation of the meet in the middle attack is as
+ follows: the adversary can half-encrypt the known or chosen plain
+ text with all possible first half-keys, sort the output, then half-
+ decrypt the encoded text with all the second half-keys. If a match
+ is found, the full key can be assembled from the halves and used to
+ decrypt other parts of the message or other messages. At its best,
+ this type of attack can halve the exponent of the work required by
+ the adversary while adding a large but roughly constant factor of
+ effort. To be assured of safety against this, a doubling of the
+ amount of randomness in the key to a minimum of 102 bits is required.
+
+ The meet in the middle attack assumes that the cryptographic
+ algorithm can be decomposed in this way but we can not rule that out
+ without a deep knowledge of the algorithm. Even if a basic algorithm
+ is not subject to a meet in the middle attack, an attempt to produce
+ a stronger algorithm by applying the basic algorithm twice (or two
+ different algorithms sequentially) with different keys may gain less
+ added security than would be expected. Such a composite algorithm
+ would be subject to a meet in the middle attack.
+
+ Enormous resources may be required to mount a meet in the middle
+ attack but they are probably within the range of the national
+ security services of a major nation. Essentially all nations spy on
+ other nations government traffic and several nations are believed to
+ spy on commercial traffic for economic advantage.
+
+8.2.3 Other Considerations
+
+ Since we have not even considered the possibilities of special
+ purpose code breaking hardware or just how much of a safety margin we
+ want beyond our assumptions above, probably a good minimum for a very
+ high security cryptographic key is 128 bits of randomness which
+ implies a minimum key length of 128 bits. If the two parties agree
+ on a key by Diffie-Hellman exchange [D-H], then in principle only
+ half of this randomness would have to be supplied by each party.
+ However, there is probably some correlation between their random
+ inputs so it is probably best to assume that each party needs to
+
+
+
+Eastlake, Crocker & Schiller [Page 26]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ provide at least 96 bits worth of randomness for very high security
+ if Diffie-Hellman is used.
+
+ This amount of randomness is beyond the limit of that in the inputs
+ recommended by the US DoD for password generation and could require
+ user typing timing, hardware random number generation, or other
+ sources.
+
+ It should be noted that key length calculations such at those above
+ are controversial and depend on various assumptions about the
+ cryptographic algorithms in use. In some cases, a professional with
+ a deep knowledge of code breaking techniques and of the strength of
+ the algorithm in use could be satisfied with less than half of the
+ key size derived above.
+
+9. Conclusion
+
+ Generation of unguessable "random" secret quantities for security use
+ is an essential but difficult task.
+
+ We have shown that hardware techniques to produce such randomness
+ would be relatively simple. In particular, the volume and quality
+ would not need to be high and existing computer hardware, such as
+ disk drives, can be used. Computational techniques are available to
+ process low quality random quantities from multiple sources or a
+ larger quantity of such low quality input from one source and produce
+ a smaller quantity of higher quality, less predictable key material.
+ In the absence of hardware sources of randomness, a variety of user
+ and software sources can frequently be used instead with care;
+ however, most modern systems already have hardware, such as disk
+ drives or audio input, that could be used to produce high quality
+ randomness.
+
+ Once a sufficient quantity of high quality seed key material (a few
+ hundred bits) is available, strong computational techniques are
+ available to produce cryptographically strong sequences of
+ unpredicatable quantities from this seed material.
+
+10. Security Considerations
+
+ The entirety of this document concerns techniques and recommendations
+ for generating unguessable "random" quantities for use as passwords,
+ cryptographic keys, and similar security uses.
+
+
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 27]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+References
+
+ [ASYMMETRIC] - Secure Communications and Asymmetric Cryptosystems,
+ edited by Gustavus J. Simmons, AAAS Selected Symposium 69, Westview
+ Press, Inc.
+
+ [BBS] - A Simple Unpredictable Pseudo-Random Number Generator, SIAM
+ Journal on Computing, v. 15, n. 2, 1986, L. Blum, M. Blum, & M. Shub.
+
+ [BRILLINGER] - Time Series: Data Analysis and Theory, Holden-Day,
+ 1981, David Brillinger.
+
+ [CRC] - C.R.C. Standard Mathematical Tables, Chemical Rubber
+ Publishing Company.
+
+ [CRYPTO1] - Cryptography: A Primer, A Wiley-Interscience Publication,
+ John Wiley & Sons, 1981, Alan G. Konheim.
+
+ [CRYPTO2] - Cryptography: A New Dimension in Computer Data Security,
+ A Wiley-Interscience Publication, John Wiley & Sons, 1982, Carl H.
+ Meyer & Stephen M. Matyas.
+
+ [CRYPTO3] - Applied Cryptography: Protocols, Algorithms, and Source
+ Code in C, John Wiley & Sons, 1994, Bruce Schneier.
+
+ [DAVIS] - Cryptographic Randomness from Air Turbulence in Disk
+ Drives, Advances in Cryptology - Crypto '94, Springer-Verlag Lecture
+ Notes in Computer Science #839, 1984, Don Davis, Ross Ihaka, and
+ Philip Fenstermacher.
+
+ [DES] - Data Encryption Standard, United States of America,
+ Department of Commerce, National Institute of Standards and
+ Technology, Federal Information Processing Standard (FIPS) 46-1.
+ - Data Encryption Algorithm, American National Standards Institute,
+ ANSI X3.92-1981.
+ (See also FIPS 112, Password Usage, which includes FORTRAN code for
+ performing DES.)
+
+ [DES MODES] - DES Modes of Operation, United States of America,
+ Department of Commerce, National Institute of Standards and
+ Technology, Federal Information Processing Standard (FIPS) 81.
+ - Data Encryption Algorithm - Modes of Operation, American National
+ Standards Institute, ANSI X3.106-1983.
+
+ [D-H] - New Directions in Cryptography, IEEE Transactions on
+ Information Technology, November, 1976, Whitfield Diffie and Martin
+ E. Hellman.
+
+
+
+
+Eastlake, Crocker & Schiller [Page 28]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ [DoD] - Password Management Guideline, United States of America,
+ Department of Defense, Computer Security Center, CSC-STD-002-85.
+ (See also FIPS 112, Password Usage, which incorporates CSC-STD-002-85
+ as one of its appendices.)
+
+ [GIFFORD] - Natural Random Number, MIT/LCS/TM-371, September 1988,
+ David K. Gifford
+
+ [KNUTH] - The Art of Computer Programming, Volume 2: Seminumerical
+ Algorithms, Chapter 3: Random Numbers. Addison Wesley Publishing
+ Company, Second Edition 1982, Donald E. Knuth.
+
+ [KRAWCZYK] - How to Predict Congruential Generators, Journal of
+ Algorithms, V. 13, N. 4, December 1992, H. Krawczyk
+
+ [MD2] - The MD2 Message-Digest Algorithm, RFC1319, April 1992, B.
+ Kaliski
+ [MD4] - The MD4 Message-Digest Algorithm, RFC1320, April 1992, R.
+ Rivest
+ [MD5] - The MD5 Message-Digest Algorithm, RFC1321, April 1992, R.
+ Rivest
+
+ [PEM] - RFCs 1421 through 1424:
+ - RFC 1424, Privacy Enhancement for Internet Electronic Mail: Part
+ IV: Key Certification and Related Services, 02/10/1993, B. Kaliski
+ - RFC 1423, Privacy Enhancement for Internet Electronic Mail: Part
+ III: Algorithms, Modes, and Identifiers, 02/10/1993, D. Balenson
+ - RFC 1422, Privacy Enhancement for Internet Electronic Mail: Part
+ II: Certificate-Based Key Management, 02/10/1993, S. Kent
+ - RFC 1421, Privacy Enhancement for Internet Electronic Mail: Part I:
+ Message Encryption and Authentication Procedures, 02/10/1993, J. Linn
+
+ [SHANNON] - The Mathematical Theory of Communication, University of
+ Illinois Press, 1963, Claude E. Shannon. (originally from: Bell
+ System Technical Journal, July and October 1948)
+
+ [SHIFT1] - Shift Register Sequences, Aegean Park Press, Revised
+ Edition 1982, Solomon W. Golomb.
+
+ [SHIFT2] - Cryptanalysis of Shift-Register Generated Stream Cypher
+ Systems, Aegean Park Press, 1984, Wayne G. Barker.
+
+ [SHS] - Secure Hash Standard, United States of American, National
+ Institute of Science and Technology, Federal Information Processing
+ Standard (FIPS) 180, April 1993.
+
+ [STERN] - Secret Linear Congruential Generators are not
+ Cryptograhically Secure, Proceedings of IEEE STOC, 1987, J. Stern.
+
+
+
+Eastlake, Crocker & Schiller [Page 29]
+
+RFC 1750 Randomness Recommendations for Security December 1994
+
+
+ [VON NEUMANN] - Various techniques used in connection with random
+ digits, von Neumann's Collected Works, Vol. 5, Pergamon Press, 1963,
+ J. von Neumann.
+
+Authors' Addresses
+
+ Donald E. Eastlake 3rd
+ Digital Equipment Corporation
+ 550 King Street, LKG2-1/BB3
+ Littleton, MA 01460
+
+ Phone: +1 508 486 6577(w) +1 508 287 4877(h)
+ EMail: dee@lkg.dec.com
+
+
+ Stephen D. Crocker
+ CyberCash Inc.
+ 2086 Hunters Crest Way
+ Vienna, VA 22181
+
+ Phone: +1 703-620-1222(w) +1 703-391-2651 (fax)
+ EMail: crocker@cybercash.com
+
+
+ Jeffrey I. Schiller
+ Massachusetts Institute of Technology
+ 77 Massachusetts Avenue
+ Cambridge, MA 02139
+
+ Phone: +1 617 253 0161(w)
+ EMail: jis@mit.edu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eastlake, Crocker & Schiller [Page 30]
+
diff --git a/crypto/heimdal/doc/standardisation/rfc1831.txt b/crypto/heimdal/doc/standardisation/rfc1831.txt
new file mode 100644
index 000000000000..0556c9e83f3b
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/rfc1831.txt
@@ -0,0 +1,1011 @@
+
+
+
+
+
+
+Network Working Group R. Srinivasan
+Request for Comments: 1831 Sun Microsystems
+Category: Standards Track August 1995
+
+
+ RPC: Remote Procedure Call Protocol Specification Version 2
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+ABSTRACT
+
+ This document describes the ONC Remote Procedure Call (ONC RPC
+ Version 2) protocol as it is currently deployed and accepted. "ONC"
+ stands for "Open Network Computing".
+
+TABLE OF CONTENTS
+
+ 1. INTRODUCTION 2
+ 2. TERMINOLOGY 2
+ 3. THE RPC MODEL 2
+ 4. TRANSPORTS AND SEMANTICS 4
+ 5. BINDING AND RENDEZVOUS INDEPENDENCE 5
+ 6. AUTHENTICATION 5
+ 7. RPC PROTOCOL REQUIREMENTS 5
+ 7.1 RPC Programs and Procedures 6
+ 7.2 Authentication 7
+ 7.3 Program Number Assignment 8
+ 7.4 Other Uses of the RPC Protocol 8
+ 7.4.1 Batching 8
+ 7.4.2 Broadcast Remote Procedure Calls 8
+ 8. THE RPC MESSAGE PROTOCOL 9
+ 9. AUTHENTICATION PROTOCOLS 12
+ 9.1 Null Authentication 13
+ 10. RECORD MARKING STANDARD 13
+ 11. THE RPC LANGUAGE 13
+ 11.1 An Example Service Described in the RPC Language 13
+ 11.2 The RPC Language Specification 14
+ 11.3 Syntax Notes 15
+ APPENDIX A: SYSTEM AUTHENTICATION 16
+ REFERENCES 17
+ Security Considerations 18
+ Author's Address 18
+
+
+
+Srinivasan Standards Track [Page 1]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+1. INTRODUCTION
+
+ This document specifies version two of the message protocol used in
+ ONC Remote Procedure Call (RPC). The message protocol is specified
+ with the eXternal Data Representation (XDR) language [9]. This
+ document assumes that the reader is familiar with XDR. It does not
+ attempt to justify remote procedure calls systems or describe their
+ use. The paper by Birrell and Nelson [1] is recommended as an
+ excellent background for the remote procedure call concept.
+
+2. TERMINOLOGY
+
+ This document discusses clients, calls, servers, replies, services,
+ programs, procedures, and versions. Each remote procedure call has
+ two sides: an active client side that makes the call to a server,
+ which sends back a reply. A network service is a collection of one
+ or more remote programs. A remote program implements one or more
+ remote procedures; the procedures, their parameters, and results are
+ documented in the specific program's protocol specification. A
+ server may support more than one version of a remote program in order
+ to be compatible with changing protocols.
+
+ For example, a network file service may be composed of two programs.
+ One program may deal with high-level applications such as file system
+ access control and locking. The other may deal with low-level file
+ input and output and have procedures like "read" and "write". A
+ client of the network file service would call the procedures
+ associated with the two programs of the service on behalf of the
+ client.
+
+ The terms client and server only apply to a particular transaction; a
+ particular hardware entity (host) or software entity (process or
+ program) could operate in both roles at different times. For
+ example, a program that supplies remote execution service could also
+ be a client of a network file service.
+
+3. THE RPC MODEL
+
+ The ONC RPC protocol is based on the remote procedure call model,
+ which is similar to the local procedure call model. In the local
+ case, the caller places arguments to a procedure in some well-
+ specified location (such as a register window). It then transfers
+ control to the procedure, and eventually regains control. At that
+ point, the results of the procedure are extracted from the well-
+ specified location, and the caller continues execution.
+
+
+
+
+
+
+Srinivasan Standards Track [Page 2]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+ The remote procedure call model is similar. One thread of control
+ logically winds through two processes: the caller's process, and a
+ server's process. The caller process first sends a call message to
+ the server process and waits (blocks) for a reply message. The call
+ message includes the procedure's parameters, and the reply message
+ includes the procedure's results. Once the reply message is
+ received, the results of the procedure are extracted, and caller's
+ execution is resumed.
+
+ On the server side, a process is dormant awaiting the arrival of a
+ call message. When one arrives, the server process extracts the
+ procedure's parameters, computes the results, sends a reply message,
+ and then awaits the next call message.
+
+ In this model, only one of the two processes is active at any given
+ time. However, this model is only given as an example. The ONC RPC
+ protocol makes no restrictions on the concurrency model implemented,
+ and others are possible. For example, an implementation may choose
+ to have RPC calls be asynchronous, so that the client may do useful
+ work while waiting for the reply from the server. Another
+ possibility is to have the server create a separate task to process
+ an incoming call, so that the original server can be free to receive
+ other requests.
+
+ There are a few important ways in which remote procedure calls differ
+ from local procedure calls:
+
+ 1. Error handling: failures of the remote server or network must
+ be handled when using remote procedure calls.
+
+ 2. Global variables and side-effects: since the server does not
+ have access to the client's address space, hidden arguments cannot
+ be passed as global variables or returned as side effects.
+
+ 3. Performance: remote procedures usually operate one or more
+ orders of magnitude slower than local procedure calls.
+
+ 4. Authentication: since remote procedure calls can be transported
+ over unsecured networks, authentication may be necessary.
+ Authentication prevents one entity from masquerading as some other
+ entity.
+
+ The conclusion is that even though there are tools to automatically
+ generate client and server libraries for a given service, protocols
+ must still be designed carefully.
+
+
+
+
+
+
+Srinivasan Standards Track [Page 3]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+4. TRANSPORTS AND SEMANTICS
+
+ The RPC protocol can be implemented on several different transport
+ protocols. The RPC protocol does not care how a message is passed
+ from one process to another, but only with specification and
+ interpretation of messages. However, the application may wish to
+ obtain information about (and perhaps control over) the transport
+ layer through an interface not specified in this document. For
+ example, the transport protocol may impose a restriction on the
+ maximum size of RPC messages, or it may be stream-oriented like TCP
+ with no size limit. The client and server must agree on their
+ transport protocol choices.
+
+ It is important to point out that RPC does not try to implement any
+ kind of reliability and that the application may need to be aware of
+ the type of transport protocol underneath RPC. If it knows it is
+ running on top of a reliable transport such as TCP [6], then most of
+ the work is already done for it. On the other hand, if it is running
+ on top of an unreliable transport such as UDP [7], it must implement
+ its own time-out, retransmission, and duplicate detection policies as
+ the RPC protocol does not provide these services.
+
+ Because of transport independence, the RPC protocol does not attach
+ specific semantics to the remote procedures or their execution
+ requirements. Semantics can be inferred from (but should be
+ explicitly specified by) the underlying transport protocol. For
+ example, consider RPC running on top of an unreliable transport such
+ as UDP. If an application retransmits RPC call messages after time-
+ outs, and does not receive a reply, it cannot infer anything about
+ the number of times the procedure was executed. If it does receive a
+ reply, then it can infer that the procedure was executed at least
+ once.
+
+ A server may wish to remember previously granted requests from a
+ client and not regrant them in order to insure some degree of
+ execute-at-most-once semantics. A server can do this by taking
+ advantage of the transaction ID that is packaged with every RPC
+ message. The main use of this transaction ID is by the client RPC
+ entity in matching replies to calls. However, a client application
+ may choose to reuse its previous transaction ID when retransmitting a
+ call. The server may choose to remember this ID after executing a
+ call and not execute calls with the same ID in order to achieve some
+ degree of execute-at-most-once semantics. The server is not allowed
+ to examine this ID in any other way except as a test for equality.
+
+ On the other hand, if using a "reliable" transport such as TCP, the
+ application can infer from a reply message that the procedure was
+ executed exactly once, but if it receives no reply message, it cannot
+
+
+
+Srinivasan Standards Track [Page 4]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+ assume that the remote procedure was not executed. Note that even if
+ a connection-oriented protocol like TCP is used, an application still
+ needs time-outs and reconnection to handle server crashes.
+
+ There are other possibilities for transports besides datagram- or
+ connection-oriented protocols. For example, a request-reply protocol
+ such as VMTP [2] is perhaps a natural transport for RPC. ONC RPC
+ uses both TCP and UDP transport protocols. Section 10 (RECORD
+ MARKING STANDARD) describes the mechanism employed by ONC RPC to
+ utilize a connection-oriented, stream-oriented transport such as TCP.
+
+5. BINDING AND RENDEZVOUS INDEPENDENCE
+
+ The act of binding a particular client to a particular service and
+ transport parameters is NOT part of this RPC protocol specification.
+ This important and necessary function is left up to some higher-level
+ software.
+
+ Implementors could think of the RPC protocol as the jump-subroutine
+ instruction ("JSR") of a network; the loader (binder) makes JSR
+ useful, and the loader itself uses JSR to accomplish its task.
+ Likewise, the binding software makes RPC useful, possibly using RPC
+ to accomplish this task.
+
+6. AUTHENTICATION
+
+ The RPC protocol provides the fields necessary for a client to
+ identify itself to a service, and vice-versa, in each call and reply
+ message. Security and access control mechanisms can be built on top
+ of this message authentication. Several different authentication
+ protocols can be supported. A field in the RPC header indicates
+ which protocol is being used. More information on specific
+ authentication protocols is in section 9: "Authentication Protocols".
+
+7. RPC PROTOCOL REQUIREMENTS
+
+ The RPC protocol must provide for the following:
+
+ (1) Unique specification of a procedure to be called.
+ (2) Provisions for matching response messages to request messages.
+ (3) Provisions for authenticating the caller to service and
+ vice-versa.
+
+
+
+
+
+
+
+
+
+Srinivasan Standards Track [Page 5]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+ Besides these requirements, features that detect the following are
+ worth supporting because of protocol roll-over errors, implementation
+ bugs, user error, and network administration:
+
+ (1) RPC protocol mismatches.
+ (2) Remote program protocol version mismatches.
+ (3) Protocol errors (such as misspecification of a procedure's
+ parameters).
+ (4) Reasons why remote authentication failed.
+ (5) Any other reasons why the desired procedure was not called.
+
+7.1 RPC Programs and Procedures
+
+ The RPC call message has three unsigned integer fields -- remote
+ program number, remote program version number, and remote procedure
+ number -- which uniquely identify the procedure to be called.
+ Program numbers are administered by a central authority
+ (rpc@sun.com). Once implementors have a program number, they can
+ implement their remote program; the first implementation would most
+ likely have the version number 1. Because most new protocols evolve,
+ a version field of the call message identifies which version of the
+ protocol the caller is using. Version numbers enable support of both
+ old and new protocols through the same server process.
+
+ The procedure number identifies the procedure to be called. These
+ numbers are documented in the specific program's protocol
+ specification. For example, a file service's protocol specification
+ may state that its procedure number 5 is "read" and procedure number
+ 12 is "write".
+
+ Just as remote program protocols may change over several versions,
+ the actual RPC message protocol could also change. Therefore, the
+ call message also has in it the RPC version number, which is always
+ equal to two for the version of RPC described here.
+
+ The reply message to a request message has enough information to
+ distinguish the following error conditions:
+
+ (1) The remote implementation of RPC does not support protocol
+ version 2. The lowest and highest supported RPC version numbers
+ are returned.
+
+ (2) The remote program is not available on the remote system.
+
+ (3) The remote program does not support the requested version
+ number. The lowest and highest supported remote program version
+ numbers are returned.
+
+
+
+
+Srinivasan Standards Track [Page 6]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+ (4) The requested procedure number does not exist. (This is
+ usually a client side protocol or programming error.)
+
+ (5) The parameters to the remote procedure appear to be garbage
+ from the server's point of view. (Again, this is usually caused
+ by a disagreement about the protocol between client and service.)
+
+7.2 Authentication
+
+ Provisions for authentication of caller to service and vice-versa are
+ provided as a part of the RPC protocol. The call message has two
+ authentication fields, the credential and verifier. The reply
+ message has one authentication field, the response verifier. The RPC
+ protocol specification defines all three fields to be the following
+ opaque type (in the eXternal Data Representation (XDR) language [9]):
+
+ enum auth_flavor {
+ AUTH_NONE = 0,
+ AUTH_SYS = 1,
+ AUTH_SHORT = 2
+ /* and more to be defined */
+ };
+
+ struct opaque_auth {
+ auth_flavor flavor;
+ opaque body<400>;
+ };
+
+ In other words, any "opaque_auth" structure is an "auth_flavor"
+ enumeration followed by up to 400 bytes which are opaque to
+ (uninterpreted by) the RPC protocol implementation.
+
+ The interpretation and semantics of the data contained within the
+ authentication fields is specified by individual, independent
+ authentication protocol specifications. (Section 9 defines the
+ various authentication protocols.)
+
+ If authentication parameters were rejected, the reply message
+ contains information stating why they were rejected.
+
+
+
+
+
+
+
+
+
+
+
+
+Srinivasan Standards Track [Page 7]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+7.3 Program Number Assignment
+
+ Program numbers are given out in groups of hexadecimal 20000000
+ (decimal 536870912) according to the following chart:
+
+ 0 - 1fffffff defined by rpc@sun.com
+ 20000000 - 3fffffff defined by user
+ 40000000 - 5fffffff transient
+ 60000000 - 7fffffff reserved
+ 80000000 - 9fffffff reserved
+ a0000000 - bfffffff reserved
+ c0000000 - dfffffff reserved
+ e0000000 - ffffffff reserved
+
+ The first group is a range of numbers administered by rpc@sun.com and
+ should be identical for all sites. The second range is for
+ applications peculiar to a particular site. This range is intended
+ primarily for debugging new programs. When a site develops an
+ application that might be of general interest, that application
+ should be given an assigned number in the first range. Application
+ developers may apply for blocks of RPC program numbers in the first
+ range by sending electronic mail to "rpc@sun.com". The third group
+ is for applications that generate program numbers dynamically. The
+ final groups are reserved for future use, and should not be used.
+
+7.4 Other Uses of the RPC Protocol
+
+ The intended use of this protocol is for calling remote procedures.
+ Normally, each call message is matched with a reply message.
+ However, the protocol itself is a message-passing protocol with which
+ other (non-procedure call) protocols can be implemented.
+
+7.4.1 Batching
+
+ Batching is useful when a client wishes to send an arbitrarily large
+ sequence of call messages to a server. Batching typically uses
+ reliable byte stream protocols (like TCP) for its transport. In the
+ case of batching, the client never waits for a reply from the server,
+ and the server does not send replies to batch calls. A sequence of
+ batch calls is usually terminated by a legitimate remote procedure
+ call operation in order to flush the pipeline and get positive
+ acknowledgement.
+
+7.4.2 Broadcast Remote Procedure Calls
+
+ In broadcast protocols, the client sends a broadcast call to the
+ network and waits for numerous replies. This requires the use of
+ packet-based protocols (like UDP) as its transport protocol. Servers
+
+
+
+Srinivasan Standards Track [Page 8]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+ that support broadcast protocols usually respond only when the call
+ is successfully processed and are silent in the face of errors, but
+ this varies with the application.
+
+ The principles of broadcast RPC also apply to multicasting - an RPC
+ request can be sent to a multicast address.
+
+8. THE RPC MESSAGE PROTOCOL
+
+ This section defines the RPC message protocol in the XDR data
+ description language [9].
+
+ enum msg_type {
+ CALL = 0,
+ REPLY = 1
+ };
+
+ A reply to a call message can take on two forms: The message was
+ either accepted or rejected.
+
+ enum reply_stat {
+ MSG_ACCEPTED = 0,
+ MSG_DENIED = 1
+ };
+
+ Given that a call message was accepted, the following is the status
+ of an attempt to call a remote procedure.
+
+ enum accept_stat {
+ SUCCESS = 0, /* RPC executed successfully */
+ PROG_UNAVAIL = 1, /* remote hasn't exported program */
+ PROG_MISMATCH = 2, /* remote can't support version # */
+ PROC_UNAVAIL = 3, /* program can't support procedure */
+ GARBAGE_ARGS = 4, /* procedure can't decode params */
+ SYSTEM_ERR = 5 /* errors like memory allocation failure */
+ };
+
+ Reasons why a call message was rejected:
+
+ enum reject_stat {
+ RPC_MISMATCH = 0, /* RPC version number != 2 */
+ AUTH_ERROR = 1 /* remote can't authenticate caller */
+ };
+
+ Why authentication failed:
+
+ enum auth_stat {
+ AUTH_OK = 0, /* success */
+
+
+
+Srinivasan Standards Track [Page 9]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+ /*
+ * failed at remote end
+ */
+ AUTH_BADCRED = 1, /* bad credential (seal broken) */
+ AUTH_REJECTEDCRED = 2, /* client must begin new session */
+ AUTH_BADVERF = 3, /* bad verifier (seal broken) */
+ AUTH_REJECTEDVERF = 4, /* verifier expired or replayed */
+ AUTH_TOOWEAK = 5, /* rejected for security reasons */
+ /*
+ * failed locally
+ */
+ AUTH_INVALIDRESP = 6, /* bogus response verifier */
+ AUTH_FAILED = 7 /* reason unknown */
+ };
+
+ The RPC message:
+
+ All messages start with a transaction identifier, xid, followed by a
+ two-armed discriminated union. The union's discriminant is a
+ msg_type which switches to one of the two types of the message. The
+ xid of a REPLY message always matches that of the initiating CALL
+ message. NB: The xid field is only used for clients matching reply
+ messages with call messages or for servers detecting retransmissions;
+ the service side cannot treat this id as any type of sequence number.
+
+ struct rpc_msg {
+ unsigned int xid;
+ union switch (msg_type mtype) {
+ case CALL:
+ call_body cbody;
+ case REPLY:
+ reply_body rbody;
+ } body;
+ };
+
+ Body of an RPC call:
+
+ In version 2 of the RPC protocol specification, rpcvers must be equal
+ to 2. The fields prog, vers, and proc specify the remote program,
+ its version number, and the procedure within the remote program to be
+ called. After these fields are two authentication parameters: cred
+ (authentication credential) and verf (authentication verifier). The
+ two authentication parameters are followed by the parameters to the
+ remote procedure, which are specified by the specific program
+ protocol.
+
+ The purpose of the authentication verifier is to validate the
+ authentication credential. Note that these two items are
+
+
+
+Srinivasan Standards Track [Page 10]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+ historically separate, but are always used together as one logical
+ entity.
+
+ struct call_body {
+ unsigned int rpcvers; /* must be equal to two (2) */
+ unsigned int prog;
+ unsigned int vers;
+ unsigned int proc;
+ opaque_auth cred;
+ opaque_auth verf;
+ /* procedure specific parameters start here */
+ };
+
+ Body of a reply to an RPC call:
+
+ union reply_body switch (reply_stat stat) {
+ case MSG_ACCEPTED:
+ accepted_reply areply;
+ case MSG_DENIED:
+ rejected_reply rreply;
+ } reply;
+
+ Reply to an RPC call that was accepted by the server:
+
+ There could be an error even though the call was accepted. The first
+ field is an authentication verifier that the server generates in
+ order to validate itself to the client. It is followed by a union
+ whose discriminant is an enum accept_stat. The SUCCESS arm of the
+ union is protocol specific. The PROG_UNAVAIL, PROC_UNAVAIL,
+ GARBAGE_ARGS, and SYSTEM_ERR arms of the union are void. The
+ PROG_MISMATCH arm specifies the lowest and highest version numbers of
+ the remote program supported by the server.
+
+ struct accepted_reply {
+ opaque_auth verf;
+ union switch (accept_stat stat) {
+ case SUCCESS:
+ opaque results[0];
+ /*
+ * procedure-specific results start here
+ */
+ case PROG_MISMATCH:
+ struct {
+ unsigned int low;
+ unsigned int high;
+ } mismatch_info;
+ default:
+ /*
+
+
+
+Srinivasan Standards Track [Page 11]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+ * Void. Cases include PROG_UNAVAIL, PROC_UNAVAIL,
+ * GARBAGE_ARGS, and SYSTEM_ERR.
+ */
+ void;
+ } reply_data;
+ };
+
+ Reply to an RPC call that was rejected by the server:
+
+ The call can be rejected for two reasons: either the server is not
+ running a compatible version of the RPC protocol (RPC_MISMATCH), or
+ the server rejects the identity of the caller (AUTH_ERROR). In case
+ of an RPC version mismatch, the server returns the lowest and highest
+ supported RPC version numbers. In case of invalid authentication,
+ failure status is returned.
+
+ union rejected_reply switch (reject_stat stat) {
+ case RPC_MISMATCH:
+ struct {
+ unsigned int low;
+ unsigned int high;
+ } mismatch_info;
+ case AUTH_ERROR:
+ auth_stat stat;
+ };
+
+9. AUTHENTICATION PROTOCOLS
+
+ As previously stated, authentication parameters are opaque, but
+ open-ended to the rest of the RPC protocol. This section defines two
+ standard "flavors" of authentication. Implementors are free to
+ invent new authentication types, with the same rules of flavor number
+ assignment as there is for program number assignment. The "flavor"
+ of a credential or verifier refers to the value of the "flavor" field
+ in the opaque_auth structure. Flavor numbers, like RPC program
+ numbers, are also administered centrally, and developers may assign
+ new flavor numbers by applying through electronic mail to
+ "rpc@sun.com". Credentials and verifiers are represented as variable
+ length opaque data (the "body" field in the opaque_auth structure).
+
+ In this document, two flavors of authentication are described. Of
+ these, Null authentication (described in the next subsection) is
+ mandatory - it must be available in all implementations. System
+ authentication is described in Appendix A. It is strongly
+ recommended that implementors include System authentication in their
+ implementations. Many applications use this style of authentication,
+ and availability of this flavor in an implementation will enhance
+ interoperability.
+
+
+
+Srinivasan Standards Track [Page 12]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+9.1 Null Authentication
+
+ Often calls must be made where the client does not care about its
+ identity or the server does not care who the client is. In this
+ case, the flavor of the RPC message's credential, verifier, and reply
+ verifier is "AUTH_NONE". Opaque data associated with "AUTH_NONE" is
+ undefined. It is recommended that the length of the opaque data be
+ zero.
+
+10. RECORD MARKING STANDARD
+
+ When RPC messages are passed on top of a byte stream transport
+ protocol (like TCP), it is necessary to delimit one message from
+ another in order to detect and possibly recover from protocol errors.
+ This is called record marking (RM). One RPC message fits into one RM
+ record.
+
+ A record is composed of one or more record fragments. A record
+ fragment is a four-byte header followed by 0 to (2**31) - 1 bytes of
+ fragment data. The bytes encode an unsigned binary number; as with
+ XDR integers, the byte order is from highest to lowest. The number
+ encodes two values -- a boolean which indicates whether the fragment
+ is the last fragment of the record (bit value 1 implies the fragment
+ is the last fragment) and a 31-bit unsigned binary value which is the
+ length in bytes of the fragment's data. The boolean value is the
+ highest-order bit of the header; the length is the 31 low-order bits.
+ (Note that this record specification is NOT in XDR standard form!)
+
+11. THE RPC LANGUAGE
+
+ Just as there was a need to describe the XDR data-types in a formal
+ language, there is also need to describe the procedures that operate
+ on these XDR data-types in a formal language as well. The RPC
+ Language is an extension to the XDR language, with the addition of
+ "program", "procedure", and "version" declarations. The following
+ example is used to describe the essence of the language.
+
+11.1 An Example Service Described in the RPC Language
+
+ Here is an example of the specification of a simple ping program.
+
+ program PING_PROG {
+ /*
+ * Latest and greatest version
+ */
+ version PING_VERS_PINGBACK {
+ void
+ PINGPROC_NULL(void) = 0;
+
+
+
+Srinivasan Standards Track [Page 13]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+ /*
+ * Ping the client, return the round-trip time
+ * (in microseconds). Returns -1 if the operation
+ * timed out.
+ */
+ int
+ PINGPROC_PINGBACK(void) = 1;
+ } = 2;
+
+ /*
+ * Original version
+ */
+ version PING_VERS_ORIG {
+ void
+ PINGPROC_NULL(void) = 0;
+ } = 1;
+ } = 1;
+
+ const PING_VERS = 2; /* latest version */
+
+ The first version described is PING_VERS_PINGBACK with two
+ procedures, PINGPROC_NULL and PINGPROC_PINGBACK. PINGPROC_NULL takes
+ no arguments and returns no results, but it is useful for computing
+ round-trip times from the client to the server and back again. By
+ convention, procedure 0 of any RPC protocol should have the same
+ semantics, and never require any kind of authentication. The second
+ procedure is used for the client to have the server do a reverse ping
+ operation back to the client, and it returns the amount of time (in
+ microseconds) that the operation used. The next version,
+ PING_VERS_ORIG, is the original version of the protocol and it does
+ not contain PINGPROC_PINGBACK procedure. It is useful for
+ compatibility with old client programs, and as this program matures
+ it may be dropped from the protocol entirely.
+
+11.2 The RPC Language Specification
+
+ The RPC language is identical to the XDR language defined in RFC
+ 1014, except for the added definition of a "program-def" described
+ below.
+
+ program-def:
+ "program" identifier "{"
+ version-def
+ version-def *
+ "}" "=" constant ";"
+
+ version-def:
+ "version" identifier "{"
+
+
+
+Srinivasan Standards Track [Page 14]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+ procedure-def
+ procedure-def *
+ "}" "=" constant ";"
+
+ procedure-def:
+ type-specifier identifier "(" type-specifier
+ ("," type-specifier )* ")" "=" constant ";"
+
+11.3 Syntax Notes
+
+ (1) The following keywords are added and cannot be used as
+ identifiers: "program" and "version";
+
+ (2) A version name cannot occur more than once within the scope of a
+ program definition. Nor can a version number occur more than once
+ within the scope of a program definition.
+
+ (3) A procedure name cannot occur more than once within the scope of
+ a version definition. Nor can a procedure number occur more than once
+ within the scope of version definition.
+
+ (4) Program identifiers are in the same name space as constant and
+ type identifiers.
+
+ (5) Only unsigned constants can be assigned to programs, versions and
+ procedures.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Srinivasan Standards Track [Page 15]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+APPENDIX A: SYSTEM AUTHENTICATION
+
+ The client may wish to identify itself, for example, as it is
+ identified on a UNIX(tm) system. The flavor of the client credential
+ is "AUTH_SYS". The opaque data constituting the credential encodes
+ the following structure:
+
+ struct authsys_parms {
+ unsigned int stamp;
+ string machinename<255>;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int gids<16>;
+ };
+
+ The "stamp" is an arbitrary ID which the caller machine may generate.
+ The "machinename" is the name of the caller's machine (like
+ "krypton"). The "uid" is the caller's effective user ID. The "gid"
+ is the caller's effective group ID. The "gids" is a counted array of
+ groups which contain the caller as a member. The verifier
+ accompanying the credential should have "AUTH_NONE" flavor value
+ (defined above). Note this credential is only unique within a
+ particular domain of machine names, uids, and gids.
+
+ The flavor value of the verifier received in the reply message from
+ the server may be "AUTH_NONE" or "AUTH_SHORT". In the case of
+ "AUTH_SHORT", the bytes of the reply verifier's string encode an
+ opaque structure. This new opaque structure may now be passed to the
+ server instead of the original "AUTH_SYS" flavor credential. The
+ server may keep a cache which maps shorthand opaque structures
+ (passed back by way of an "AUTH_SHORT" style reply verifier) to the
+ original credentials of the caller. The caller can save network
+ bandwidth and server cpu cycles by using the shorthand credential.
+
+ The server may flush the shorthand opaque structure at any time. If
+ this happens, the remote procedure call message will be rejected due
+ to an authentication error. The reason for the failure will be
+ "AUTH_REJECTEDCRED". At this point, the client may wish to try the
+ original "AUTH_SYS" style of credential.
+
+ It should be noted that use of this flavor of authentication does not
+ guarantee any security for the users or providers of a service, in
+ itself. The authentication provided by this scheme can be considered
+ legitimate only when applications using this scheme and the network
+ can be secured externally, and privileged transport addresses are
+ used for the communicating end-points (an example of this is the use
+ of privileged TCP/UDP ports in Unix systems - note that not all
+ systems enforce privileged transport address mechanisms).
+
+
+
+Srinivasan Standards Track [Page 16]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+REFERENCES
+
+ [1] Birrell, A. D. & Nelson, B. J., "Implementing Remote Procedure
+ Calls", XEROX CSL-83-7, October 1983.
+
+ [2] Cheriton, D., "VMTP: Versatile Message Transaction Protocol",
+ Preliminary Version 0.3, Stanford University, January 1987.
+
+ [3] Diffie & Hellman, "New Directions in Cryptography", IEEE
+ Transactions on Information Theory IT-22, November 1976.
+
+ [4] Mills, D., "Network Time Protocol", RFC 1305, UDEL,
+ March 1992.
+
+ [5] National Bureau of Standards, "Data Encryption Standard",
+ Federal Information Processing Standards Publication 46, January
+ 1977.
+
+ [6] Postel, J., "Transmission Control Protocol - DARPA Internet
+ Program Protocol Specification", STD 7, RFC 793, USC/Information
+ Sciences Institute, September 1981.
+
+ [7] Postel, J., "User Datagram Protocol", STD 6, RFC 768,
+ USC/Information Sciences Institute, August 1980.
+
+ [8] Reynolds, J., and Postel, J., "Assigned Numbers", STD 2,
+ RFC 1700, USC/Information Sciences Institute, October 1994.
+
+ [9] Srinivasan, R., "XDR: External Data Representation Standard",
+ RFC 1832, Sun Microsystems, Inc., August 1995.
+
+ [10] Miller, S., Neuman, C., Schiller, J., and J. Saltzer, "Section
+ E.2.1: Kerberos Authentication and Authorization System",
+ M.I.T. Project Athena, Cambridge, Massachusetts, December 21,
+ 1987.
+
+ [11] Steiner, J., Neuman, C., and J. Schiller, "Kerberos: An
+ Authentication Service for Open Network Systems", pp. 191-202 in
+ Usenix Conference Proceedings, Dallas, Texas, February 1988.
+
+ [12] Kohl, J. and C. Neuman, "The Kerberos Network Authentication
+ Service (V5)", RFC 1510, Digital Equipment Corporation,
+ USC/Information Sciences Institute, September 1993.
+
+
+
+
+
+
+
+
+Srinivasan Standards Track [Page 17]
+
+RFC 1831 Remote Procedure Call Protocol Version 2 August 1995
+
+
+Security Considerations
+
+ Security issues are not discussed in this memo.
+
+Author's Address
+
+ Raj Srinivasan
+ Sun Microsystems, Inc.
+ ONC Technologies
+ 2550 Garcia Avenue
+ M/S MTV-5-40
+ Mountain View, CA 94043
+ USA
+
+ Phone: 415-336-2478
+ Fax: 415-336-6015
+ EMail: raj@eng.sun.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Srinivasan Standards Track [Page 18]
+
diff --git a/crypto/heimdal/doc/standardisation/rfc1964.txt b/crypto/heimdal/doc/standardisation/rfc1964.txt
new file mode 100644
index 000000000000..f2960b961dd6
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/rfc1964.txt
@@ -0,0 +1,1123 @@
+
+
+
+
+
+
+Network Working Group J. Linn
+Request for Comments: 1964 OpenVision Technologies
+Category: Standards Track June 1996
+
+
+ The Kerberos Version 5 GSS-API Mechanism
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+ABSTRACT
+
+ This specification defines protocols, procedures, and conventions to
+ be employed by peers implementing the Generic Security Service
+ Application Program Interface (as specified in RFCs 1508 and 1509)
+ when using Kerberos Version 5 technology (as specified in RFC 1510).
+
+ACKNOWLEDGMENTS
+
+ Much of the material in this memo is based on working documents
+ drafted by John Wray of Digital Equipment Corporation and on
+ discussions, implementation activities, and interoperability testing
+ involving Marc Horowitz, Ted Ts'o, and John Wray. Particular thanks
+ are due to each of these individuals for their contributions towards
+ development and availability of GSS-API support within the Kerberos
+ Version 5 code base.
+
+1. Token Formats
+
+ This section discusses protocol-visible characteristics of the GSS-
+ API mechanism to be implemented atop Kerberos V5 security technology
+ per RFC-1508 and RFC-1510; it defines elements of protocol for
+ interoperability and is independent of language bindings per RFC-
+ 1509.
+
+ Tokens transferred between GSS-API peers (for security context
+ management and per-message protection purposes) are defined. The
+ data elements exchanged between a GSS-API endpoint implementation and
+ the Kerberos KDC are not specific to GSS-API usage and are therefore
+ defined within RFC-1510 rather than within this specification.
+
+
+
+
+
+
+Linn Standards Track [Page 1]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ To support ongoing experimentation, testing, and evolution of the
+ specification, the Kerberos V5 GSS-API mechanism as defined in this
+ and any successor memos will be identified with the following Object
+ Identifier, as defined in RFC-1510, until the specification is
+ advanced to the level of Proposed Standard RFC:
+
+ {iso(1), org(3), dod(5), internet(1), security(5), kerberosv5(2)}
+
+ Upon advancement to the level of Proposed Standard RFC, the Kerberos
+ V5 GSS-API mechanism will be identified by an Object Identifier
+ having the value:
+
+ {iso(1) member-body(2) United States(840) mit(113554) infosys(1)
+ gssapi(2) krb5(2)}
+
+1.1. Context Establishment Tokens
+
+ Per RFC-1508, Appendix B, the initial context establishment token
+ will be enclosed within framing as follows:
+
+ InitialContextToken ::=
+ [APPLICATION 0] IMPLICIT SEQUENCE {
+ thisMech MechType
+ -- MechType is OBJECT IDENTIFIER
+ -- representing "Kerberos V5"
+ innerContextToken ANY DEFINED BY thisMech
+ -- contents mechanism-specific;
+ -- ASN.1 usage within innerContextToken
+ -- is not required
+ }
+
+ The innerContextToken of the initial context token will consist of a
+ Kerberos V5 KRB_AP_REQ message, preceded by a two-byte token-id
+ (TOK_ID) field, which shall contain the value 01 00.
+
+ The above GSS-API framing shall be applied to all tokens emitted by
+ the Kerberos V5 GSS-API mechanism, including KRB_AP_REP, KRB_ERROR,
+ context-deletion, and per-message tokens, not just to the initial
+ token in a context establishment sequence. While not required by
+ RFC-1508, this enables implementations to perform enhanced error-
+ checking. The innerContextToken field of context establishment tokens
+ for the Kerberos V5 GSS-API mechanism will contain a Kerberos message
+ (KRB_AP_REQ, KRB_AP_REP or KRB_ERROR), preceded by a 2-byte TOK_ID
+ field containing 01 00 for KRB_AP_REQ messages, 02 00 for KRB_AP_REP
+ messages and 03 00 for KRB_ERROR messages.
+
+
+
+
+
+
+Linn Standards Track [Page 2]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+1.1.1. Initial Token
+
+ Relevant KRB_AP_REQ syntax (from RFC-1510) is as follows:
+
+ AP-REQ ::= [APPLICATION 14] SEQUENCE {
+ pvno [0] INTEGER, -- indicates Version 5
+ msg-type [1] INTEGER, -- indicates KRB_AP_REQ
+ ap-options[2] APOptions,
+ ticket[3] Ticket,
+ authenticator[4] EncryptedData
+ }
+
+ APOptions ::= BIT STRING {
+ reserved (0),
+ use-session-key (1),
+ mutual-required (2)
+ }
+
+ Ticket ::= [APPLICATION 1] SEQUENCE {
+ tkt-vno [0] INTEGER, -- indicates Version 5
+ realm [1] Realm,
+ sname [2] PrincipalName,
+ enc-part [3] EncryptedData
+ }
+
+ -- Encrypted part of ticket
+ EncTicketPart ::= [APPLICATION 3] SEQUENCE {
+ flags[0] TicketFlags,
+ key[1] EncryptionKey,
+ crealm[2] Realm,
+ cname[3] PrincipalName,
+ transited[4] TransitedEncoding,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ caddr[9] HostAddresses OPTIONAL,
+ authorization-data[10] AuthorizationData OPTIONAL
+ }
+
+ -- Unencrypted authenticator
+ Authenticator ::= [APPLICATION 2] SEQUENCE {
+ authenticator-vno[0] INTEGER,
+ crealm[1] Realm,
+ cname[2] PrincipalName,
+ cksum[3] Checksum OPTIONAL,
+ cusec[4] INTEGER,
+ ctime[5] KerberosTime,
+
+
+
+Linn Standards Track [Page 3]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ subkey[6] EncryptionKey OPTIONAL,
+ seq-number[7] INTEGER OPTIONAL,
+ authorization-data[8] AuthorizationData OPTIONAL
+ }
+
+ For purposes of this specification, the authenticator shall include
+ the optional sequence number, and the checksum field shall be used to
+ convey channel binding, service flags, and optional delegation
+ information. The checksum will have a type of 0x8003 (a value being
+ registered within the Kerberos protocol specification), and a value
+ field of at least 24 bytes in length. The length of the value field
+ is extended beyond 24 bytes if and only if an optional facility to
+ carry a Kerberos-defined KRB_CRED message for delegation purposes is
+ supported by an implementation and active on a context. When
+ delegation is active, a TGT with its FORWARDABLE flag set will be
+ transferred within the KRB_CRED message.
+
+ The checksum value field's format is as follows:
+
+ Byte Name Description
+ 0..3 Lgth Number of bytes in Bnd field;
+ Currently contains hex 10 00 00 00
+ (16, represented in little-endian form)
+ 4..19 Bnd MD5 hash of channel bindings, taken over all non-null
+ components of bindings, in order of declaration.
+ Integer fields within channel bindings are represented
+ in little-endian order for the purposes of the MD5
+ calculation.
+ 20..23 Flags Bit vector of context-establishment flags,
+ with values consistent with RFC-1509, p. 41:
+ GSS_C_DELEG_FLAG: 1
+ GSS_C_MUTUAL_FLAG: 2
+ GSS_C_REPLAY_FLAG: 4
+ GSS_C_SEQUENCE_FLAG: 8
+ GSS_C_CONF_FLAG: 16
+ GSS_C_INTEG_FLAG: 32
+ The resulting bit vector is encoded into bytes 20..23
+ in little-endian form.
+ 24..25 DlgOpt The Delegation Option identifier (=1) [optional]
+ 26..27 Dlgth The length of the Deleg field. [optional]
+ 28..n Deleg A KRB_CRED message (n = Dlgth + 29) [optional]
+
+ In computing the contents of the "Bnd" field, the following detailed
+ points apply:
+
+ (1) Each integer field shall be formatted into four bytes, using
+ little-endian byte ordering, for purposes of MD5 hash
+ computation.
+
+
+
+Linn Standards Track [Page 4]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ (2) All input length fields within gss_buffer_desc elements of a
+ gss_channel_bindings_struct, even those which are zero-valued,
+ shall be included in the hash calculation; the value elements of
+ gss_buffer_desc elements shall be dereferenced, and the
+ resulting data shall be included within the hash computation,
+ only for the case of gss_buffer_desc elements having non-zero
+ length specifiers.
+
+ (3) If the caller passes the value GSS_C_NO_BINDINGS instead of
+ a valid channel bindings structure, the Bnd field shall be set
+ to 16 zero-valued bytes.
+
+ In the initial Kerberos V5 GSS-API mechanism token (KRB_AP_REQ token)
+ from initiator to target, the GSS_C_DELEG_FLAG, GSS_C_MUTUAL_FLAG,
+ GSS_C_REPLAY_FLAG, and GSS_C_SEQUENCE_FLAG values shall each be set
+ as the logical AND of the initiator's corresponding request flag to
+ GSS_Init_sec_context() and a Boolean indicator of whether that
+ optional service is available to GSS_Init_sec_context()'s caller.
+ GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG, for which no corresponding
+ context-level input indicator flags to GSS_Init_sec_context() exist,
+ shall each be set to indicate whether their respective per-message
+ protection services are available for use on the context being
+ established.
+
+ When input source address channel binding values are provided by a
+ caller (i.e., unless the input argument is GSS_C_NO_BINDINGS or the
+ source address specifier value within the input structure is
+ GSS_C_NULL_ADDRTYPE), and the corresponding token received from the
+ context's peer bears address restrictions, it is recommended that an
+ implementation of the Kerberos V5 GSS-API mechanism should check that
+ the source address as provided by the caller matches that in the
+ received token, and should return the GSS_S_BAD_BINDINGS major_status
+ value if a mismatch is detected. Note: discussion is ongoing about
+ the strength of recommendation to be made in this area, and on the
+ circumstances under which such a recommendation should be applicable;
+ implementors are therefore advised that changes on this matter may be
+ included in subsequent versions of this specification.
+
+1.1.2. Response Tokens
+
+ A context establishment sequence based on the Kerberos V5 mechanism
+ will perform one-way authentication (without confirmation or any
+ return token from target to initiator in response to the initiator's
+ KRB_AP_REQ) if the mutual_req bit is not set in the application's
+ call to GSS_Init_sec_context(). Applications requiring confirmation
+ that their authentication was successful should request mutual
+ authentication, resulting in a "mutual-required" indication within
+ KRB_AP_REQ APoptions and the setting of the mutual_req bit in the
+
+
+
+Linn Standards Track [Page 5]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ flags field of the authenticator checksum. In response to such a
+ request, the context target will reply to the initiator with a token
+ containing either a KRB_AP_REP or KRB_ERROR, completing the mutual
+ context establishment exchange.
+
+ Relevant KRB_AP_REP syntax is as follows:
+
+ AP-REP ::= [APPLICATION 15] SEQUENCE {
+ pvno [0] INTEGER, -- represents Kerberos V5
+ msg-type [1] INTEGER, -- represents KRB_AP_REP
+ enc-part [2] EncryptedData
+ }
+
+ EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
+ ctime [0] KerberosTime,
+ cusec [1] INTEGER,
+ subkey [2] EncryptionKey OPTIONAL,
+ seq-number [3] INTEGER OPTIONAL
+ }
+
+ The optional seq-number element within the AP-REP's EncAPRepPart
+ shall be included.
+
+ The syntax of KRB_ERROR is as follows:
+
+ KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ctime[2] KerberosTime OPTIONAL,
+ cusec[3] INTEGER OPTIONAL,
+ stime[4] KerberosTime,
+ susec[5] INTEGER,
+ error-code[6] INTEGER,
+ crealm[7] Realm OPTIONAL,
+ cname[8] PrincipalName OPTIONAL,
+ realm[9] Realm, -- Correct realm
+ sname[10] PrincipalName, -- Correct name
+ e-text[11] GeneralString OPTIONAL,
+ e-data[12] OCTET STRING OPTIONAL
+ }
+
+ Values to be transferred in the error-code field of a KRB-ERROR
+ message are defined in [RFC-1510], not in this specification.
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 6]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+1.2. Per-Message and Context Deletion Tokens
+
+ Three classes of tokens are defined in this section: "MIC" tokens,
+ emitted by calls to GSS_GetMIC() (formerly GSS_Sign()) and consumed
+ by calls to GSS_VerifyMIC() (formerly GSS_Verify()), "Wrap" tokens,
+ emitted by calls to GSS_Wrap() (formerly GSS_Seal()) and consumed by
+ calls to GSS_Unwrap() (formerly GSS_Unseal()), and context deletion
+ tokens, emitted by calls to GSS_Delete_sec_context() and consumed by
+ calls to GSS_Process_context_token(). Note: References to GSS-API
+ per-message routines in the remainder of this specification will be
+ based on those routines' newer recommended names rather than those
+ names' predecessors.
+
+ Several variants of cryptographic keys are used in generation and
+ processing of per-message tokens:
+
+ (1) context key: uses Kerberos session key (or subkey, if
+ present in authenticator emitted by context initiator) directly
+
+ (2) confidentiality key: forms variant of context key by
+ exclusive-OR with the hexadecimal constant f0f0f0f0f0f0f0f0.
+
+ (3) MD2.5 seed key: forms variant of context key by reversing
+ the bytes of the context key (i.e. if the original key is the
+ 8-byte sequence {aa, bb, cc, dd, ee, ff, gg, hh}, the seed key
+ will be {hh, gg, ff, ee, dd, cc, bb, aa}).
+
+1.2.1. Per-message Tokens - MIC
+
+Use of the GSS_GetMIC() call yields a token, separate from the user
+data being protected, which can be used to verify the integrity of
+that data as received. The token has the following format:
+
+ Byte no Name Description
+ 0..1 TOK_ID Identification field.
+ Tokens emitted by GSS_GetMIC() contain
+ the hex value 01 01 in this field.
+ 2..3 SGN_ALG Integrity algorithm indicator.
+ 00 00 - DES MAC MD5
+ 01 00 - MD2.5
+ 02 00 - DES MAC
+ 4..7 Filler Contains ff ff ff ff
+ 8..15 SND_SEQ Sequence number field.
+ 16..23 SGN_CKSUM Checksum of "to-be-signed data",
+ calculated according to algorithm
+ specified in SGN_ALG field.
+
+
+
+
+
+Linn Standards Track [Page 7]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ GSS-API tokens must be encapsulated within the higher-level protocol
+ by the application; no embedded length field is necessary.
+
+1.2.1.1. Checksum
+
+ Checksum calculation procedure (common to all algorithms): Checksums
+ are calculated over the data field, logically prepended by the first
+ 8 bytes of the plaintext packet header. The resulting value binds
+ the data to the packet type and signature algorithm identifier
+ fields.
+
+ DES MAC MD5 algorithm: The checksum is formed by computing an MD5
+ [RFC-1321] hash over the plaintext data, and then computing a DES-CBC
+ MAC on the 16-byte MD5 result. A standard 64-bit DES-CBC MAC is
+ computed per [FIPS-PUB-113], employing the context key and a zero IV.
+ The 8-byte result is stored in the SGN_CKSUM field.
+
+ MD2.5 algorithm: The checksum is formed by first DES-CBC encrypting a
+ 16-byte zero-block, using a zero IV and a key formed by reversing the
+ bytes of the context key (i.e. if the original key is the 8-byte
+ sequence {aa, bb, cc, dd, ee, ff, gg, hh}, the checksum key will be
+ {hh, gg, ff, ee, dd, cc, bb, aa}). The resulting 16-byte value is
+ logically prepended to the to-be-signed data. A standard MD5
+ checksum is calculated over the combined data, and the first 8 bytes
+ of the result are stored in the SGN_CKSUM field. Note 1: we refer to
+ this algorithm informally as "MD2.5" to connote the fact that it uses
+ half of the 128 bits generated by MD5; use of only a subset of the
+ MD5 bits is intended to protect against the prospect that data could
+ be postfixed to an existing message with corresponding modifications
+ being made to the checksum. Note 2: This algorithm is fairly novel
+ and has received more limited evaluation than that to which other
+ integrity algorithms have been subjected. An initial, limited
+ evaluation indicates that it may be significantly weaker than DES MAC
+ MD5.
+
+ DES-MAC algorithm: A standard 64-bit DES-CBC MAC is computed on the
+ plaintext data per [FIPS-PUB-113], employing the context key and a
+ zero IV. Padding procedures to accomodate plaintext data lengths
+ which may not be integral multiples of 8 bytes are defined in [FIPS-
+ PUB-113]. The result is an 8-byte value, which is stored in the
+ SGN_CKSUM field. Support for this algorithm may not be present in
+ all implementations.
+
+1.2.1.2. Sequence Number
+
+ Sequence number field: The 8 byte plaintext sequence number field is
+ formed from the sender's four-byte sequence number as follows. If
+ the four bytes of the sender's sequence number are named s0, s1, s2
+
+
+
+Linn Standards Track [Page 8]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ and s3 (from least to most significant), the plaintext sequence
+ number field is the 8 byte sequence: (s0, s1, s2, s3, di, di, di,
+ di), where 'di' is the direction-indicator (Hex 0 - sender is the
+ context initiator, Hex FF - sender is the context acceptor). The
+ field is then DES-CBC encrypted using the context key and an IV
+ formed from the first 8 bytes of the previously calculated SGN_CKSUM
+ field. After sending a GSS_GetMIC() or GSS_Wrap() token, the sender's
+ sequence number is incremented by one.
+
+ The receiver of the token will first verify the SGN_CKSUM field. If
+ valid, the sequence number field may be decrypted and compared to the
+ expected sequence number. The repetition of the (effectively 1-bit)
+ direction indicator within the sequence number field provides
+ redundancy so that the receiver may verify that the decryption
+ succeeded.
+
+ Since the checksum computation is used as an IV to the sequence
+ number decryption, attempts to splice a checksum and sequence number
+ from different messages will be detected. The direction indicator
+ will detect packets that have been maliciously reflected.
+
+ The sequence number provides a basis for detection of replayed
+ tokens. Replay detection can be performed using state information
+ retained on received sequence numbers, interpreted in conjunction
+ with the security context on which they arrive.
+
+ Provision of per-message replay and out-of-sequence detection
+ services is optional for implementations of the Kerberos V5 GSS-API
+ mechanism. Further, it is recommended that implementations of the
+ Kerberos V5 GSS-API mechanism which offer these services should honor
+ a caller's request that the services be disabled on a context.
+ Specifically, if replay_det_req_flag is input FALSE, replay_det_state
+ should be returned FALSE and the GSS_DUPLICATE_TOKEN and
+ GSS_OLD_TOKEN stati should not be indicated as a result of duplicate
+ detection when tokens are processed; if sequence_req_flag is input
+ FALSE, sequence_state should be returned FALSE and
+ GSS_DUPLICATE_TOKEN, GSS_OLD_TOKEN, and GSS_UNSEQ_TOKEN stati should
+ not be indicated as a result of out-of-sequence detection when tokens
+ are processed.
+
+1.2.2. Per-message Tokens - Wrap
+
+ Use of the GSS_Wrap() call yields a token which encapsulates the
+ input user data (optionally encrypted) along with associated
+ integrity check quantities. The token emitted by GSS_Wrap() consists
+ of an integrity header whose format is identical to that emitted by
+ GSS_GetMIC() (except that the TOK_ID field contains the value 02 01),
+ followed by a body portion that contains either the plaintext data
+
+
+
+Linn Standards Track [Page 9]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ (if SEAL_ALG = ff ff) or encrypted data for any other supported value
+ of SEAL_ALG. Currently, only SEAL_ALG = 00 00 is supported, and
+ means that DES-CBC encryption is being used to protect the data.
+
+ The GSS_Wrap() token has the following format:
+
+ Byte no Name Description
+ 0..1 TOK_ID Identification field.
+ Tokens emitted by GSS_Wrap() contain
+ the hex value 02 01 in this field.
+ 2..3 SGN_ALG Checksum algorithm indicator.
+ 00 00 - DES MAC MD5
+ 01 00 - MD2.5
+ 02 00 - DES MAC
+ 4..5 SEAL_ALG ff ff - none
+ 00 00 - DES
+ 6..7 Filler Contains ff ff
+ 8..15 SND_SEQ Encrypted sequence number field.
+ 16..23 SGN_CKSUM Checksum of plaintext padded data,
+ calculated according to algorithm
+ specified in SGN_ALG field.
+ 24..last Data encrypted or plaintext padded data
+
+ GSS-API tokens must be encapsulated within the higher-level protocol
+ by the application; no embedded length field is necessary.
+
+1.2.2.1. Checksum
+
+ Checksum calculation procedure (common to all algorithms): Checksums
+ are calculated over the plaintext padded data field, logically
+ prepended by the first 8 bytes of the plaintext packet header. The
+ resulting signature binds the data to the packet type, protocol
+ version, and signature algorithm identifier fields.
+
+ DES MAC MD5 algorithm: The checksum is formed by computing an MD5
+ hash over the plaintext padded data, and then computing a DES-CBC MAC
+ on the 16-byte MD5 result. A standard 64-bit DES-CBC MAC is computed
+ per [FIPS-PUB-113], employing the context key and a zero IV. The 8-
+ byte result is stored in the SGN_CKSUM field.
+
+ MD2.5 algorithm: The checksum is formed by first DES-CBC encrypting a
+ 16-byte zero-block, using a zero IV and a key formed by reversing the
+ bytes of the context key (i.e., if the original key is the 8-byte
+ sequence {aa, bb, cc, dd, ee, ff, gg, hh}, the checksum key will be
+ {hh, gg, ff, ee, dd, cc, bb, aa}). The resulting 16-byte value is
+ logically pre-pended to the "to-be-signed data". A standard MD5
+ checksum is calculated over the combined data, and the first 8 bytes
+ of the result are stored in the SGN_CKSUM field.
+
+
+
+Linn Standards Track [Page 10]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ DES-MAC algorithm: A standard 64-bit DES-CBC MAC is computed on the
+ plaintext padded data per [FIPS-PUB-113], employing the context key
+ and a zero IV. The plaintext padded data is already assured to be an
+ integral multiple of 8 bytes; no additional padding is required or
+ applied in order to accomplish MAC calculation. The result is an 8-
+ byte value, which is stored in the SGN_CKSUM field. Support for this
+ lgorithm may not be present in all implementations.
+
+1.2.2.2. Sequence Number
+
+ Sequence number field: The 8 byte plaintext sequence number field is
+ formed from the sender's four-byte sequence number as follows. If
+ the four bytes of the sender's sequence number are named s0, s1, s2
+ and s3 (from least to most significant), the plaintext sequence
+ number field is the 8 byte sequence: (s0, s1, s2, s3, di, di, di,
+ di), where 'di' is the direction-indicator (Hex 0 - sender is the
+ context initiator, Hex FF - sender is the context acceptor).
+
+ The field is then DES-CBC encrypted using the context key and an IV
+ formed from the first 8 bytes of the SEAL_CKSUM field.
+
+ After sending a GSS_GetMIC() or GSS_Wrap() token, the sender's
+ sequence numbers are incremented by one.
+
+1.2.2.3. Padding
+
+ Data padding: Before encryption and/or signature calculation,
+ plaintext data is padded to the next highest multiple of 8 bytes, by
+ appending between 1 and 8 bytes, the value of each such byte being
+ the total number of pad bytes. For example, given data of length 20
+ bytes, four pad bytes will be appended, and each byte will contain
+ the hex value 04. An 8-byte random confounder is prepended to the
+ data, and signatures are calculated over the resulting padded
+ plaintext.
+
+ After padding, the data is encrypted according to the algorithm
+ specified in the SEAL_ALG field. For SEAL_ALG=DES (the only non-null
+ algorithm currently supported), the data is encrypted using DES-CBC,
+ with an IV of zero. The key used is derived from the established
+ context key by XOR-ing the context key with the hexadecimal constant
+ f0f0f0f0f0f0f0f0.
+
+1.2.3. Context deletion token
+
+ The token emitted by GSS_Delete_sec_context() is based on the packet
+ format for tokens emitted by GSS_GetMIC(). The context-deletion
+ token has the following format:
+
+
+
+
+Linn Standards Track [Page 11]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ Byte no Name Description
+ 0..1 TOK_ID Identification field.
+ Tokens emitted by
+ GSS_Delete_sec_context() contain
+ the hex value 01 02 in this field.
+ 2..3 SGN_ALG Integrity algorithm indicator.
+ 00 00 - DES MAC MD5
+ 01 00 - MD2.5
+ 02 00 - DES MAC
+ 4..7 Filler Contains ff ff ff ff
+ 8..15 SND_SEQ Sequence number field.
+ 16..23 SGN_CKSUM Checksum of "to-be-signed data",
+ calculated according to algorithm
+ specified in SGN_ALG field.
+
+ SGN_ALG and SND_SEQ will be calculated as for tokens emitted by
+ GSS_GetMIC(). The SGN_CKSUM will be calculated as for tokens emitted
+ by GSS_GetMIC(), except that the user-data component of the "to-be-
+ signed" data will be a zero-length string.
+
+2. Name Types and Object Identifiers
+
+ This section discusses the name types which may be passed as input to
+ the Kerberos V5 GSS-API mechanism's GSS_Import_name() call, and their
+ associated identifier values. It defines interface elements in
+ support of portability, and assumes use of C language bindings per
+ RFC-1509. In addition to specifying OID values for name type
+ identifiers, symbolic names are included and recommended to GSS-API
+ implementors in the interests of convenience to callers. It is
+ understood that not all implementations of the Kerberos V5 GSS-API
+ mechanism need support all name types in this list, and that
+ additional name forms will likely be added to this list over time.
+ Further, the definitions of some or all name types may later migrate
+ to other, mechanism-independent, specifications. The occurrence of a
+ name type in this specification is specifically not intended to
+ suggest that the type may be supported only by an implementation of
+ the Kerberos V5 mechanism. In particular, the occurrence of the
+ string "_KRB5_" in the symbolic name strings constitutes a means to
+ unambiguously register the name strings, avoiding collision with
+ other documents; it is not meant to limit the name types' usage or
+ applicability.
+
+ For purposes of clarification to GSS-API implementors, this section's
+ discussion of some name forms describes means through which those
+ forms can be supported with existing Kerberos technology. These
+ discussions are not intended to preclude alternative implementation
+ strategies for support of the name forms within Kerberos mechanisms
+ or mechanisms based on other technologies. To enhance application
+
+
+
+Linn Standards Track [Page 12]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ portability, implementors of mechanisms are encouraged to support
+ name forms as defined in this section, even if their mechanisms are
+ independent of Kerberos V5.
+
+2.1. Mandatory Name Forms
+
+ This section discusses name forms which are to be supported by all
+ conformant implementations of the Kerberos V5 GSS-API mechanism.
+
+2.1.1. Kerberos Principal Name Form
+
+ This name form shall be represented by the Object Identifier {iso(1)
+ member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ krb5(2) krb5_name(1)}. The recommended symbolic name for this type
+ is "GSS_KRB5_NT_PRINCIPAL_NAME".
+
+ This name type corresponds to the single-string representation of a
+ Kerberos name. (Within the MIT Kerberos V5 implementation, such
+ names are parseable with the krb5_parse_name() function.) The
+ elements included within this name representation are as follows,
+ proceeding from the beginning of the string:
+
+ (1) One or more principal name components; if more than one
+ principal name component is included, the components are
+ separated by `/`. Arbitrary octets may be included within
+ principal name components, with the following constraints and
+ special considerations:
+
+ (1a) Any occurrence of the characters `@` or `/` within a
+ name component must be immediately preceded by the `\`
+ quoting character, to prevent interpretation as a component
+ or realm separator.
+
+ (1b) The ASCII newline, tab, backspace, and null characters
+ may occur directly within the component or may be
+ represented, respectively, by `\n`, `\t`, `\b`, or `\0`.
+
+ (1c) If the `\` quoting character occurs outside the contexts
+ described in (1a) and (1b) above, the following character is
+ interpreted literally. As a special case, this allows the
+ doubled representation `\\` to represent a single occurrence
+ of the quoting character.
+
+ (1d) An occurrence of the `\` quoting character as the last
+ character of a component is illegal.
+
+
+
+
+
+
+Linn Standards Track [Page 13]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ (2) Optionally, a `@` character, signifying that a realm name
+ immediately follows. If no realm name element is included, the
+ local realm name is assumed. The `/` , `:`, and null characters
+ may not occur within a realm name; the `@`, newline, tab, and
+ backspace characters may be included using the quoting
+ conventions described in (1a), (1b), and (1c) above.
+
+2.1.2. Host-Based Service Name Form
+
+ This name form has been incorporated at the mechanism-independent
+ GSS-API level as of GSS-API, Version 2. This subsection retains the
+ Object Identifier and symbolic name assignments previously made at
+ the Kerberos V5 GSS-API mechanism level, and adopts the definition as
+ promoted to the mechanism-independent level.
+
+ This name form shall be represented by the Object Identifier {iso(1)
+ member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ generic(1) service_name(4)}. The previously recommended symbolic
+ name for this type is "GSS_KRB5_NT_HOSTBASED_SERVICE_NAME". The
+ currently preferred symbolic name for this type is
+ "GSS_C_NT_HOSTBASED_SERVICE".
+
+ This name type is used to represent services associated with host
+ computers. This name form is constructed using two elements,
+ "service" and "hostname", as follows:
+
+ service@hostname
+
+ When a reference to a name of this type is resolved, the "hostname"
+ is canonicalized by attempting a DNS lookup and using the fully-
+ qualified domain name which is returned, or by using the "hostname"
+ as provided if the DNS lookup fails. The canonicalization operation
+ also maps the host's name into lower-case characters.
+
+ The "hostname" element may be omitted. If no "@" separator is
+ included, the entire name is interpreted as the service specifier,
+ with the "hostname" defaulted to the canonicalized name of the local
+ host.
+
+ Values for the "service" element will be registered with the IANA.
+
+2.1.3. Exported Name Object Form for Kerberos V5 Mechanism
+
+ Support for this name form is not required for GSS-V1
+ implementations, but will be required for use in conjunction with the
+ GSS_Export_name() call planned for GSS-API Version 2. Use of this
+ name form will be signified by a "GSS-API Exported Name Object" OID
+ value which will be defined at the mechanism-independent level for
+
+
+
+Linn Standards Track [Page 14]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ GSS-API Version 2.
+
+ This name type represents a self-describing object, whose framing
+ structure will be defined at the mechanism-independent level for
+ GSS-API Version 2. When generated by the Kerberos V5 mechanism, the
+ Mechanism OID within the exportable name shall be that of the
+ Kerberos V5 mechanism. The name component within the exportable name
+ shall be a contiguous string with structure as defined for the
+ Kerberos Principal Name Form.
+
+ In order to achieve a distinguished encoding for comparison purposes,
+ the following additional constraints are imposed on the export
+ operation:
+
+ (1) all occurrences of the characters `@`, `/`, and `\` within
+ principal components or realm names shall be quoted with an
+ immediately-preceding `\`.
+
+ (2) all occurrences of the null, backspace, tab, or newline
+ characters within principal components or realm names will be
+ represented, respectively, with `\0`, `\b`, `\t`, or `\n`.
+
+ (3) the `\` quoting character shall not be emitted within an
+ exported name except to accomodate cases (1) and (2).
+
+2.2. Optional Name Forms
+
+ This section discusses additional name forms which may optionally be
+ supported by implementations of the Kerberos V5 GSS-API mechanism.
+ It is recognized that some of the name forms cited here are derived
+ from UNIX(tm) operating system platforms; some listed forms may be
+ irrelevant to non-UNIX platforms, and definition of additional forms
+ corresponding to such platforms may also be appropriate. It is also
+ recognized that OS-specific functions outside GSS-API are likely to
+ exist in order to perform translations among these forms, and that
+ GSS-API implementations supporting these forms may themselves be
+ layered atop such OS-specific functions. Inclusion of this support
+ within GSS-API implementations is intended as a convenience to
+ applications.
+
+2.2.1. User Name Form
+
+ This name form shall be represented by the Object Identifier {iso(1)
+ member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ generic(1) user_name(1)}. The recommended symbolic name for this
+ type is "GSS_KRB5_NT_USER_NAME".
+
+ This name type is used to indicate a named user on a local system.
+
+
+
+Linn Standards Track [Page 15]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ Its interpretation is OS-specific. This name form is constructed as:
+
+ username
+
+ Assuming that users' principal names are the same as their local
+ operating system names, an implementation of GSS_Import_name() based
+ on Kerberos V5 technology can process names of this form by
+ postfixing an "@" sign and the name of the local realm.
+
+2.2.2. Machine UID Form
+
+ This name form shall be represented by the Object Identifier {iso(1)
+ member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ generic(1) machine_uid_name(2)}. The recommended symbolic name for
+ this type is "GSS_KRB5_NT_MACHINE_UID_NAME".
+
+ This name type is used to indicate a numeric user identifier
+ corresponding to a user on a local system. Its interpretation is
+ OS-specific. The gss_buffer_desc representing a name of this type
+ should contain a locally-significant uid_t, represented in host byte
+ order. The GSS_Import_name() operation resolves this uid into a
+ username, which is then treated as the User Name Form.
+
+2.2.3. String UID Form
+
+ This name form shall be represented by the Object Identifier {iso(1)
+ member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ generic(1) string_uid_name(3)}. The recommended symbolic name for
+ this type is "GSS_KRB5_NT_STRING_UID_NAME".
+
+ This name type is used to indicate a string of digits representing
+ the numeric user identifier of a user on a local system. Its
+ interpretation is OS-specific. This name type is similar to the
+ Machine UID Form, except that the buffer contains a string
+ representing the uid_t.
+
+3. Credentials Management
+
+ The Kerberos V5 protocol uses different credentials (in the GSSAPI
+ sense) for initiating and accepting security contexts. Normal
+ clients receive a ticket-granting ticket (TGT) and an associated
+ session key at "login" time; the pair of a TGT and its corresponding
+ session key forms a credential which is suitable for initiating
+ security contexts. A ticket-granting ticket, its session key, and
+ any other (ticket, key) pairs obtained through use of the ticket-
+ granting-ticket, are typically stored in a Kerberos V5 credentials
+ cache, sometimes known as a ticket file.
+
+
+
+
+Linn Standards Track [Page 16]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ The encryption key used by the Kerberos server to seal tickets for a
+ particular application service forms the credentials suitable for
+ accepting security contexts. These service keys are typically stored
+ in a Kerberos V5 key table, or srvtab file. In addition to their use
+ as accepting credentials, these service keys may also be used to
+ obtain initiating credentials for their service principal.
+
+ The Kerberos V5 mechanism's credential handle may contain references
+ to either or both types of credentials. It is a local matter how the
+ Kerberos V5 mechanism implementation finds the appropriate Kerberos
+ V5 credentials cache or key table.
+
+ However, when the Kerberos V5 mechanism attempts to obtain initiating
+ credentials for a service principal which are not available in a
+ credentials cache, and the key for that service principal is
+ available in a Kerberos V5 key table, the mechanism should use the
+ service key to obtain initiating credentials for that service. This
+ should be accomplished by requesting a ticket-granting-ticket from
+ the Kerberos Key Distribution Center (KDC), and decrypting the KDC's
+ reply using the service key.
+
+4. Parameter Definitions
+
+ This section defines parameter values used by the Kerberos V5 GSS-API
+ mechanism. It defines interface elements in support of portability,
+ and assumes use of C language bindings per RFC-1509.
+
+4.1. Minor Status Codes
+
+ This section recommends common symbolic names for minor_status values
+ to be returned by the Kerberos V5 GSS-API mechanism. Use of these
+ definitions will enable independent implementors to enhance
+ application portability across different implementations of the
+ mechanism defined in this specification. (In all cases,
+ implementations of GSS_Display_status() will enable callers to
+ convert minor_status indicators to text representations.) Each
+ implementation should make available, through include files or other
+ means, a facility to translate these symbolic names into the concrete
+ values which a particular GSS-API implementation uses to represent
+ the minor_status values specified in this section.
+
+ It is recognized that this list may grow over time, and that the need
+ for additional minor_status codes specific to particular
+ implementations may arise. It is recommended, however, that
+ implementations should return a minor_status value as defined on a
+ mechanism-wide basis within this section when that code is accurately
+ representative of reportable status rather than using a separate,
+ implementation-defined code.
+
+
+
+Linn Standards Track [Page 17]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+4.1.1. Non-Kerberos-specific codes
+
+ GSS_KRB5_S_G_BAD_SERVICE_NAME
+ /* "No @ in SERVICE-NAME name string" */
+ GSS_KRB5_S_G_BAD_STRING_UID
+ /* "STRING-UID-NAME contains nondigits" */
+ GSS_KRB5_S_G_NOUSER
+ /* "UID does not resolve to username" */
+ GSS_KRB5_S_G_VALIDATE_FAILED
+ /* "Validation error" */
+ GSS_KRB5_S_G_BUFFER_ALLOC
+ /* "Couldn't allocate gss_buffer_t data" */
+ GSS_KRB5_S_G_BAD_MSG_CTX
+ /* "Message context invalid" */
+ GSS_KRB5_S_G_WRONG_SIZE
+ /* "Buffer is the wrong size" */
+ GSS_KRB5_S_G_BAD_USAGE
+ /* "Credential usage type is unknown" */
+ GSS_KRB5_S_G_UNKNOWN_QOP
+ /* "Unknown quality of protection specified" */
+
+4.1.2. Kerberos-specific-codes
+
+ GSS_KRB5_S_KG_CCACHE_NOMATCH
+ /* "Principal in credential cache does not match desired name" */
+ GSS_KRB5_S_KG_KEYTAB_NOMATCH
+ /* "No principal in keytab matches desired name" */
+ GSS_KRB5_S_KG_TGT_MISSING
+ /* "Credential cache has no TGT" */
+ GSS_KRB5_S_KG_NO_SUBKEY
+ /* "Authenticator has no subkey" */
+ GSS_KRB5_S_KG_CONTEXT_ESTABLISHED
+ /* "Context is already fully established" */
+ GSS_KRB5_S_KG_BAD_SIGN_TYPE
+ /* "Unknown signature type in token" */
+ GSS_KRB5_S_KG_BAD_LENGTH
+ /* "Invalid field length in token" */
+ GSS_KRB5_S_KG_CTX_INCOMPLETE
+ /* "Attempt to use incomplete security context" */
+
+4.2. Quality of Protection Values
+
+ This section defines Quality of Protection (QOP) values to be used
+ with the Kerberos V5 GSS-API mechanism as input to GSS_Wrap() and
+ GSS_GetMIC() routines in order to select among alternate integrity
+ and confidentiality algorithms. Additional QOP values may be added in
+ future versions of this specification. Non-overlapping bit positions
+ are and will be employed in order that both integrity and
+
+
+
+Linn Standards Track [Page 18]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+ confidentiality QOP may be selected within a single parameter, via
+ inclusive-OR of the specified integrity and confidentiality values.
+
+4.2.1. Integrity Algorithms
+
+ The following Quality of Protection (QOP) values are currently
+ defined for the Kerberos V5 GSS-API mechanism, and are used to select
+ among alternate integrity checking algorithms.
+
+ GSS_KRB5_INTEG_C_QOP_MD5 (numeric value: 1)
+ /* Integrity using partial MD5 ("MD2.5") of plaintext */
+
+ GSS_KRB5_INTEG_C_QOP_DES_MD5 (numeric value: 2)
+ /* Integrity using DES MAC of MD5 of plaintext */
+
+ GSS_KRB5_INTEG_C_QOP_DES_MAC (numeric value: 3)
+ /* Integrity using DES MAC of plaintext */
+
+4.2.2. Confidentiality Algorithms
+
+ Only one confidentiality QOP value is currently defined for the
+ Kerberos V5 GSS-API mechanism:
+
+ GSS_KRB5_CONF_C_QOP_DES (numeric value: 0)
+ /* Confidentiality with DES */
+
+ Note: confidentiality QOP should be indicated only by GSS-API calls
+ capable of providing confidentiality services. If non-zero
+ confidentiality QOP values are defined in future to represent
+ different algorithms, therefore, the bit positions containing those
+ values should be cleared before being returned by implementations of
+ GSS_GetMIC() and GSS_VerifyMIC().
+
+4.3. Buffer Sizes
+
+ All implementations of this specification shall be capable of
+ accepting buffers of at least 16 Kbytes as input to GSS_GetMIC(),
+ GSS_VerifyMIC(), and GSS_Wrap(), and shall be capable of accepting
+ the output_token generated by GSS_Wrap() for a 16 Kbyte input buffer
+ as input to GSS_Unwrap(). Support for larger buffer sizes is optional
+ but recommended.
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 19]
+
+RFC 1964 Kerberos Version 5 GSS-API June 1996
+
+
+5. Security Considerations
+
+ Security issues are discussed throughout this memo.
+
+6. References
+
+
+ [RFC-1321]: Rivest, R., "The MD5 Message-Digest Algorithm", RFC
+ 1321, April 1992.
+
+ [RFC-1508]: Linn, J., "Generic Security Service Application Program
+ Interface", RFC 1508, September 1993.
+
+ [RFC-1509]: Wray, J., "Generic Security Service Application Program
+ Interface: C-bindings", RFC 1509, September 1993.
+
+ [RFC-1510]: Kohl, J., and C. Neuman, "The Kerberos Network
+ Authentication Service (V5)", RFC 1510, September 1993.
+
+ [FIPS-PUB-113]: National Bureau of Standards, Federal Information
+ Processing Standard 113, "Computer Data Authentication", May 1985.
+
+AUTHOR'S ADDRESS
+
+ John Linn
+ OpenVision Technologies
+ One Main St.
+ Cambridge, MA 02142 USA
+
+ Phone: +1 617.374.2245
+ EMail: John.Linn@ov.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 20]
+
diff --git a/crypto/heimdal/doc/standardisation/rfc2078.txt b/crypto/heimdal/doc/standardisation/rfc2078.txt
new file mode 100644
index 000000000000..1dd1e4aebd2d
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/rfc2078.txt
@@ -0,0 +1,4763 @@
+
+
+
+
+
+
+Network Working Group J. Linn
+Request for Comments: 2078 OpenVision Technologies
+Category: Standards Track January 1997
+Obsoletes: 1508
+
+
+ Generic Security Service Application Program Interface, Version 2
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Abstract
+
+ The Generic Security Service Application Program Interface (GSS-API),
+ as defined in RFC-1508, provides security services to callers in a
+ generic fashion, supportable with a range of underlying mechanisms
+ and technologies and hence allowing source-level portability of
+ applications to different environments. This specification defines
+ GSS-API services and primitives at a level independent of underlying
+ mechanism and programming language environment, and is to be
+ complemented by other, related specifications:
+
+ documents defining specific parameter bindings for particular
+ language environments
+
+ documents defining token formats, protocols, and procedures to be
+ implemented in order to realize GSS-API services atop particular
+ security mechanisms
+
+ This memo revises RFC-1508, making specific, incremental changes in
+ response to implementation experience and liaison requests. It is
+ intended, therefore, that this memo or a successor version thereto
+ will become the basis for subsequent progression of the GSS-API
+ specification on the standards track.
+
+Table of Contents
+
+ 1: GSS-API Characteristics and Concepts.......................... 3
+ 1.1: GSS-API Constructs.......................................... 6
+ 1.1.1: Credentials.............................................. 6
+ 1.1.1.1: Credential Constructs and Concepts...................... 6
+ 1.1.1.2: Credential Management................................... 7
+ 1.1.1.3: Default Credential Resolution........................... 8
+
+
+
+Linn Standards Track [Page 1]
+
+RFC 2078 GSS-API January 1997
+
+
+ 1.1.2: Tokens.................................................... 9
+ 1.1.3: Security Contexts........................................ 10
+ 1.1.4: Mechanism Types.......................................... 11
+ 1.1.5: Naming................................................... 12
+ 1.1.6: Channel Bindings......................................... 14
+ 1.2: GSS-API Features and Issues................................ 15
+ 1.2.1: Status Reporting......................................... 15
+ 1.2.2: Per-Message Security Service Availability................. 17
+ 1.2.3: Per-Message Replay Detection and Sequencing............... 18
+ 1.2.4: Quality of Protection.................................... 20
+ 1.2.5: Anonymity Support......................................... 21
+ 1.2.6: Initialization............................................ 22
+ 1.2.7: Per-Message Protection During Context Establishment....... 22
+ 1.2.8: Implementation Robustness................................. 23
+ 2: Interface Descriptions....................................... 23
+ 2.1: Credential management calls................................ 25
+ 2.1.1: GSS_Acquire_cred call.................................... 26
+ 2.1.2: GSS_Release_cred call.................................... 28
+ 2.1.3: GSS_Inquire_cred call.................................... 29
+ 2.1.4: GSS_Add_cred call........................................ 31
+ 2.1.5: GSS_Inquire_cred_by_mech call............................ 33
+ 2.2: Context-level calls........................................ 34
+ 2.2.1: GSS_Init_sec_context call................................ 34
+ 2.2.2: GSS_Accept_sec_context call.............................. 40
+ 2.2.3: GSS_Delete_sec_context call.............................. 44
+ 2.2.4: GSS_Process_context_token call........................... 46
+ 2.2.5: GSS_Context_time call.................................... 47
+ 2.2.6: GSS_Inquire_context call................................. 47
+ 2.2.7: GSS_Wrap_size_limit call................................. 49
+ 2.2.8: GSS_Export_sec_context call.............................. 50
+ 2.2.9: GSS_Import_sec_context call.............................. 52
+ 2.3: Per-message calls.......................................... 53
+ 2.3.1: GSS_GetMIC call.......................................... 54
+ 2.3.2: GSS_VerifyMIC call....................................... 55
+ 2.3.3: GSS_Wrap call............................................ 56
+ 2.3.4: GSS_Unwrap call.......................................... 58
+ 2.4: Support calls.............................................. 59
+ 2.4.1: GSS_Display_status call.................................. 60
+ 2.4.2: GSS_Indicate_mechs call.................................. 60
+ 2.4.3: GSS_Compare_name call.................................... 61
+ 2.4.4: GSS_Display_name call.................................... 62
+ 2.4.5: GSS_Import_name call..................................... 63
+ 2.4.6: GSS_Release_name call.................................... 64
+ 2.4.7: GSS_Release_buffer call.................................. 65
+ 2.4.8: GSS_Release_OID_set call................................. 65
+ 2.4.9: GSS_Create_empty_OID_set call............................ 66
+ 2.4.10: GSS_Add_OID_set_member call.............................. 67
+ 2.4.11: GSS_Test_OID_set_member call............................. 67
+
+
+
+Linn Standards Track [Page 2]
+
+RFC 2078 GSS-API January 1997
+
+
+ 2.4.12: GSS_Release_OID call..................................... 68
+ 2.4.13: GSS_OID_to_str call...................................... 68
+ 2.4.14: GSS_Str_to_OID call...................................... 69
+ 2.4.15: GSS_Inquire_names_for_mech call.......................... 69
+ 2.4.16: GSS_Inquire_mechs_for_name call.......................... 70
+ 2.4.17: GSS_Canonicalize_name call............................... 71
+ 2.4.18: GSS_Export_name call..................................... 72
+ 2.4.19: GSS_Duplicate_name call.................................. 73
+ 3: Data Structure Definitions for GSS-V2 Usage................... 73
+ 3.1: Mechanism-Independent Token Format.......................... 74
+ 3.2: Mechanism-Independent Exported Name Object Format........... 77
+ 4: Name Type Definitions......................................... 77
+ 4.1: Host-Based Service Name Form................................ 77
+ 4.2: User Name Form.............................................. 78
+ 4.3: Machine UID Form............................................ 78
+ 4.4: String UID Form............................................. 79
+ 5: Mechanism-Specific Example Scenarios......................... 79
+ 5.1: Kerberos V5, single-TGT..................................... 79
+ 5.2: Kerberos V5, double-TGT..................................... 80
+ 5.3: X.509 Authentication Framework............................. 81
+ 6: Security Considerations...................................... 82
+ 7: Related Activities........................................... 82
+ Appendix A: Mechanism Design Constraints......................... 83
+ Appendix B: Compatibility with GSS-V1............................ 83
+
+1: GSS-API Characteristics and Concepts
+
+ GSS-API operates in the following paradigm. A typical GSS-API caller
+ is itself a communications protocol, calling on GSS-API in order to
+ protect its communications with authentication, integrity, and/or
+ confidentiality security services. A GSS-API caller accepts tokens
+ provided to it by its local GSS-API implementation and transfers the
+ tokens to a peer on a remote system; that peer passes the received
+ tokens to its local GSS-API implementation for processing. The
+ security services available through GSS-API in this fashion are
+ implementable (and have been implemented) over a range of underlying
+ mechanisms based on secret-key and public-key cryptographic
+ technologies.
+
+ The GSS-API separates the operations of initializing a security
+ context between peers, achieving peer entity authentication (This
+ security service definition, and other definitions used in this
+ document, corresponds to that provided in International Standard ISO
+ 7498-2-1988(E), Security Architecture.) (GSS_Init_sec_context() and
+ GSS_Accept_sec_context() calls), from the operations of providing
+ per-message data origin authentication and data integrity protection
+ (GSS_GetMIC() and GSS_VerifyMIC() calls) for messages subsequently
+ transferred in conjunction with that context. When establishing a
+
+
+
+Linn Standards Track [Page 3]
+
+RFC 2078 GSS-API January 1997
+
+
+ security context, the GSS-API enables a context initiator to
+ optionally permit its credentials to be delegated, meaning that the
+ context acceptor may initiate further security contexts on behalf of
+ the initiating caller. Per-message GSS_Wrap() and GSS_Unwrap() calls
+ provide the data origin authentication and data integrity services
+ which GSS_GetMIC() and GSS_VerifyMIC() offer, and also support
+ selection of confidentiality services as a caller option. Additional
+ calls provide supportive functions to the GSS-API's users.
+
+ The following paragraphs provide an example illustrating the
+ dataflows involved in use of the GSS-API by a client and server in a
+ mechanism-independent fashion, establishing a security context and
+ transferring a protected message. The example assumes that credential
+ acquisition has already been completed. The example assumes that the
+ underlying authentication technology is capable of authenticating a
+ client to a server using elements carried within a single token, and
+ of authenticating the server to the client (mutual authentication)
+ with a single returned token; this assumption holds for presently-
+ documented CAT mechanisms but is not necessarily true for other
+ cryptographic technologies and associated protocols.
+
+ The client calls GSS_Init_sec_context() to establish a security
+ context to the server identified by targ_name, and elects to set the
+ mutual_req_flag so that mutual authentication is performed in the
+ course of context establishment. GSS_Init_sec_context() returns an
+ output_token to be passed to the server, and indicates
+ GSS_S_CONTINUE_NEEDED status pending completion of the mutual
+ authentication sequence. Had mutual_req_flag not been set, the
+ initial call to GSS_Init_sec_context() would have returned
+ GSS_S_COMPLETE status. The client sends the output_token to the
+ server.
+
+ The server passes the received token as the input_token parameter to
+ GSS_Accept_sec_context(). GSS_Accept_sec_context indicates
+ GSS_S_COMPLETE status, provides the client's authenticated identity
+ in the src_name result, and provides an output_token to be passed to
+ the client. The server sends the output_token to the client.
+
+ The client passes the received token as the input_token parameter to
+ a successor call to GSS_Init_sec_context(), which processes data
+ included in the token in order to achieve mutual authentication from
+ the client's viewpoint. This call to GSS_Init_sec_context() returns
+ GSS_S_COMPLETE status, indicating successful mutual authentication
+ and the completion of context establishment for this example.
+
+ The client generates a data message and passes it to GSS_Wrap().
+ GSS_Wrap() performs data origin authentication, data integrity, and
+ (optionally) confidentiality processing on the message and
+
+
+
+Linn Standards Track [Page 4]
+
+RFC 2078 GSS-API January 1997
+
+
+ encapsulates the result into output_message, indicating
+ GSS_S_COMPLETE status. The client sends the output_message to the
+ server.
+
+ The server passes the received message to GSS_Unwrap(). GSS_Unwrap()
+ inverts the encapsulation performed by GSS_Wrap(), deciphers the
+ message if the optional confidentiality feature was applied, and
+ validates the data origin authentication and data integrity checking
+ quantities. GSS_Unwrap() indicates successful validation by
+ returning GSS_S_COMPLETE status along with the resultant
+ output_message.
+
+ For purposes of this example, we assume that the server knows by
+ out-of-band means that this context will have no further use after
+ one protected message is transferred from client to server. Given
+ this premise, the server now calls GSS_Delete_sec_context() to flush
+ context-level information. Optionally, the server-side application
+ may provide a token buffer to GSS_Delete_sec_context(), to receive a
+ context_token to be transferred to the client in order to request
+ that client-side context-level information be deleted.
+
+ If a context_token is transferred, the client passes the
+ context_token to GSS_Process_context_token(), which returns
+ GSS_S_COMPLETE status after deleting context-level information at the
+ client system.
+
+ The GSS-API design assumes and addresses several basic goals,
+ including:
+
+ Mechanism independence: The GSS-API defines an interface to
+ cryptographically implemented strong authentication and other
+ security services at a generic level which is independent of
+ particular underlying mechanisms. For example, GSS-API-provided
+ services can be implemented by secret-key technologies (e.g.,
+ Kerberos) or public-key approaches (e.g., X.509).
+
+ Protocol environment independence: The GSS-API is independent of
+ the communications protocol suites with which it is employed,
+ permitting use in a broad range of protocol environments. In
+ appropriate environments, an intermediate implementation "veneer"
+ which is oriented to a particular communication protocol (e.g.,
+ Remote Procedure Call (RPC)) may be interposed between
+ applications which call that protocol and the GSS-API, thereby
+ invoking GSS-API facilities in conjunction with that protocol's
+ communications invocations.
+
+ Protocol association independence: The GSS-API's security context
+ construct is independent of communications protocol association
+
+
+
+Linn Standards Track [Page 5]
+
+RFC 2078 GSS-API January 1997
+
+
+ constructs. This characteristic allows a single GSS-API
+ implementation to be utilized by a variety of invoking protocol
+ modules on behalf of those modules' calling applications. GSS-API
+ services can also be invoked directly by applications, wholly
+ independent of protocol associations.
+
+ Suitability to a range of implementation placements: GSS-API
+ clients are not constrained to reside within any Trusted Computing
+ Base (TCB) perimeter defined on a system where the GSS-API is
+ implemented; security services are specified in a manner suitable
+ to both intra-TCB and extra-TCB callers.
+
+1.1: GSS-API Constructs
+
+ This section describes the basic elements comprising the GSS-API.
+
+1.1.1: Credentials
+
+1.1.1.1: Credential Constructs and Concepts
+
+ Credentials provide the prerequisites which permit GSS-API peers to
+ establish security contexts with each other. A caller may designate
+ that the credential elements which are to be applied for context
+ initiation or acceptance be selected by default. Alternately, those
+ GSS-API callers which need to make explicit selection of particular
+ credentials structures may make references to those credentials
+ through GSS-API-provided credential handles ("cred_handles"). In all
+ cases, callers' credential references are indirect, mediated by GSS-
+ API implementations and not requiring callers to access the selected
+ credential elements.
+
+ A single credential structure may be used to initiate outbound
+ contexts and to accept inbound contexts. Callers needing to operate
+ in only one of these modes may designate this fact when credentials
+ are acquired for use, allowing underlying mechanisms to optimize
+ their processing and storage requirements. The credential elements
+ defined by a particular mechanism may contain multiple cryptographic
+ keys, e.g., to enable authentication and message encryption to be
+ performed with different algorithms.
+
+ A GSS-API credential structure may contain multiple credential
+ elements, each containing mechanism-specific information for a
+ particular underlying mechanism (mech_type), but the set of elements
+ within a given credential structure represent a common entity. A
+ credential structure's contents will vary depending on the set of
+ mech_types supported by a particular GSS-API implementation. Each
+ credential element identifies the data needed by its mechanism in
+ order to establish contexts on behalf of a particular principal, and
+
+
+
+Linn Standards Track [Page 6]
+
+RFC 2078 GSS-API January 1997
+
+
+ may contain separate credential references for use in context
+ initiation and context acceptance. Multiple credential elements
+ within a given credential having overlapping combinations of
+ mechanism, usage mode, and validity period are not permitted.
+
+ Commonly, a single mech_type will be used for all security contexts
+ established by a particular initiator to a particular target. A major
+ motivation for supporting credential sets representing multiple
+ mech_types is to allow initiators on systems which are equipped to
+ handle multiple types to initiate contexts to targets on other
+ systems which can accommodate only a subset of the set supported at
+ the initiator's system.
+
+1.1.1.2: Credential Management
+
+ It is the responsibility of underlying system-specific mechanisms and
+ OS functions below the GSS-API to ensure that the ability to acquire
+ and use credentials associated with a given identity is constrained
+ to appropriate processes within a system. This responsibility should
+ be taken seriously by implementors, as the ability for an entity to
+ utilize a principal's credentials is equivalent to the entity's
+ ability to successfully assert that principal's identity.
+
+ Once a set of GSS-API credentials is established, the transferability
+ of that credentials set to other processes or analogous constructs
+ within a system is a local matter, not defined by the GSS-API. An
+ example local policy would be one in which any credentials received
+ as a result of login to a given user account, or of delegation of
+ rights to that account, are accessible by, or transferable to,
+ processes running under that account.
+
+ The credential establishment process (particularly when performed on
+ behalf of users rather than server processes) is likely to require
+ access to passwords or other quantities which should be protected
+ locally and exposed for the shortest time possible. As a result, it
+ will often be appropriate for preliminary credential establishment to
+ be performed through local means at user login time, with the
+ result(s) cached for subsequent reference. These preliminary
+ credentials would be set aside (in a system-specific fashion) for
+ subsequent use, either:
+
+ to be accessed by an invocation of the GSS-API GSS_Acquire_cred()
+ call, returning an explicit handle to reference that credential
+
+ to comprise default credential elements to be installed, and to be
+ used when default credential behavior is requested on behalf of a
+ process
+
+
+
+
+Linn Standards Track [Page 7]
+
+RFC 2078 GSS-API January 1997
+
+
+1.1.1.3: Default Credential Resolution
+
+ The gss_init_sec_context and gss_accept_sec_context routines allow
+ the value GSS_C_NO_CREDENTIAL to be specified as their credential
+ handle parameter. This special credential-handle indicates a desire
+ by the application to act as a default principal. While individual
+ GSS-API implementations are free to determine such default behavior
+ as appropriate to the mechanism, the following default behavior by
+ these routines is recommended for portability:
+
+ GSS_Init_sec_context:
+
+ (i) If there is only a single principal capable of initiating
+ security contexts that the application is authorized to act on
+ behalf of, then that principal shall be used, otherwise
+
+ (ii) If the platform maintains a concept of a default network-
+ identity, and if the application is authorized to act on behalf of
+ that identity for the purpose of initiating security contexts,
+ then the principal corresponding to that identity shall be used,
+ otherwise
+
+ (iii) If the platform maintains a concept of a default local
+ identity, and provides a means to map local identities into
+ network-identities, and if the application is authorized to act on
+ behalf of the network-identity image of the default local identity
+ for the purpose of initiating security contexts, then the
+ principal corresponding to that identity shall be used, otherwise
+
+ (iv) A user-configurable default identity should be used.
+
+ GSS_Accept_sec_context:
+
+ (i) If there is only a single authorized principal identity
+ capable of accepting security contexts, then that principal shall
+ be used, otherwise
+
+ (ii) If the mechanism can determine the identity of the target
+ principal by examining the context-establishment token, and if the
+ accepting application is authorized to act as that principal for
+ the purpose of accepting security contexts, then that principal
+ identity shall be used, otherwise
+
+ (iii) If the mechanism supports context acceptance by any
+ principal, and mutual authentication was not requested, any
+ principal that the application is authorized to accept security
+ contexts under may be used, otherwise
+
+
+
+
+Linn Standards Track [Page 8]
+
+RFC 2078 GSS-API January 1997
+
+
+ (iv) A user-configurable default identity shall be used.
+
+ The purpose of the above rules is to allow security contexts to be
+ established by both initiator and acceptor using the default behavior
+ wherever possible. Applications requesting default behavior are
+ likely to be more portable across mechanisms and platforms than ones
+ that use GSS_Acquire_cred to request a specific identity.
+
+1.1.2: Tokens
+
+ Tokens are data elements transferred between GSS-API callers, and are
+ divided into two classes. Context-level tokens are exchanged in order
+ to establish and manage a security context between peers. Per-message
+ tokens relate to an established context and are exchanged to provide
+ protective security services (i.e., data origin authentication,
+ integrity, and optional confidentiality) for corresponding data
+ messages.
+
+ The first context-level token obtained from GSS_Init_sec_context() is
+ required to indicate at its very beginning a globally-interpretable
+ mechanism identifier, i.e., an Object Identifier (OID) of the
+ security mechanism. The remaining part of this token as well as the
+ whole content of all other tokens are specific to the particular
+ underlying mechanism used to support the GSS-API. Section 3 of this
+ document provides, for designers of GSS-API support mechanisms, the
+ description of the header of the first context-level token which is
+ then followed by mechanism-specific information.
+
+ Tokens' contents are opaque from the viewpoint of GSS-API callers.
+ They are generated within the GSS-API implementation at an end
+ system, provided to a GSS-API caller to be transferred to the peer
+ GSS-API caller at a remote end system, and processed by the GSS-API
+ implementation at that remote end system. Tokens may be output by
+ GSS-API calls (and should be transferred to GSS-API peers) whether or
+ not the calls' status indicators indicate successful completion.
+ Token transfer may take place in an in-band manner, integrated into
+ the same protocol stream used by the GSS-API callers for other data
+ transfers, or in an out-of-band manner across a logically separate
+ channel.
+
+ Different GSS-API tokens are used for different purposes (e.g.,
+ context initiation, context acceptance, protected message data on an
+ established context), and it is the responsibility of a GSS-API
+ caller receiving tokens to distinguish their types, associate them
+ with corresponding security contexts, and pass them to appropriate
+ GSS-API processing routines. Depending on the caller protocol
+ environment, this distinction may be accomplished in several ways.
+
+
+
+
+Linn Standards Track [Page 9]
+
+RFC 2078 GSS-API January 1997
+
+
+ The following examples illustrate means through which tokens' types
+ may be distinguished:
+
+ - implicit tagging based on state information (e.g., all tokens on
+ a new association are considered to be context establishment
+ tokens until context establishment is completed, at which point
+ all tokens are considered to be wrapped data objects for that
+ context),
+
+ - explicit tagging at the caller protocol level,
+
+ - a hybrid of these approaches.
+
+ Commonly, the encapsulated data within a token includes internal
+ mechanism-specific tagging information, enabling mechanism-level
+ processing modules to distinguish tokens used within the mechanism
+ for different purposes. Such internal mechanism-level tagging is
+ recommended to mechanism designers, and enables mechanisms to
+ determine whether a caller has passed a particular token for
+ processing by an inappropriate GSS-API routine.
+
+ Development of GSS-API support primitives based on a particular
+ underlying cryptographic technique and protocol (i.e., conformant to
+ a specific GSS-API mechanism definition) does not necessarily imply
+ that GSS-API callers using that GSS-API mechanism will be able to
+ interoperate with peers invoking the same technique and protocol
+ outside the GSS-API paradigm, or with peers implementing a different
+ GSS-API mechanism based on the same underlying technology. The
+ format of GSS-API tokens defined in conjunction with a particular
+ mechanism, and the techniques used to integrate those tokens into
+ callers' protocols, may not be interoperable with the tokens used by
+ non-GSS-API callers of the same underlying technique.
+
+1.1.3: Security Contexts
+
+ Security contexts are established between peers, using credentials
+ established locally in conjunction with each peer or received by
+ peers via delegation. Multiple contexts may exist simultaneously
+ between a pair of peers, using the same or different sets of
+ credentials. Coexistence of multiple contexts using different
+ credentials allows graceful rollover when credentials expire.
+ Distinction among multiple contexts based on the same credentials
+ serves applications by distinguishing different message streams in a
+ security sense.
+
+ The GSS-API is independent of underlying protocols and addressing
+ structure, and depends on its callers to transport GSS-API-provided
+ data elements. As a result of these factors, it is a caller
+
+
+
+Linn Standards Track [Page 10]
+
+RFC 2078 GSS-API January 1997
+
+
+ responsibility to parse communicated messages, separating GSS-API-
+ related data elements from caller-provided data. The GSS-API is
+ independent of connection vs. connectionless orientation of the
+ underlying communications service.
+
+ No correlation between security context and communications protocol
+ association is dictated. (The optional channel binding facility,
+ discussed in Section 1.1.6 of this document, represents an
+ intentional exception to this rule, supporting additional protection
+ features within GSS-API supporting mechanisms.) This separation
+ allows the GSS-API to be used in a wide range of communications
+ environments, and also simplifies the calling sequences of the
+ individual calls. In many cases (depending on underlying security
+ protocol, associated mechanism, and availability of cached
+ information), the state information required for context setup can be
+ sent concurrently with initial signed user data, without interposing
+ additional message exchanges.
+
+1.1.4: Mechanism Types
+
+ In order to successfully establish a security context with a target
+ peer, it is necessary to identify an appropriate underlying mechanism
+ type (mech_type) which both initiator and target peers support. The
+ definition of a mechanism embodies not only the use of a particular
+ cryptographic technology (or a hybrid or choice among alternative
+ cryptographic technologies), but also definition of the syntax and
+ semantics of data element exchanges which that mechanism will employ
+ in order to support security services.
+
+ It is recommended that callers initiating contexts specify the
+ "default" mech_type value, allowing system-specific functions within
+ or invoked by the GSS-API implementation to select the appropriate
+ mech_type, but callers may direct that a particular mech_type be
+ employed when necessary.
+
+ The means for identifying a shared mech_type to establish a security
+ context with a peer will vary in different environments and
+ circumstances; examples include (but are not limited to):
+
+ use of a fixed mech_type, defined by configuration, within an
+ environment
+
+ syntactic convention on a target-specific basis, through
+ examination of a target's name
+
+ lookup of a target's name in a naming service or other database in
+ order to identify mech_types supported by that target
+
+
+
+
+Linn Standards Track [Page 11]
+
+RFC 2078 GSS-API January 1997
+
+
+ explicit negotiation between GSS-API callers in advance of
+ security context setup
+
+ When transferred between GSS-API peers, mech_type specifiers (per
+ Section 3, represented as Object Identifiers (OIDs)) serve to qualify
+ the interpretation of associated tokens. (The structure and encoding
+ of Object Identifiers is defined in ISO/IEC 8824, "Specification of
+ Abstract Syntax Notation One (ASN.1)" and in ISO/IEC 8825,
+ "Specification of Basic Encoding Rules for Abstract Syntax Notation
+ One (ASN.1)".) Use of hierarchically structured OIDs serves to
+ preclude ambiguous interpretation of mech_type specifiers. The OID
+ representing the DASS MechType, for example, is 1.3.12.2.1011.7.5,
+ and that of the Kerberos V5 mechanism, once advanced to the level of
+ Proposed Standard, will be 1.2.840.113554.1.2.2.
+
+1.1.5: Naming
+
+ The GSS-API avoids prescribing naming structures, treating the names
+ which are transferred across the interface in order to initiate and
+ accept security contexts as opaque objects. This approach supports
+ the GSS-API's goal of implementability atop a range of underlying
+ security mechanisms, recognizing the fact that different mechanisms
+ process and authenticate names which are presented in different
+ forms. Generalized services offering translation functions among
+ arbitrary sets of naming environments are outside the scope of the
+ GSS-API; availability and use of local conversion functions to
+ translate among the naming formats supported within a given end
+ system is anticipated.
+
+ Different classes of name representations are used in conjunction
+ with different GSS-API parameters:
+
+ - Internal form (denoted in this document by INTERNAL NAME),
+ opaque to callers and defined by individual GSS-API
+ implementations. GSS-API implementations supporting multiple
+ namespace types must maintain internal tags to disambiguate the
+ interpretation of particular names. A Mechanism Name (MN) is a
+ special case of INTERNAL NAME, guaranteed to contain elements
+ corresponding to one and only one mechanism; calls which are
+ guaranteed to emit MNs or which require MNs as input are so
+ identified within this specification.
+
+ - Contiguous string ("flat") form (denoted in this document by
+ OCTET STRING); accompanied by OID tags identifying the namespace
+ to which they correspond. Depending on tag value, flat names may
+ or may not be printable strings for direct acceptance from and
+ presentation to users. Tagging of flat names allows GSS-API
+ callers and underlying GSS-API mechanisms to disambiguate name
+
+
+
+Linn Standards Track [Page 12]
+
+RFC 2078 GSS-API January 1997
+
+
+ types and to determine whether an associated name's type is one
+ which they are capable of processing, avoiding aliasing problems
+ which could result from misinterpreting a name of one type as a
+ name of another type.
+
+ - The GSS-API Exported Name Object, a special case of flat name
+ designated by a reserved OID value, carries a canonicalized form
+ of a name suitable for binary comparisons.
+
+ In addition to providing means for names to be tagged with types,
+ this specification defines primitives to support a level of naming
+ environment independence for certain calling applications. To provide
+ basic services oriented towards the requirements of callers which
+ need not themselves interpret the internal syntax and semantics of
+ names, GSS-API calls for name comparison (GSS_Compare_name()),
+ human-readable display (GSS_Display_name()), input conversion
+ (GSS_Import_name()), internal name deallocation (GSS_Release_name()),
+ and internal name duplication (GSS_Duplicate_name()) functions are
+ defined. (It is anticipated that these proposed GSS-API calls will be
+ implemented in many end systems based on system-specific name
+ manipulation primitives already extant within those end systems;
+ inclusion within the GSS-API is intended to offer GSS-API callers a
+ portable means to perform specific operations, supportive of
+ authorization and audit requirements, on authenticated names.)
+
+ GSS_Import_name() implementations can, where appropriate, support
+ more than one printable syntax corresponding to a given namespace
+ (e.g., alternative printable representations for X.500 Distinguished
+ Names), allowing flexibility for their callers to select among
+ alternative representations. GSS_Display_name() implementations
+ output a printable syntax selected as appropriate to their
+ operational environments; this selection is a local matter. Callers
+ desiring portability across alternative printable syntaxes should
+ refrain from implementing comparisons based on printable name forms
+ and should instead use the GSS_Compare_name() call to determine
+ whether or not one internal-format name matches another.
+
+ The GSS_Canonicalize_name() and GSS_Export_name() calls enable
+ callers to acquire and process Exported Name Objects, canonicalized
+ and translated in accordance with the procedures of a particular
+ GSS-API mechanism. Exported Name Objects can, in turn, be input to
+ GSS_Import_name(), yielding equivalent MNs. These facilities are
+ designed specifically to enable efficient storage and comparison of
+ names (e.g., for use in access control lists).
+
+
+
+
+
+
+
+Linn Standards Track [Page 13]
+
+RFC 2078 GSS-API January 1997
+
+
+ The following diagram illustrates the intended dataflow among name-
+ related GSS-API processing routines.
+
+ GSS-API library defaults
+ |
+ |
+ V text, for
+ text --------------> internal_name (IN) -----------> display only
+ import_name() / display_name()
+ /
+ /
+ /
+ accept_sec_context() /
+ | /
+ | /
+ | / canonicalize_name()
+ | /
+ | /
+ | /
+ | /
+ | /
+ | |
+ V V <---------------------
+ single mechanism import_name() exported name: flat
+ internal_name (MN) binary "blob" usable
+ ----------------------> for access control
+ export_name()
+
+1.1.6: Channel Bindings
+
+ The GSS-API accommodates the concept of caller-provided channel
+ binding ("chan_binding") information. Channel bindings are used to
+ strengthen the quality with which peer entity authentication is
+ provided during context establishment, by limiting the scope within
+ which an intercepted context establishment token can be reused by an
+ attacker. Specifically, they enable GSS-API callers to bind the
+ establishment of a security context to relevant characteristics
+ (e.g., addresses, transformed representations of encryption keys) of
+ the underlying communications channel, of protection mechanisms
+ applied to that communications channel, and to application-specific
+ data.
+
+ The caller initiating a security context must determine the
+ appropriate channel binding values to provide as input to the
+ GSS_Init_sec_context() call, and consistent values must be provided
+ to GSS_Accept_sec_context() by the context's target, in order for
+ both peers' GSS-API mechanisms to validate that received tokens
+ possess correct channel-related characteristics. Use or non-use of
+
+
+
+Linn Standards Track [Page 14]
+
+RFC 2078 GSS-API January 1997
+
+
+ the GSS-API channel binding facility is a caller option. GSS-API
+ mechanisms can operate in an environment where NULL channel bindings
+ are presented; mechanism implementors are encouraged, but not
+ required, to make use of caller-provided channel binding data within
+ their mechanisms. Callers should not assume that underlying
+ mechanisms provide confidentiality protection for channel binding
+ information.
+
+ When non-NULL channel bindings are provided by callers, certain
+ mechanisms can offer enhanced security value by interpreting the
+ bindings' content (rather than simply representing those bindings, or
+ integrity check values computed on them, within tokens) and will
+ therefore depend on presentation of specific data in a defined
+ format. To this end, agreements among mechanism implementors are
+ defining conventional interpretations for the contents of channel
+ binding arguments, including address specifiers (with content
+ dependent on communications protocol environment) for context
+ initiators and acceptors. (These conventions are being incorporated
+ in GSS-API mechanism specifications and into the GSS-API C language
+ bindings specification.) In order for GSS-API callers to be portable
+ across multiple mechanisms and achieve the full security
+ functionality which each mechanism can provide, it is strongly
+ recommended that GSS-API callers provide channel bindings consistent
+ with these conventions and those of the networking environment in
+ which they operate.
+
+1.2: GSS-API Features and Issues
+
+ This section describes aspects of GSS-API operations, of the security
+ services which the GSS-API provides, and provides commentary on
+ design issues.
+
+1.2.1: Status Reporting
+
+ Each GSS-API call provides two status return values. Major_status
+ values provide a mechanism-independent indication of call status
+ (e.g., GSS_S_COMPLETE, GSS_S_FAILURE, GSS_S_CONTINUE_NEEDED),
+ sufficient to drive normal control flow within the caller in a
+ generic fashion. Table 1 summarizes the defined major_status return
+ codes in tabular fashion.
+
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 15]
+
+RFC 2078 GSS-API January 1997
+
+
+Table 1: GSS-API Major Status Codes
+
+ FATAL ERROR CODES
+
+ GSS_S_BAD_BINDINGS channel binding mismatch
+ GSS_S_BAD_MECH unsupported mechanism requested
+ GSS_S_BAD_NAME invalid name provided
+ GSS_S_BAD_NAMETYPE name of unsupported type provided
+ GSS_S_BAD_STATUS invalid input status selector
+ GSS_S_BAD_SIG token had invalid integrity check
+ GSS_S_CONTEXT_EXPIRED specified security context expired
+ GSS_S_CREDENTIALS_EXPIRED expired credentials detected
+ GSS_S_DEFECTIVE_CREDENTIAL defective credential detected
+ GSS_S_DEFECTIVE_TOKEN defective token detected
+ GSS_S_FAILURE failure, unspecified at GSS-API
+ level
+ GSS_S_NO_CONTEXT no valid security context specified
+ GSS_S_NO_CRED no valid credentials provided
+ GSS_S_BAD_QOP unsupported QOP value
+ GSS_S_UNAUTHORIZED operation unauthorized
+ GSS_S_UNAVAILABLE operation unavailable
+ GSS_S_DUPLICATE_ELEMENT duplicate credential element requested
+ GSS_S_NAME_NOT_MN name contains multi-mechanism elements
+
+ INFORMATORY STATUS CODES
+
+ GSS_S_COMPLETE normal completion
+ GSS_S_CONTINUE_NEEDED continuation call to routine
+ required
+ GSS_S_DUPLICATE_TOKEN duplicate per-message token
+ detected
+ GSS_S_OLD_TOKEN timed-out per-message token
+ detected
+ GSS_S_UNSEQ_TOKEN reordered (early) per-message token
+ detected
+ GSS_S_GAP_TOKEN skipped predecessor token(s)
+ detected
+
+ Minor_status provides more detailed status information which may
+ include status codes specific to the underlying security mechanism.
+ Minor_status values are not specified in this document.
+
+ GSS_S_CONTINUE_NEEDED major_status returns, and optional message
+ outputs, are provided in GSS_Init_sec_context() and
+ GSS_Accept_sec_context() calls so that different mechanisms'
+ employment of different numbers of messages within their
+ authentication sequences need not be reflected in separate code paths
+ within calling applications. Instead, such cases are accommodated
+
+
+
+Linn Standards Track [Page 16]
+
+RFC 2078 GSS-API January 1997
+
+
+ with sequences of continuation calls to GSS_Init_sec_context() and
+ GSS_Accept_sec_context(). The same mechanism is used to encapsulate
+ mutual authentication within the GSS-API's context initiation calls.
+
+ For mech_types which require interactions with third-party servers in
+ order to establish a security context, GSS-API context establishment
+ calls may block pending completion of such third-party interactions.
+
+ On the other hand, no GSS-API calls pend on serialized interactions
+ with GSS-API peer entities. As a result, local GSS-API status
+ returns cannot reflect unpredictable or asynchronous exceptions
+ occurring at remote peers, and reflection of such status information
+ is a caller responsibility outside the GSS-API.
+
+1.2.2: Per-Message Security Service Availability
+
+ When a context is established, two flags are returned to indicate the
+ set of per-message protection security services which will be
+ available on the context:
+
+ the integ_avail flag indicates whether per-message integrity and
+ data origin authentication services are available
+
+ the conf_avail flag indicates whether per-message confidentiality
+ services are available, and will never be returned TRUE unless the
+ integ_avail flag is also returned TRUE
+
+ GSS-API callers desiring per-message security services should
+ check the values of these flags at context establishment time, and
+ must be aware that a returned FALSE value for integ_avail means
+ that invocation of GSS_GetMIC() or GSS_Wrap() primitives on the
+ associated context will apply no cryptographic protection to user
+ data messages.
+
+ The GSS-API per-message integrity and data origin authentication
+ services provide assurance to a receiving caller that protection was
+ applied to a message by the caller's peer on the security context,
+ corresponding to the entity named at context initiation. The GSS-API
+ per-message confidentiality service provides assurance to a sending
+ caller that the message's content is protected from access by
+ entities other than the context's named peer.
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 17]
+
+RFC 2078 GSS-API January 1997
+
+
+ The GSS-API per-message protection service primitives, as the
+ category name implies, are oriented to operation at the granularity
+ of protocol data units. They perform cryptographic operations on the
+ data units, transfer cryptographic control information in tokens,
+ and, in the case of GSS_Wrap(), encapsulate the protected data unit.
+ As such, these primitives are not oriented to efficient data
+ protection for stream-paradigm protocols (e.g., Telnet) if
+ cryptography must be applied on an octet-by-octet basis.
+
+1.2.3: Per-Message Replay Detection and Sequencing
+
+ Certain underlying mech_types offer support for replay detection
+ and/or sequencing of messages transferred on the contexts they
+ support. These optionally-selectable protection features are distinct
+ from replay detection and sequencing features applied to the context
+ establishment operation itself; the presence or absence of context-
+ level replay or sequencing features is wholly a function of the
+ underlying mech_type's capabilities, and is not selected or omitted
+ as a caller option.
+
+ The caller initiating a context provides flags (replay_det_req_flag
+ and sequence_req_flag) to specify whether the use of per-message
+ replay detection and sequencing features is desired on the context
+ being established. The GSS-API implementation at the initiator system
+ can determine whether these features are supported (and whether they
+ are optionally selectable) as a function of mech_type, without need
+ for bilateral negotiation with the target. When enabled, these
+ features provide recipients with indicators as a result of GSS-API
+ processing of incoming messages, identifying whether those messages
+ were detected as duplicates or out-of-sequence. Detection of such
+ events does not prevent a suspect message from being provided to a
+ recipient; the appropriate course of action on a suspect message is a
+ matter of caller policy.
+
+ The semantics of the replay detection and sequencing services applied
+ to received messages, as visible across the interface which the GSS-
+ API provides to its clients, are as follows:
+
+ When replay_det_state is TRUE, the possible major_status returns for
+ well-formed and correctly signed messages are as follows:
+
+ 1. GSS_S_COMPLETE indicates that the message was within the window
+ (of time or sequence space) allowing replay events to be detected,
+ and that the message was not a replay of a previously-processed
+ message within that window.
+
+
+
+
+
+
+Linn Standards Track [Page 18]
+
+RFC 2078 GSS-API January 1997
+
+
+ 2. GSS_S_DUPLICATE_TOKEN indicates that the cryptographic
+ checkvalue on the received message was correct, but that the
+ message was recognized as a duplicate of a previously-processed
+ message.
+
+ 3. GSS_S_OLD_TOKEN indicates that the cryptographic checkvalue on
+ the received message was correct, but that the message is too old
+ to be checked for duplication.
+
+ When sequence_state is TRUE, the possible major_status returns for
+ well-formed and correctly signed messages are as follows:
+
+ 1. GSS_S_COMPLETE indicates that the message was within the window
+ (of time or sequence space) allowing replay events to be detected,
+ that the message was not a replay of a previously-processed
+ message within that window, and that no predecessor sequenced
+ messages are missing relative to the last received message (if
+ any) processed on the context with a correct cryptographic
+ checkvalue.
+
+ 2. GSS_S_DUPLICATE_TOKEN indicates that the integrity check value
+ on the received message was correct, but that the message was
+ recognized as a duplicate of a previously-processed message.
+
+ 3. GSS_S_OLD_TOKEN indicates that the integrity check value on the
+ received message was correct, but that the token is too old to be
+ checked for duplication.
+
+ 4. GSS_S_UNSEQ_TOKEN indicates that the cryptographic checkvalue
+ on the received message was correct, but that it is earlier in a
+ sequenced stream than a message already processed on the context.
+ [Note: Mechanisms can be architected to provide a stricter form of
+ sequencing service, delivering particular messages to recipients
+ only after all predecessor messages in an ordered stream have been
+ delivered. This type of support is incompatible with the GSS-API
+ paradigm in which recipients receive all messages, whether in
+ order or not, and provide them (one at a time, without intra-GSS-
+ API message buffering) to GSS-API routines for validation. GSS-
+ API facilities provide supportive functions, aiding clients to
+ achieve strict message stream integrity in an efficient manner in
+ conjunction with sequencing provisions in communications
+ protocols, but the GSS-API does not offer this level of message
+ stream integrity service by itself.]
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 19]
+
+RFC 2078 GSS-API January 1997
+
+
+ 5. GSS_S_GAP_TOKEN indicates that the cryptographic checkvalue on
+ the received message was correct, but that one or more predecessor
+ sequenced messages have not been successfully processed relative
+ to the last received message (if any) processed on the context
+ with a correct cryptographic checkvalue.
+
+ As the message stream integrity features (especially sequencing) may
+ interfere with certain applications' intended communications
+ paradigms, and since support for such features is likely to be
+ resource intensive, it is highly recommended that mech_types
+ supporting these features allow them to be activated selectively on
+ initiator request when a context is established. A context initiator
+ and target are provided with corresponding indicators
+ (replay_det_state and sequence_state), signifying whether these
+ features are active on a given context.
+
+ An example mech_type supporting per-message replay detection could
+ (when replay_det_state is TRUE) implement the feature as follows: The
+ underlying mechanism would insert timestamps in data elements output
+ by GSS_GetMIC() and GSS_Wrap(), and would maintain (within a time-
+ limited window) a cache (qualified by originator-recipient pair)
+ identifying received data elements processed by GSS_VerifyMIC() and
+ GSS_Unwrap(). When this feature is active, exception status returns
+ (GSS_S_DUPLICATE_TOKEN, GSS_S_OLD_TOKEN) will be provided when
+ GSS_VerifyMIC() or GSS_Unwrap() is presented with a message which is
+ either a detected duplicate of a prior message or which is too old to
+ validate against a cache of recently received messages.
+
+1.2.4: Quality of Protection
+
+ Some mech_types provide their users with fine granularity control
+ over the means used to provide per-message protection, allowing
+ callers to trade off security processing overhead dynamically against
+ the protection requirements of particular messages. A per-message
+ quality-of-protection parameter (analogous to quality-of-service, or
+ QOS) selects among different QOP options supported by that mechanism.
+ On context establishment for a multi-QOP mech_type, context-level
+ data provides the prerequisite data for a range of protection
+ qualities.
+
+ It is expected that the majority of callers will not wish to exert
+ explicit mechanism-specific QOP control and will therefore request
+ selection of a default QOP. Definitions of, and choices among, non-
+ default QOP values are mechanism-specific, and no ordered sequences
+ of QOP values can be assumed equivalent across different mechanisms.
+ Meaningful use of non-default QOP values demands that callers be
+ familiar with the QOP definitions of an underlying mechanism or
+ mechanisms, and is therefore a non-portable construct. The
+
+
+
+Linn Standards Track [Page 20]
+
+RFC 2078 GSS-API January 1997
+
+
+ GSS_S_BAD_QOP major_status value is defined in order to indicate that
+ a provided QOP value is unsupported for a security context, most
+ likely because that value is unrecognized by the underlying
+ mechanism.
+
+1.2.5: Anonymity Support
+
+ In certain situations or environments, an application may wish to
+ authenticate a peer and/or protect communications using GSS-API per-
+ message services without revealing its own identity. For example,
+ consider an application which provides read access to a research
+ database, and which permits queries by arbitrary requestors. A
+ client of such a service might wish to authenticate the service, to
+ establish trust in the information received from it, but might not
+ wish to disclose its identity to the service for privacy reasons.
+
+ In ordinary GSS-API usage, a context initiator's identity is made
+ available to the context acceptor as part of the context
+ establishment process. To provide for anonymity support, a facility
+ (input anon_req_flag to GSS_Init_sec_context()) is provided through
+ which context initiators may request that their identity not be
+ provided to the context acceptor. Mechanisms are not required to
+ honor this request, but a caller will be informed (via returned
+ anon_state indicator from GSS_Init_sec_context()) whether or not the
+ request is honored. Note that authentication as the anonymous
+ principal does not necessarily imply that credentials are not
+ required in order to establish a context.
+
+ The following Object Identifier value is provided as a means to
+ identify anonymous names, and can be compared against in order to
+ determine, in a mechanism-independent fashion, whether a name refers
+ to an anonymous principal:
+
+ {1(iso), 3(org), 6(dod), 1(internet), 5(security), 6(nametypes),
+ 3(gss-anonymous-name)}
+
+ The recommended symbolic name corresponding to this definition is
+ GSS_C_NT_ANONYMOUS.
+
+ Four possible combinations of anon_state and mutual_state are
+ possible, with the following results:
+
+ anon_state == FALSE, mutual_state == FALSE: initiator
+ authenticated to target.
+
+ anon_state == FALSE, mutual_state == TRUE: initiator authenticated
+ to target, target authenticated to initiator.
+
+
+
+
+Linn Standards Track [Page 21]
+
+RFC 2078 GSS-API January 1997
+
+
+ anon_state == TRUE, mutual_state == FALSE: initiator authenticated
+ as anonymous principal to target.
+
+ anon_state == TRUE, mutual_state == TRUE: initiator authenticated
+ as anonymous principal to target, target authenticated to
+ initiator.
+
+1.2.6: Initialization
+
+ No initialization calls (i.e., calls which must be invoked prior to
+ invocation of other facilities in the interface) are defined in GSS-
+ API. As an implication of this fact, GSS-API implementations must
+ themselves be self-initializing.
+
+1.2.7: Per-Message Protection During Context Establishment
+
+ A facility is defined in GSS-V2 to enable protection and buffering of
+ data messages for later transfer while a security context's
+ establishment is in GSS_S_CONTINUE_NEEDED status, to be used in cases
+ where the caller side already possesses the necessary session key to
+ enable this processing. Specifically, a new state Boolean, called
+ prot_ready_state, is added to the set of information returned by
+ GSS_Init_sec_context(), GSS_Accept_sec_context(), and
+ GSS_Inquire_context().
+
+ For context establishment calls, this state Boolean is valid and
+ interpretable when the associated major_status is either
+ GSS_S_CONTINUE_NEEDED, or GSS_S_COMPLETE. Callers of GSS-API (both
+ initiators and acceptors) can assume that per-message protection (via
+ GSS_Wrap(), GSS_Unwrap(), GSS_GetMIC() and GSS_VerifyMIC()) is
+ available and ready for use if either: prot_ready_state == TRUE, or
+ major_status == GSS_S_COMPLETE, though mutual authentication (if
+ requested) cannot be guaranteed until GSS_S_COMPLETE is returned.
+
+ This achieves full, transparent backward compatibility for GSS-API V1
+ callers, who need not even know of the existence of prot_ready_state,
+ and who will get the expected behavior from GSS_S_COMPLETE, but who
+ will not be able to use per-message protection before GSS_S_COMPLETE
+ is returned.
+
+ It is not a requirement that GSS-V2 mechanisms ever return TRUE
+ prot_ready_state before completion of context establishment (indeed,
+ some mechanisms will not evolve usable message protection keys,
+ especially at the context acceptor, before context establishment is
+ complete). It is expected but not required that GSS-V2 mechanisms
+ will return TRUE prot_ready_state upon completion of context
+ establishment if they support per-message protection at all (however
+ GSS-V2 applications should not assume that TRUE prot_ready_state will
+
+
+
+Linn Standards Track [Page 22]
+
+RFC 2078 GSS-API January 1997
+
+
+ always be returned together with the GSS_S_COMPLETE major_status,
+ since GSS-V2 implementations may continue to support GSS-V1 mechanism
+ code, which will never return TRUE prot_ready_state).
+
+ When prot_ready_state is returned TRUE, mechanisms shall also set
+ those context service indicator flags (deleg_state, mutual_state,
+ replay_det_state, sequence_state, anon_state, trans_state,
+ conf_avail, integ_avail) which represent facilities confirmed, at
+ that time, to be available on the context being established. In
+ situations where prot_ready_state is returned before GSS_S_COMPLETE,
+ it is possible that additional facilities may be confirmed and
+ subsequently indicated when GSS_S_COMPLETE is returned.
+
+1.2.8: Implementation Robustness
+
+ This section recommends aspects of GSS-API implementation behavior in
+ the interests of overall robustness.
+
+ If a token is presented for processing on a GSS-API security context
+ and that token is determined to be invalid for that context, the
+ context's state should not be disrupted for purposes of processing
+ subsequent valid tokens.
+
+ Certain local conditions at a GSS-API implementation (e.g.,
+ unavailability of memory) may preclude, temporarily or permanently,
+ the successful processing of tokens on a GSS-API security context,
+ typically generating GSS_S_FAILURE major_status returns along with
+ locally-significant minor_status. For robust operation under such
+ conditions, the following recommendations are made:
+
+ Failing calls should free any memory they allocate, so that
+ callers may retry without causing further loss of resources.
+
+ Failure of an individual call on an established context should not
+ preclude subsequent calls from succeeding on the same context.
+
+ Whenever possible, it should be possible for
+ GSS_Delete_sec_context() calls to be successfully processed even
+ if other calls cannot succeed, thereby enabling context-related
+ resources to be released.
+
+2: Interface Descriptions
+
+ This section describes the GSS-API's service interface, dividing the
+ set of calls offered into four groups. Credential management calls
+ are related to the acquisition and release of credentials by
+ principals. Context-level calls are related to the management of
+ security contexts between principals. Per-message calls are related
+
+
+
+Linn Standards Track [Page 23]
+
+RFC 2078 GSS-API January 1997
+
+
+ to the protection of individual messages on established security
+ contexts. Support calls provide ancillary functions useful to GSS-API
+ callers. Table 2 groups and summarizes the calls in tabular fashion.
+
+Table 2: GSS-API Calls
+
+ CREDENTIAL MANAGEMENT
+
+ GSS_Acquire_cred acquire credentials for use
+ GSS_Release_cred release credentials after use
+ GSS_Inquire_cred display information about
+ credentials
+ GSS_Add_cred construct credentials incrementally
+ GSS_Inquire_cred_by_mech display per-mechanism credential
+ information
+
+ CONTEXT-LEVEL CALLS
+
+ GSS_Init_sec_context initiate outbound security context
+ GSS_Accept_sec_context accept inbound security context
+ GSS_Delete_sec_context flush context when no longer needed
+ GSS_Process_context_token process received control token on
+ context
+ GSS_Context_time indicate validity time remaining on
+ context
+ GSS_Inquire_context display information about context
+ GSS_Wrap_size_limit determine GSS_Wrap token size limit
+ GSS_Export_sec_context transfer context to other process
+ GSS_Import_sec_context import transferred context
+
+ PER-MESSAGE CALLS
+
+ GSS_GetMIC apply integrity check, receive as
+ token separate from message
+ GSS_VerifyMIC validate integrity check token
+ along with message
+ GSS_Wrap sign, optionally encrypt,
+ encapsulate
+ GSS_Unwrap decapsulate, decrypt if needed,
+ validate integrity check
+
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 24]
+
+RFC 2078 GSS-API January 1997
+
+
+ SUPPORT CALLS
+
+ GSS_Display_status translate status codes to printable
+ form
+ GSS_Indicate_mechs indicate mech_types supported on
+ local system
+ GSS_Compare_name compare two names for equality
+ GSS_Display_name translate name to printable form
+ GSS_Import_name convert printable name to
+ normalized form
+ GSS_Release_name free storage of normalized-form
+ name
+ GSS_Release_buffer free storage of printable name
+ GSS_Release_OID free storage of OID object
+ GSS_Release_OID_set free storage of OID set object
+ GSS_Create_empty_OID_set create empty OID set
+ GSS_Add_OID_set_member add member to OID set
+ GSS_Test_OID_set_member test if OID is member of OID set
+ GSS_OID_to_str display OID as string
+ GSS_Str_to_OID construct OID from string
+ GSS_Inquire_names_for_mech indicate name types supported by
+ mechanism
+ GSS_Inquire_mechs_for_name indicates mechanisms supporting name
+ type
+ GSS_Canonicalize_name translate name to per-mechanism form
+ GSS_Export_name externalize per-mechanism name
+ GSS_Duplicate_name duplicate name object
+
+2.1: Credential management calls
+
+ These GSS-API calls provide functions related to the management of
+ credentials. Their characterization with regard to whether or not
+ they may block pending exchanges with other network entities (e.g.,
+ directories or authentication servers) depends in part on OS-specific
+ (extra-GSS-API) issues, so is not specified in this document.
+
+ The GSS_Acquire_cred() call is defined within the GSS-API in support
+ of application portability, with a particular orientation towards
+ support of portable server applications. It is recognized that (for
+ certain systems and mechanisms) credentials for interactive users may
+ be managed differently from credentials for server processes; in such
+ environments, it is the GSS-API implementation's responsibility to
+ distinguish these cases and the procedures for making this
+ distinction are a local matter. The GSS_Release_cred() call provides
+ a means for callers to indicate to the GSS-API that use of a
+ credentials structure is no longer required. The GSS_Inquire_cred()
+ call allows callers to determine information about a credentials
+ structure. The GSS_Add_cred() call enables callers to append
+
+
+
+Linn Standards Track [Page 25]
+
+RFC 2078 GSS-API January 1997
+
+
+ elements to an existing credential structure, allowing iterative
+ construction of a multi-mechanism credential. The
+ GSS_Inquire_cred_by_mech() call enables callers to extract per-
+ mechanism information describing a credentials structure.
+
+2.1.1: GSS_Acquire_cred call
+
+ Inputs:
+
+ o desired_name INTERNAL NAME, -NULL requests locally-determined
+ default
+
+ o lifetime_req INTEGER,-in seconds; 0 requests default
+
+ o desired_mechs SET OF OBJECT IDENTIFIER,-empty set requests
+ system-selected default
+
+ o cred_usage INTEGER -0=INITIATE-AND-ACCEPT, 1=INITIATE-ONLY,
+ 2=ACCEPT-ONLY
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_cred_handle CREDENTIAL HANDLE,
+
+ o actual_mechs SET OF OBJECT IDENTIFIER,
+
+ o lifetime_rec INTEGER -in seconds, or reserved value for
+ INDEFINITE
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that requested credentials were
+ successfully established, for the duration indicated in
+ lifetime_rec, suitable for the usage requested in cred_usage,
+ for the set of mech_types indicated in actual_mechs, and that
+ those credentials can be referenced for subsequent use with
+ the handle returned in output_cred_handle.
+
+ o GSS_S_BAD_MECH indicates that a mech_type unsupported by the
+ GSS-API implementation type was requested, causing the
+ credential establishment operation to fail.
+
+
+
+
+
+
+Linn Standards Track [Page 26]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_BAD_NAMETYPE indicates that the provided desired_name is
+ uninterpretable or of a type unsupported by the applicable
+ underlying GSS-API mechanism(s), so no credentials could be
+ established for the accompanying desired_name.
+
+ o GSS_S_BAD_NAME indicates that the provided desired_name is
+ inconsistent in terms of internally-incorporated type specifier
+ information, so no credentials could be established for the
+ accompanying desired_name.
+
+ o GSS_S_FAILURE indicates that credential establishment failed
+ for reasons unspecified at the GSS-API level, including lack
+ of authorization to establish and use credentials associated
+ with the identity named in the input desired_name argument.
+
+ GSS_Acquire_cred() is used to acquire credentials so that a
+ principal can (as a function of the input cred_usage parameter)
+ initiate and/or accept security contexts under the identity
+ represented by the desired_name input argument. On successful
+ completion, the returned output_cred_handle result provides a handle
+ for subsequent references to the acquired credentials. Typically,
+ single-user client processes requesting that default credential
+ behavior be applied for context establishment purposes will have no
+ need to invoke this call.
+
+ A caller may provide the value NULL for desired_name, signifying a
+ request for credentials corresponding to a principal identity
+ selected by default for the caller. The procedures used by GSS-API
+ implementations to select the appropriate principal identity in
+ response to such a request are local matters. It is possible that
+ multiple pre-established credentials may exist for the same principal
+ identity (for example, as a result of multiple user login sessions)
+ when GSS_Acquire_cred() is called; the means used in such cases to
+ select a specific credential are local matters. The input
+ lifetime_req argument to GSS_Acquire_cred() may provide useful
+ information for local GSS-API implementations to employ in making
+ this disambiguation in a manner which will best satisfy a caller's
+ intent.
+
+ The lifetime_rec result indicates the length of time for which the
+ acquired credentials will be valid, as an offset from the present. A
+ mechanism may return a reserved value indicating INDEFINITE if no
+ constraints on credential lifetime are imposed. A caller of
+ GSS_Acquire_cred() can request a length of time for which acquired
+ credentials are to be valid (lifetime_req argument), beginning at the
+ present, or can request credentials with a default validity interval.
+ (Requests for postdated credentials are not supported within the
+ GSS-API.) Certain mechanisms and implementations may bind in
+
+
+
+Linn Standards Track [Page 27]
+
+RFC 2078 GSS-API January 1997
+
+
+ credential validity period specifiers at a point preliminary to
+ invocation of the GSS_Acquire_cred() call (e.g., in conjunction with
+ user login procedures). As a result, callers requesting non-default
+ values for lifetime_req must recognize that such requests cannot
+ always be honored and must be prepared to accommodate the use of
+ returned credentials with different lifetimes as indicated in
+ lifetime_rec.
+
+ The caller of GSS_Acquire_cred() can explicitly specify a set of
+ mech_types which are to be accommodated in the returned credentials
+ (desired_mechs argument), or can request credentials for a system-
+ defined default set of mech_types. Selection of the system-specified
+ default set is recommended in the interests of application
+ portability. The actual_mechs return value may be interrogated by the
+ caller to determine the set of mechanisms with which the returned
+ credentials may be used.
+
+2.1.2: GSS_Release_cred call
+
+ Input:
+
+ o cred_handle CREDENTIAL HANDLE - NULL specifies that
+ the credential elements used when default credential behavior
+ is requested be released.
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the credentials referenced by the
+ input cred_handle were released for purposes of subsequent
+ access by the caller. The effect on other processes which may
+ be authorized shared access to such credentials is a local
+ matter.
+
+ o GSS_S_NO_CRED indicates that no release operation was
+ performed, either because the input cred_handle was invalid or
+ because the caller lacks authorization to access the
+ referenced credentials.
+
+ o GSS_S_FAILURE indicates that the release operation failed for
+ reasons unspecified at the GSS-API level.
+
+
+
+
+
+Linn Standards Track [Page 28]
+
+RFC 2078 GSS-API January 1997
+
+
+ Provides a means for a caller to explicitly request that credentials
+ be released when their use is no longer required. Note that system-
+ specific credential management functions are also likely to exist,
+ for example to assure that credentials shared among processes are
+ properly deleted when all affected processes terminate, even if no
+ explicit release requests are issued by those processes. Given the
+ fact that multiple callers are not precluded from gaining authorized
+ access to the same credentials, invocation of GSS_Release_cred()
+ cannot be assumed to delete a particular set of credentials on a
+ system-wide basis.
+
+2.1.3: GSS_Inquire_cred call
+
+ Input:
+
+ o cred_handle CREDENTIAL HANDLE -NULL specifies that the
+ credential elements used when default credential behavior is
+ requested are to be queried
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o cred_name INTERNAL NAME,
+
+ o lifetime_rec INTEGER -in seconds, or reserved value for
+ INDEFINITE
+
+ o cred_usage INTEGER, -0=INITIATE-AND-ACCEPT, 1=INITIATE-ONLY,
+ 2=ACCEPT-ONLY
+
+ o mech_set SET OF OBJECT IDENTIFIER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the credentials referenced by the
+ input cred_handle argument were valid, and that the output
+ cred_name, lifetime_rec, and cred_usage values represent,
+ respectively, the credentials' associated principal name,
+ remaining lifetime, suitable usage modes, and supported
+ mechanism types.
+
+ o GSS_S_NO_CRED indicates that no information could be returned
+ about the referenced credentials, either because the input
+ cred_handle was invalid or because the caller lacks
+ authorization to access the referenced credentials.
+
+
+
+Linn Standards Track [Page 29]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_DEFECTIVE_CREDENTIAL indicates that the referenced
+ credentials are invalid.
+
+ o GSS_S_CREDENTIALS_EXPIRED indicates that the referenced
+ credentials have expired.
+
+ o GSS_S_FAILURE indicates that the operation failed for
+ reasons unspecified at the GSS-API level.
+
+ The GSS_Inquire_cred() call is defined primarily for the use of those
+ callers which request use of default credential behavior rather than
+ acquiring credentials explicitly with GSS_Acquire_cred(). It enables
+ callers to determine a credential structure's associated principal
+ name, remaining validity period, usability for security context
+ initiation and/or acceptance, and supported mechanisms.
+
+ For a multi-mechanism credential, the returned "lifetime" specifier
+ indicates the shortest lifetime of any of the mechanisms' elements in
+ the credential (for either context initiation or acceptance
+ purposes).
+
+ GSS_Inquire_cred() should indicate INITIATE-AND-ACCEPT for
+ "cred_usage" if both of the following conditions hold:
+
+ (1) there exists in the credential an element which allows context
+ initiation using some mechanism
+
+ (2) there exists in the credential an element which allows context
+ acceptance using some mechanism (allowably, but not necessarily,
+ one of the same mechanism(s) qualifying for (1)).
+
+ If condition (1) holds but not condition (2), GSS_Inquire_cred()
+ should indicate INITIATE-ONLY for "cred_usage". If condition (2)
+ holds but not condition (1), GSS_Inquire_cred() should indicate
+ ACCEPT-ONLY for "cred_usage".
+
+ Callers requiring finer disambiguation among available combinations
+ of lifetimes, usage modes, and mechanisms should call the
+ GSS_Inquire_cred_by_mech() routine, passing that routine one of the
+ mech OIDs returned by GSS_Inquire_cred().
+
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 30]
+
+RFC 2078 GSS-API January 1997
+
+
+2.1.4: GSS_Add_cred call
+
+ Inputs:
+
+ o input_cred_handle CREDENTIAL HANDLE - handle to credential
+ structure created with prior GSS_Acquire_cred() or
+ GSS_Add_cred() call, or NULL to append elements to the set
+ which are applied for the caller when default credential
+ behavior is specified.
+
+ o desired_name INTERNAL NAME - NULL requests locally-determined
+ default
+
+ o initiator_time_req INTEGER - in seconds; 0 requests default
+
+ o acceptor_time_req INTEGER - in seconds; 0 requests default
+
+ o desired_mech OBJECT IDENTIFIER
+
+ o cred_usage INTEGER - 0=INITIATE-AND-ACCEPT, 1=INITIATE-ONLY,
+ 2=ACCEPT-ONLY
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_cred_handle CREDENTIAL HANDLE, - NULL to request that
+ credential elements be added "in place" to the credential
+ structure identified by input_cred_handle, non-NULL pointer
+ to request that a new credential structure and handle be created.
+
+ o actual_mechs SET OF OBJECT IDENTIFIER,
+
+ o initiator_time_rec INTEGER - in seconds, or reserved value for
+ INDEFINITE
+
+ o acceptor_time_rec INTEGER - in seconds, or reserved value for
+ INDEFINITE
+
+ o cred_usage INTEGER, -0=INITIATE-AND-ACCEPT, 1=INITIATE-ONLY,
+ 2=ACCEPT-ONLY
+
+ o mech_set SET OF OBJECT IDENTIFIER -- full set of mechanisms
+ supported by resulting credential.
+
+
+
+
+
+Linn Standards Track [Page 31]
+
+RFC 2078 GSS-API January 1997
+
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the credentials referenced by
+ the input_cred_handle argument were valid, and that the
+ resulting credential from GSS_Add_cred() is valid for the
+ durations indicated in initiator_time_rec and acceptor_time_rec,
+ suitable for the usage requested in cred_usage, and for the
+ mechanisms indicated in actual_mechs.
+
+ o GSS_S_DUPLICATE_ELEMENT indicates that the input desired_mech
+ specified a mechanism for which the referenced credential
+ already contained a credential element with overlapping
+ cred_usage and validity time specifiers.
+
+ o GSS_S_BAD_MECH indicates that the input desired_mech specified
+ a mechanism unsupported by the GSS-API implementation, causing
+ the GSS_Add_cred() operation to fail.
+
+ o GSS_S_BAD_NAMETYPE indicates that the provided desired_name
+ is uninterpretable or of a type unsupported by the applicable
+ underlying GSS-API mechanism(s), so the GSS_Add_cred() operation
+ could not be performed for that name.
+
+ o GSS_S_BAD_NAME indicates that the provided desired_name is
+ inconsistent in terms of internally-incorporated type specifier
+ information, so the GSS_Add_cred() operation could not be
+ performed for that name.
+
+ o GSS_S_NO_CRED indicates that the input_cred_handle referenced
+ invalid or inaccessible credentials.
+
+ o GSS_S_FAILURE indicates that the operation failed for
+ reasons unspecified at the GSS-API level, including lack of
+ authorization to establish or use credentials representing
+ the requested identity.
+
+ GSS_Add_cred() enables callers to construct credentials iteratively
+ by adding credential elements in successive operations, corresponding
+ to different mechanisms. This offers particular value in multi-
+ mechanism environments, as the major_status and minor_status values
+ returned on each iteration are individually visible and can therefore
+ be interpreted unambiguously on a per-mechanism basis.
+
+ The same input desired_name, or default reference, should be used on
+ all GSS_Acquire_cred() and GSS_Add_cred() calls corresponding to a
+ particular credential.
+
+
+
+
+
+Linn Standards Track [Page 32]
+
+RFC 2078 GSS-API January 1997
+
+
+2.1.5: GSS_Inquire_cred_by_mech call
+
+ Inputs:
+
+ o cred_handle CREDENTIAL HANDLE -- NULL specifies that the
+ credential elements used when default credential behavior is
+ requested are to be queried
+
+ o mech_type OBJECT IDENTIFIER -- specific mechanism for
+ which credentials are being queried
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o cred_name INTERNAL NAME, -- guaranteed to be MN
+
+ o lifetime_rec_initiate INTEGER -- in seconds, or reserved value for
+ INDEFINITE
+
+ o lifetime_rec_accept INTEGER -- in seconds, or reserved value for
+ INDEFINITE
+
+ o cred_usage INTEGER, -0=INITIATE-AND-ACCEPT, 1=INITIATE-ONLY,
+ 2=ACCEPT-ONLY
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the credentials referenced by the
+ input cred_handle argument were valid, that the mechanism
+ indicated by the input mech_type was represented with elements
+ within those credentials, and that the output cred_name,
+ lifetime_rec_initiate, lifetime_rec_accept, and cred_usage values
+ represent, respectively, the credentials' associated principal
+ name, remaining lifetimes, and suitable usage modes.
+
+ o GSS_S_NO_CRED indicates that no information could be returned
+ about the referenced credentials, either because the input
+ cred_handle was invalid or because the caller lacks
+ authorization to access the referenced credentials.
+
+ o GSS_S_DEFECTIVE_CREDENTIAL indicates that the referenced
+ credentials are invalid.
+
+ o GSS_S_CREDENTIALS_EXPIRED indicates that the referenced
+ credentials have expired.
+
+
+
+Linn Standards Track [Page 33]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_BAD_MECH indicates that the referenced credentials do not
+ contain elements for the requested mechanism.
+
+ o GSS_S_FAILURE indicates that the operation failed for reasons
+ unspecified at the GSS-API level.
+
+ The GSS_Inquire_cred_by_mech() call enables callers in multi-
+ mechanism environments to acquire specific data about available
+ combinations of lifetimes, usage modes, and mechanisms within a
+ credential structure. The lifetime_rec_initiate result indicates the
+ available lifetime for context initiation purposes; the
+ lifetime_rec_accept result indicates the available lifetime for
+ context acceptance purposes.
+
+2.2: Context-level calls
+
+ This group of calls is devoted to the establishment and management of
+ security contexts between peers. A context's initiator calls
+ GSS_Init_sec_context(), resulting in generation of a token which the
+ caller passes to the target. At the target, that token is passed to
+ GSS_Accept_sec_context(). Depending on the underlying mech_type and
+ specified options, additional token exchanges may be performed in the
+ course of context establishment; such exchanges are accommodated by
+ GSS_S_CONTINUE_NEEDED status returns from GSS_Init_sec_context() and
+ GSS_Accept_sec_context().
+
+ Either party to an established context may invoke
+ GSS_Delete_sec_context() to flush context information when a context
+ is no longer required. GSS_Process_context_token() is used to
+ process received tokens carrying context-level control information.
+ GSS_Context_time() allows a caller to determine the length of time
+ for which an established context will remain valid.
+ GSS_Inquire_context() returns status information describing context
+ characteristics. GSS_Wrap_size_limit() allows a caller to determine
+ the size of a token which will be generated by a GSS_Wrap()
+ operation. GSS_Export_sec_context() and GSS_Import_sec_context()
+ enable transfer of active contexts between processes on an end
+ system.
+
+2.2.1: GSS_Init_sec_context call
+
+ Inputs:
+
+ o claimant_cred_handle CREDENTIAL HANDLE, -NULL specifies "use
+ default"
+
+ o input_context_handle CONTEXT HANDLE, -0 specifies "none assigned
+ yet"
+
+
+
+Linn Standards Track [Page 34]
+
+RFC 2078 GSS-API January 1997
+
+
+ o targ_name INTERNAL NAME,
+
+ o mech_type OBJECT IDENTIFIER, -NULL parameter specifies "use
+ default"
+
+ o deleg_req_flag BOOLEAN,
+
+ o mutual_req_flag BOOLEAN,
+
+ o replay_det_req_flag BOOLEAN,
+
+ o sequence_req_flag BOOLEAN,
+
+ o anon_req_flag BOOLEAN,
+
+ o lifetime_req INTEGER,-0 specifies default lifetime
+
+ o chan_bindings OCTET STRING,
+
+ o input_token OCTET STRING-NULL or token received from target
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_context_handle CONTEXT HANDLE,
+
+ o mech_type OBJECT IDENTIFIER, -actual mechanism always
+ indicated, never NULL
+
+ o output_token OCTET STRING, -NULL or token to pass to context
+ target
+
+ o deleg_state BOOLEAN,
+
+ o mutual_state BOOLEAN,
+
+ o replay_det_state BOOLEAN,
+
+ o sequence_state BOOLEAN,
+
+ o anon_state BOOLEAN,
+
+ o trans_state BOOLEAN,
+
+ o prot_ready_state BOOLEAN, -- see Section 1.2.7
+
+
+
+Linn Standards Track [Page 35]
+
+RFC 2078 GSS-API January 1997
+
+
+ o conf_avail BOOLEAN,
+
+ o integ_avail BOOLEAN,
+
+ o lifetime_rec INTEGER - in seconds, or reserved value for
+ INDEFINITE
+
+ This call may block pending network interactions for those mech_types
+ in which an authentication server or other network entity must be
+ consulted on behalf of a context initiator in order to generate an
+ output_token suitable for presentation to a specified target.
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that context-level information was
+ successfully initialized, and that the returned output_token
+ will provide sufficient information for the target to perform
+ per-message processing on the newly-established context.
+
+ o GSS_S_CONTINUE_NEEDED indicates that control information in the
+ returned output_token must be sent to the target, and that a
+ reply must be received and passed as the input_token argument
+ to a continuation call to GSS_Init_sec_context(), before
+ per-message processing can be performed in conjunction with
+ this context.
+
+ o GSS_S_DEFECTIVE_TOKEN indicates that consistency checks
+ performed on the input_token failed, preventing further
+ processing from being performed based on that token.
+
+ o GSS_S_DEFECTIVE_CREDENTIAL indicates that consistency checks
+ performed on the credential structure referenced by
+ claimant_cred_handle failed, preventing further processing from
+ being performed using that credential structure.
+
+ o GSS_S_BAD_SIG indicates that the received input_token
+ contains an incorrect integrity check, so context setup cannot
+ be accomplished.
+
+ o GSS_S_NO_CRED indicates that no context was established,
+ either because the input cred_handle was invalid, because the
+ referenced credentials are valid for context acceptor use
+ only, or because the caller lacks authorization to access the
+ referenced credentials.
+
+ o GSS_S_CREDENTIALS_EXPIRED indicates that the credentials
+ provided through the input claimant_cred_handle argument are no
+ longer valid, so context establishment cannot be completed.
+
+
+
+Linn Standards Track [Page 36]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_BAD_BINDINGS indicates that a mismatch between the
+ caller-provided chan_bindings and those extracted from the
+ input_token was detected, signifying a security-relevant
+ event and preventing context establishment. (This result will
+ be returned by GSS_Init_sec_context only for contexts where
+ mutual_state is TRUE.)
+
+ o GSS_S_OLD_TOKEN indicates that the input_token is too old to
+ be checked for integrity. This is a fatal error during context
+ establishment.
+
+ o GSS_S_DUPLICATE_TOKEN indicates that the input token has a
+ correct integrity check, but is a duplicate of a token already
+ processed. This is a fatal error during context establishment.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided; this major status will
+ be returned only for successor calls following GSS_S_CONTINUE_
+ NEEDED status returns.
+
+ o GSS_S_BAD_NAMETYPE indicates that the provided targ_name is
+ of a type uninterpretable or unsupported by the applicable
+ underlying GSS-API mechanism(s), so context establishment
+ cannot be completed.
+
+ o GSS_S_BAD_NAME indicates that the provided targ_name is
+ inconsistent in terms of internally-incorporated type specifier
+ information, so context establishment cannot be accomplished.
+
+ o GSS_S_BAD_MECH indicates receipt of a context establishment token
+ or of a caller request specifying a mechanism unsupported by
+ the local system or with the caller's active credentials
+
+ o GSS_S_FAILURE indicates that context setup could not be
+ accomplished for reasons unspecified at the GSS-API level, and
+ that no interface-defined recovery action is available.
+
+ This routine is used by a context initiator, and ordinarily emits one
+ (or, for the case of a multi-step exchange, more than one)
+ output_token suitable for use by the target within the selected
+ mech_type's protocol. Using information in the credentials structure
+ referenced by claimant_cred_handle, GSS_Init_sec_context()
+ initializes the data structures required to establish a security
+ context with target targ_name. The targ_name may be any valid
+ INTERNAL NAME; it need not be an MN. The claimant_cred_handle must
+ correspond to the same valid credentials structure on the initial
+ call to GSS_Init_sec_context() and on any successor calls resulting
+ from GSS_S_CONTINUE_NEEDED status returns; different protocol
+
+
+
+Linn Standards Track [Page 37]
+
+RFC 2078 GSS-API January 1997
+
+
+ sequences modeled by the GSS_S_CONTINUE_NEEDED facility will require
+ access to credentials at different points in the context
+ establishment sequence.
+
+ The input_context_handle argument is 0, specifying "not yet
+ assigned", on the first GSS_Init_sec_context() call relating to a
+ given context. If successful (i.e., if accompanied by major_status
+ GSS_S_COMPLETE or GSS_S_CONTINUE_NEEDED), and only if successful, the
+ initial GSS_Init_sec_context() call returns a non-zero
+ output_context_handle for use in future references to this context.
+ Once a non-zero output_context_handle has been returned, GSS-API
+ callers should call GSS_Delete_sec_context() to release context-
+ related resources if errors occur in later phases of context
+ establishment, or when an established context is no longer required.
+
+ When continuation attempts to GSS_Init_sec_context() are needed to
+ perform context establishment, the previously-returned non-zero
+ handle value is entered into the input_context_handle argument and
+ will be echoed in the returned output_context_handle argument. On
+ such continuation attempts (and only on continuation attempts) the
+ input_token value is used, to provide the token returned from the
+ context's target.
+
+ The chan_bindings argument is used by the caller to provide
+ information binding the security context to security-related
+ characteristics (e.g., addresses, cryptographic keys) of the
+ underlying communications channel. See Section 1.1.6 of this document
+ for more discussion of this argument's usage.
+
+ The input_token argument contains a message received from the target,
+ and is significant only on a call to GSS_Init_sec_context() which
+ follows a previous return indicating GSS_S_CONTINUE_NEEDED
+ major_status.
+
+ It is the caller's responsibility to establish a communications path
+ to the target, and to transmit any returned output_token (independent
+ of the accompanying returned major_status value) to the target over
+ that path. The output_token can, however, be transmitted along with
+ the first application-provided input message to be processed by
+ GSS_GetMIC() or GSS_Wrap() in conjunction with a successfully-
+ established context.
+
+ The initiator may request various context-level functions through
+ input flags: the deleg_req_flag requests delegation of access rights,
+ the mutual_req_flag requests mutual authentication, the
+ replay_det_req_flag requests that replay detection features be
+ applied to messages transferred on the established context, and the
+ sequence_req_flag requests that sequencing be enforced. (See Section
+
+
+
+Linn Standards Track [Page 38]
+
+RFC 2078 GSS-API January 1997
+
+
+ 1.2.3 for more information on replay detection and sequencing
+ features.) The anon_req_flag requests that the initiator's identity
+ not be transferred within tokens to be sent to the acceptor.
+
+ Not all of the optionally-requestable features will be available in
+ all underlying mech_types. The corresponding return state values
+ deleg_state, mutual_state, replay_det_state, and sequence_state
+ indicate, as a function of mech_type processing capabilities and
+ initiator-provided input flags, the set of features which will be
+ active on the context. The returned trans_state value indicates
+ whether the context is transferable to other processes through use of
+ GSS_Export_sec_context(). These state indicators' values are
+ undefined unless either the routine's major_status indicates
+ GSS_S_COMPLETE, or TRUE prot_ready_state is returned along with
+ GSS_S_CONTINUE_NEEDED major_status; for the latter case, it is
+ possible that additional features, not confirmed or indicated along
+ with TRUE prot_ready_state, will be confirmed and indicated when
+ GSS_S_COMPLETE is subsequently returned.
+
+ The returned anon_state and prot_ready_state values are significant
+ for both GSS_S_COMPLETE and GSS_S_CONTINUE_NEEDED major_status
+ returns from GSS_Init_sec_context(). When anon_state is returned
+ TRUE, this indicates that neither the current token nor its
+ predecessors delivers or has delivered the initiator's identity.
+ Callers wishing to perform context establishment only if anonymity
+ support is provided should transfer a returned token from
+ GSS_Init_sec_context() to the peer only if it is accompanied by a
+ TRUE anon_state indicator. When prot_ready_state is returned TRUE in
+ conjunction with GSS_S_CONTINUE_NEEDED major_status, this indicates
+ that per-message protection operations may be applied on the context:
+ see Section 1.2.7 for further discussion of this facility.
+
+ Failure to provide the precise set of features requested by the
+ caller does not cause context establishment to fail; it is the
+ caller's prerogative to delete the context if the feature set
+ provided is unsuitable for the caller's use.
+
+ The returned mech_type value indicates the specific mechanism
+ employed on the context, is valid only along with major_status
+ GSS_S_COMPLETE, and will never indicate the value for "default".
+ Note that, for the case of certain mechanisms which themselves
+ perform negotiation, the returned mech_type result may indicate
+ selection of a mechanism identified by an OID different than that
+ passed in the input mech_type argument.
+
+ The conf_avail return value indicates whether the context supports
+ per-message confidentiality services, and so informs the caller
+ whether or not a request for encryption through the conf_req_flag
+
+
+
+Linn Standards Track [Page 39]
+
+RFC 2078 GSS-API January 1997
+
+
+ input to GSS_Wrap() can be honored. In similar fashion, the
+ integ_avail return value indicates whether per-message integrity
+ services are available (through either GSS_GetMIC() or GSS_Wrap()) on
+ the established context. These state indicators' values are undefined
+ unless either the routine's major_status indicates GSS_S_COMPLETE, or
+ TRUE prot_ready_state is returned along with GSS_S_CONTINUE_NEEDED
+ major_status.
+
+ The lifetime_req input specifies a desired upper bound for the
+ lifetime of the context to be established, with a value of 0 used to
+ request a default lifetime. The lifetime_rec return value indicates
+ the length of time for which the context will be valid, expressed as
+ an offset from the present; depending on mechanism capabilities,
+ credential lifetimes, and local policy, it may not correspond to the
+ value requested in lifetime_req. If no constraints on context
+ lifetime are imposed, this may be indicated by returning a reserved
+ value representing INDEFINITE lifetime_req. The value of lifetime_rec
+ is undefined unless the routine's major_status indicates
+ GSS_S_COMPLETE.
+
+ If the mutual_state is TRUE, this fact will be reflected within the
+ output_token. A call to GSS_Accept_sec_context() at the target in
+ conjunction with such a context will return a token, to be processed
+ by a continuation call to GSS_Init_sec_context(), in order to
+ achieve mutual authentication.
+
+2.2.2: GSS_Accept_sec_context call
+
+ Inputs:
+
+ o acceptor_cred_handle CREDENTIAL HANDLE, -- NULL specifies
+ "use default"
+
+ o input_context_handle CONTEXT HANDLE, -- 0 specifies
+ "not yet assigned"
+
+ o chan_bindings OCTET STRING,
+
+ o input_token OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o src_name INTERNAL NAME, -- guaranteed to be MN
+
+
+
+
+Linn Standards Track [Page 40]
+
+RFC 2078 GSS-API January 1997
+
+
+ o mech_type OBJECT IDENTIFIER,
+
+ o output_context_handle CONTEXT HANDLE,
+
+ o deleg_state BOOLEAN,
+
+ o mutual_state BOOLEAN,
+
+ o replay_det_state BOOLEAN,
+
+ o sequence_state BOOLEAN,
+
+ o anon_state BOOLEAN,
+
+ o trans_state BOOLEAN,
+
+ o prot_ready_state BOOLEAN, -- see Section 1.2.7 for discussion
+
+ o conf_avail BOOLEAN,
+
+ o integ_avail BOOLEAN,
+
+ o lifetime_rec INTEGER, - in seconds, or reserved value for
+ INDEFINITE
+
+ o delegated_cred_handle CREDENTIAL HANDLE,
+
+ o output_token OCTET STRING -NULL or token to pass to context
+ initiator
+
+ This call may block pending network interactions for those mech_types
+ in which a directory service or other network entity must be
+ consulted on behalf of a context acceptor in order to validate a
+ received input_token.
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that context-level data structures
+ were successfully initialized, and that per-message processing
+ can now be performed in conjunction with this context.
+
+ o GSS_S_CONTINUE_NEEDED indicates that control information in the
+ returned output_token must be sent to the initiator, and that
+ a response must be received and passed as the input_token
+ argument to a continuation call to GSS_Accept_sec_context(),
+ before per-message processing can be performed in conjunction
+ with this context.
+
+
+
+
+Linn Standards Track [Page 41]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_DEFECTIVE_TOKEN indicates that consistency checks performed
+ on the input_token failed, preventing further processing from
+ being performed based on that token.
+
+ o GSS_S_DEFECTIVE_CREDENTIAL indicates that consistency checks
+ performed on the credential structure referenced by
+ acceptor_cred_handle failed, preventing further processing from
+ being performed using that credential structure.
+
+ o GSS_S_BAD_SIG indicates that the received input_token contains
+ an incorrect integrity check, so context setup cannot be
+ accomplished.
+
+ o GSS_S_DUPLICATE_TOKEN indicates that the integrity check on the
+ received input_token was correct, but that the input_token
+ was recognized as a duplicate of an input_token already
+ processed. No new context is established.
+
+ o GSS_S_OLD_TOKEN indicates that the integrity check on the received
+ input_token was correct, but that the input_token is too old
+ to be checked for duplication against previously-processed
+ input_tokens. No new context is established.
+
+ o GSS_S_NO_CRED indicates that no context was established, either
+ because the input cred_handle was invalid, because the
+ referenced credentials are valid for context initiator use
+ only, or because the caller lacks authorization to access the
+ referenced credentials.
+
+ o GSS_S_CREDENTIALS_EXPIRED indicates that the credentials provided
+ through the input acceptor_cred_handle argument are no
+ longer valid, so context establishment cannot be completed.
+
+ o GSS_S_BAD_BINDINGS indicates that a mismatch between the
+ caller-provided chan_bindings and those extracted from the
+ input_token was detected, signifying a security-relevant
+ event and preventing context establishment.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided; this major status will
+ be returned only for successor calls following GSS_S_CONTINUE_
+ NEEDED status returns.
+
+ o GSS_S_BAD_MECH indicates receipt of a context establishment token
+ specifying a mechanism unsupported by the local system or with
+ the caller's active credentials.
+
+
+
+
+
+Linn Standards Track [Page 42]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_FAILURE indicates that context setup could not be
+ accomplished for reasons unspecified at the GSS-API level, and
+ that no interface-defined recovery action is available.
+
+ The GSS_Accept_sec_context() routine is used by a context target.
+ Using information in the credentials structure referenced by the
+ input acceptor_cred_handle, it verifies the incoming input_token and
+ (following the successful completion of a context establishment
+ sequence) returns the authenticated src_name and the mech_type used.
+ The returned src_name is guaranteed to be an MN, processed by the
+ mechanism under which the context was established. The
+ acceptor_cred_handle must correspond to the same valid credentials
+ structure on the initial call to GSS_Accept_sec_context() and on any
+ successor calls resulting from GSS_S_CONTINUE_NEEDED status returns;
+ different protocol sequences modeled by the GSS_S_CONTINUE_NEEDED
+ mechanism will require access to credentials at different points in
+ the context establishment sequence.
+
+ The input_context_handle argument is 0, specifying "not yet
+ assigned", on the first GSS_Accept_sec_context() call relating to a
+ given context. If successful (i.e., if accompanied by major_status
+ GSS_S_COMPLETE or GSS_S_CONTINUE_NEEDED), and only if successful, the
+ initial GSS_Accept_sec_context() call returns a non-zero
+ output_context_handle for use in future references to this context.
+ Once a non-zero output_context_handle has been returned, GSS-API
+ callers should call GSS_Delete_sec_context() to release context-
+ related resources if errors occur in later phases of context
+ establishment, or when an established context is no longer required.
+
+ The chan_bindings argument is used by the caller to provide
+ information binding the security context to security-related
+ characteristics (e.g., addresses, cryptographic keys) of the
+ underlying communications channel. See Section 1.1.6 of this document
+ for more discussion of this argument's usage.
+
+ The returned state results (deleg_state, mutual_state,
+ replay_det_state, sequence_state, anon_state, trans_state, and
+ prot_ready_state) reflect the same information as described for
+ GSS_Init_sec_context(), and their values are significant under the
+ same return state conditions.
+
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 43]
+
+RFC 2078 GSS-API January 1997
+
+
+ The conf_avail return value indicates whether the context supports
+ per-message confidentiality services, and so informs the caller
+ whether or not a request for encryption through the conf_req_flag
+ input to GSS_Wrap() can be honored. In similar fashion, the
+ integ_avail return value indicates whether per-message integrity
+ services are available (through either GSS_GetMIC() or GSS_Wrap())
+ on the established context. These values are significant under the
+ same return state conditions as described under
+ GSS_Init_sec_context().
+
+ The lifetime_rec return value is significant only in conjunction with
+ GSS_S_COMPLETE major_status, and indicates the length of time for
+ which the context will be valid, expressed as an offset from the
+ present.
+
+ The mech_type return value indicates the specific mechanism employed
+ on the context, is valid only along with major_status GSS_S_COMPLETE,
+ and will never indicate the value for "default".
+
+ The delegated_cred_handle result is significant only when deleg_state
+ is TRUE, and provides a means for the target to reference the
+ delegated credentials. The output_token result, when non-NULL,
+ provides a context-level token to be returned to the context
+ initiator to continue a multi-step context establishment sequence. As
+ noted with GSS_Init_sec_context(), any returned token should be
+ transferred to the context's peer (in this case, the context
+ initiator), independent of the value of the accompanying returned
+ major_status.
+
+ Note: A target must be able to distinguish a context-level
+ input_token, which is passed to GSS_Accept_sec_context(), from the
+ per-message data elements passed to GSS_VerifyMIC() or GSS_Unwrap().
+ These data elements may arrive in a single application message, and
+ GSS_Accept_sec_context() must be performed before per-message
+ processing can be performed successfully.
+
+2.2.3: GSS_Delete_sec_context call
+
+ Input:
+
+ o context_handle CONTEXT HANDLE
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+
+
+
+Linn Standards Track [Page 44]
+
+RFC 2078 GSS-API January 1997
+
+
+ o output_context_token OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the context was recognized, and that
+ relevant context-specific information was flushed. If the caller
+ provides a non-null buffer to receive an output_context_token, and
+ the mechanism returns a non-NULL token into that buffer, the
+ returned output_context_token is ready for transfer to the
+ context's peer.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided, so no deletion was
+ performed.
+
+ o GSS_S_FAILURE indicates that the context is recognized, but
+ that the GSS_Delete_sec_context() operation could not be
+ performed for reasons unspecified at the GSS-API level.
+
+ This call may block pending network interactions for mech_types in
+ which active notification must be made to a central server when a
+ security context is to be deleted.
+
+ This call can be made by either peer in a security context, to flush
+ context-specific information. If a non-null output_context_token
+ parameter is provided by the caller, an output_context_token may be
+ returned to the caller. If an output_context_token is provided to
+ the caller, it can be passed to the context's peer to inform the
+ peer's GSS-API implementation that the peer's corresponding context
+ information can also be flushed. (Once a context is established, the
+ peers involved are expected to retain cached credential and context-
+ related information until the information's expiration time is
+ reached or until a GSS_Delete_sec_context() call is made.)
+
+ The facility for context_token usage to signal context deletion is
+ retained for compatibility with GSS-API Version 1. For current
+ usage, it is recommended that both peers to a context invoke
+ GSS_Delete_sec_context() independently, passing a null
+ output_context_token buffer to indicate that no context_token is
+ required. Implementations of GSS_Delete_sec_context() should delete
+ relevant locally-stored context information.
+
+ Attempts to perform per-message processing on a deleted context will
+ result in error returns.
+
+
+
+
+
+
+
+Linn Standards Track [Page 45]
+
+RFC 2078 GSS-API January 1997
+
+
+2.2.4: GSS_Process_context_token call
+
+ Inputs:
+
+ o context_handle CONTEXT HANDLE,
+
+ o input_context_token OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the input_context_token was
+ successfully processed in conjunction with the context
+ referenced by context_handle.
+
+ o GSS_S_DEFECTIVE_TOKEN indicates that consistency checks
+ performed on the received context_token failed, preventing
+ further processing from being performed with that token.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided.
+
+ o GSS_S_FAILURE indicates that the context is recognized, but
+ that the GSS_Process_context_token() operation could not be
+ performed for reasons unspecified at the GSS-API level.
+
+ This call is used to process context_tokens received from a peer once
+ a context has been established, with corresponding impact on
+ context-level state information. One use for this facility is
+ processing of the context_tokens generated by
+ GSS_Delete_sec_context(); GSS_Process_context_token() will not block
+ pending network interactions for that purpose. Another use is to
+ process tokens indicating remote-peer context establishment failures
+ after the point where the local GSS-API implementation has already
+ indicated GSS_S_COMPLETE status.
+
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 46]
+
+RFC 2078 GSS-API January 1997
+
+
+2.2.5: GSS_Context_time call
+
+ Input:
+
+ o context_handle CONTEXT HANDLE,
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o lifetime_rec INTEGER - in seconds, or reserved value for
+ INDEFINITE
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the referenced context is valid,
+ and will remain valid for the amount of time indicated in
+ lifetime_rec.
+
+ o GSS_S_CONTEXT_EXPIRED indicates that data items related to the
+ referenced context have expired.
+
+ o GSS_S_CREDENTIALS_EXPIRED indicates that the context is
+ recognized, but that its associated credentials have expired.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided.
+
+ o GSS_S_FAILURE indicates that the requested operation failed for
+ reasons unspecified at the GSS-API level.
+
+ This call is used to determine the amount of time for which a
+ currently established context will remain valid.
+
+2.2.6: GSS_Inquire_context call
+
+ Input:
+
+ o context_handle CONTEXT HANDLE,
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+
+
+
+Linn Standards Track [Page 47]
+
+RFC 2078 GSS-API January 1997
+
+
+ o src_name INTERNAL NAME, -- name of context initiator,
+ -- guaranteed to be MN
+
+ o targ_name INTERNAL NAME, -- name of context target,
+ -- guaranteed to be MN
+
+
+ o lifetime_rec INTEGER -- in seconds, or reserved value for
+ INDEFINITE,
+
+ o mech_type OBJECT IDENTIFIER, -- the mechanism supporting this
+ security context
+
+ o deleg_state BOOLEAN,
+
+ o mutual_state BOOLEAN,
+
+ o replay_det_state BOOLEAN,
+
+ o sequence_state BOOLEAN,
+
+ o anon_state BOOLEAN,
+
+ o trans_state BOOLEAN,
+
+ o prot_ready_state BOOLEAN,
+
+ o conf_avail BOOLEAN,
+
+ o integ_avail BOOLEAN,
+
+ o locally_initiated BOOLEAN, -- TRUE if initiator, FALSE if acceptor
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the referenced context is valid
+ and that src_name, targ_name, lifetime_rec, mech_type, deleg_state,
+ mutual_state, replay_det_state, sequence_state, anon_state,
+ trans_state, prot_ready_state, conf_avail, integ_avail, and
+ locally_initiated return values describe the corresponding
+ characteristics of the context.
+
+ o GSS_S_CONTEXT_EXPIRED indicates that the provided input
+ context_handle is recognized, but that the referenced context
+ has expired. Return values other than major_status and
+ minor_status are undefined.
+
+
+
+
+
+Linn Standards Track [Page 48]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided. Return values other than
+ major_status and minor_status are undefined.
+
+ o GSS_S_FAILURE indicates that the requested operation failed for
+ reasons unspecified at the GSS-API level. Return values other than
+ major_status and minor_status are undefined.
+
+ This call is used to extract information describing characteristics
+ of a security context.
+
+2.2.7: GSS_Wrap_size_limit call
+
+ Inputs:
+
+ o context_handle CONTEXT HANDLE,
+
+ o qop INTEGER,
+
+ o output_size INTEGER
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o max_input_size INTEGER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates a successful token size determination:
+ an input message with a length in octets equal to the
+ returned max_input_size value will, when passed to GSS_Wrap()
+ for processing on the context identified by the context_handle
+ parameter and with the quality of protection specifier provided
+ in the qop parameter, yield an output token no larger than the
+ value of the provided output_size parameter.
+
+ o GSS_S_CONTEXT_EXPIRED indicates that the provided input
+ context_handle is recognized, but that the referenced context
+ has expired. Return values other than major_status and
+ minor_status are undefined.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided. Return values other than
+ major_status and minor_status are undefined.
+
+
+
+
+Linn Standards Track [Page 49]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_BAD_QOP indicates that the provided QOP value is not
+ recognized or supported for the context.
+
+ o GSS_S_FAILURE indicates that the requested operation failed for
+ reasons unspecified at the GSS-API level. Return values other than
+ major_status and minor_status are undefined.
+
+ This call is used to determine the largest input datum which may be
+ passed to GSS_Wrap() without yielding an output token larger than a
+ caller-specified value.
+
+2.2.8: GSS_Export_sec_context call
+
+ Inputs:
+
+ o context_handle CONTEXT HANDLE
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o interprocess_token OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the referenced context has been
+ successfully exported to a representation in the interprocess_token,
+ and is no longer available for use by the caller.
+
+ o GSS_S_UNAVAILABLE indicates that the context export facility
+ is not available for use on the referenced context. (This status
+ should occur only for contexts for which the trans_state value is
+ FALSE.) Return values other than major_status and minor_status are
+ undefined.
+
+ o GSS_S_CONTEXT_EXPIRED indicates that the provided input
+ context_handle is recognized, but that the referenced context has
+ expired. Return values other than major_status and minor_status are
+ undefined.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided. Return values other than
+ major_status and minor_status are undefined.
+
+
+
+
+
+
+Linn Standards Track [Page 50]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_FAILURE indicates that the requested operation failed for
+ reasons unspecified at the GSS-API level. Return values other than
+ major_status and minor_status are undefined.
+
+ This call generates an interprocess token for transfer to another
+ process within an end system, in order to transfer control of a
+ security context to that process. The recipient of the interprocess
+ token will call GSS_Import_sec_context() to accept the transfer. The
+ GSS_Export_sec_context() operation is defined for use only with
+ security contexts which are fully and successfully established (i.e.,
+ those for which GSS_Init_sec_context() and GSS_Accept_sec_context()
+ have returned GSS_S_COMPLETE major_status).
+
+ To ensure portability, a caller of GSS_Export_sec_context() must not
+ assume that a context may continue to be used once it has been
+ exported; following export, the context referenced by the
+ context_handle cannot be assumed to remain valid. Further, portable
+ callers must not assume that a given interprocess token can be
+ imported by GSS_Import_sec_context() more than once, thereby creating
+ multiple instantiations of a single context. GSS-API implementations
+ may detect and reject attempted multiple imports, but are not
+ required to do so.
+
+ The internal representation contained within the interprocess token
+ is an implementation-defined local matter. Interprocess tokens
+ cannot be assumed to be transferable across different GSS-API
+ implementations.
+
+ It is recommended that GSS-API implementations adopt policies suited
+ to their operational environments in order to define the set of
+ processes eligible to import a context, but specific constraints in
+ this area are local matters. Candidate examples include transfers
+ between processes operating on behalf of the same user identity, or
+ processes comprising a common job. However, it may be impossible to
+ enforce such policies in some implementations.
+
+ In support of the above goals, implementations may protect the
+ transferred context data by using cryptography to protect data within
+ the interprocess token, or by using interprocess tokens as a means to
+ reference local interprocess communication facilities (protected by
+ other means) rather than storing the context data directly within the
+ tokens.
+
+ Transfer of an open context may, for certain mechanisms and
+ implementations, reveal data about the credential which was used to
+ establish the context. Callers should, therefore, be cautious about
+ the trustworthiness of processes to which they transfer contexts.
+ Although the GSS-API implementation may provide its own set of
+
+
+
+Linn Standards Track [Page 51]
+
+RFC 2078 GSS-API January 1997
+
+
+ protections over the exported context, the caller is responsible for
+ protecting the interprocess token from disclosure, and for taking
+ care that the context is transferred to an appropriate destination
+ process.
+
+2.2.9: GSS_Import_sec_context call
+
+ Inputs:
+
+ o interprocess_token OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o context_handle CONTEXT HANDLE
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the context represented by the
+ input interprocess_token has been successfully transferred to
+ the caller, and is available for future use via the output
+ context_handle.
+
+ o GSS_S_CONTEXT_EXPIRED indicates that the context represented by
+ the input interprocess_token has expired. Return values other
+ than major_status and minor_status are undefined.
+
+ o GSS_S_NO_CONTEXT indicates that the context represented by the
+ input interprocess_token was invalid. Return values other than
+ major_status and minor_status are undefined.
+
+ o GSS_S_DEFECTIVE_TOKEN indicates that the input interprocess_token
+ was defective. Return values other than major_status and
+ minor_status are undefined.
+
+ o GSS_S_UNAVAILABLE indicates that the context import facility
+ is not available for use on the referenced context. Return values
+ other than major_status and minor_status are undefined.
+
+ o GSS_S_UNAUTHORIZED indicates that the context represented by
+ the input interprocess_token is unauthorized for transfer to the
+ caller. Return values other than major_status and minor_status
+ are undefined.
+
+
+
+
+
+Linn Standards Track [Page 52]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_FAILURE indicates that the requested operation failed for
+ reasons unspecified at the GSS-API level. Return values other than
+ major_status and minor_status are undefined.
+
+ This call processes an interprocess token generated by
+ GSS_Export_sec_context(), making the transferred context available
+ for use by the caller. After a successful GSS_Import_sec_context()
+ operation, the imported context is available for use by the importing
+ process.
+
+ For further discussion of the security and authorization issues
+ regarding this call, please see the discussion in Section 2.2.8.
+
+2.3: Per-message calls
+
+ This group of calls is used to perform per-message protection
+ processing on an established security context. None of these calls
+ block pending network interactions. These calls may be invoked by a
+ context's initiator or by the context's target. The four members of
+ this group should be considered as two pairs; the output from
+ GSS_GetMIC() is properly input to GSS_VerifyMIC(), and the output
+ from GSS_Wrap() is properly input to GSS_Unwrap().
+
+ GSS_GetMIC() and GSS_VerifyMIC() support data origin authentication
+ and data integrity services. When GSS_GetMIC() is invoked on an
+ input message, it yields a per-message token containing data items
+ which allow underlying mechanisms to provide the specified security
+ services. The original message, along with the generated per-message
+ token, is passed to the remote peer; these two data elements are
+ processed by GSS_VerifyMIC(), which validates the message in
+ conjunction with the separate token.
+
+ GSS_Wrap() and GSS_Unwrap() support caller-requested confidentiality
+ in addition to the data origin authentication and data integrity
+ services offered by GSS_GetMIC() and GSS_VerifyMIC(). GSS_Wrap()
+ outputs a single data element, encapsulating optionally enciphered
+ user data as well as associated token data items. The data element
+ output from GSS_Wrap() is passed to the remote peer and processed by
+ GSS_Unwrap() at that system. GSS_Unwrap() combines decipherment (as
+ required) with validation of data items related to authentication and
+ integrity.
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 53]
+
+RFC 2078 GSS-API January 1997
+
+
+2.3.1: GSS_GetMIC call
+
+ Note: This call is functionally equivalent to the GSS_Sign call as
+ defined in previous versions of this specification. In the interests
+ of backward compatibility, it is recommended that implementations
+ support this function under both names for the present; future
+ references to this function as GSS_Sign are deprecated.
+
+ Inputs:
+
+ o context_handle CONTEXT HANDLE,
+
+ o qop_req INTEGER,-0 specifies default QOP
+
+ o message OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o per_msg_token OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that an integrity check, suitable for an
+ established security context, was successfully applied and
+ that the message and corresponding per_msg_token are ready
+ for transmission.
+
+ o GSS_S_CONTEXT_EXPIRED indicates that context-related data
+ items have expired, so that the requested operation cannot be
+ performed.
+
+ o GSS_S_CREDENTIALS_EXPIRED indicates that the context is recognized,
+ but that its associated credentials have expired, so
+ that the requested operation cannot be performed.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided.
+
+ o GSS_S_BAD_QOP indicates that the provided QOP value is not
+ recognized or supported for the context.
+
+ o GSS_S_FAILURE indicates that the context is recognized, but
+ that the requested operation could not be performed for
+ reasons unspecified at the GSS-API level.
+
+
+
+Linn Standards Track [Page 54]
+
+RFC 2078 GSS-API January 1997
+
+
+ Using the security context referenced by context_handle, apply an
+ integrity check to the input message (along with timestamps and/or
+ other data included in support of mech_type-specific mechanisms) and
+ return the result in per_msg_token. The qop_req parameter,
+ interpretation of which is discussed in Section 1.2.4, allows
+ quality-of-protection control. The caller passes the message and the
+ per_msg_token to the target.
+
+ The GSS_GetMIC() function completes before the message and
+ per_msg_token is sent to the peer; successful application of
+ GSS_GetMIC() does not guarantee that a corresponding GSS_VerifyMIC()
+ has been (or can necessarily be) performed successfully when the
+ message arrives at the destination.
+
+ Mechanisms which do not support per-message protection services
+ should return GSS_S_FAILURE if this routine is called.
+
+2.3.2: GSS_VerifyMIC call
+
+ Note: This call is functionally equivalent to the GSS_Verify call as
+ defined in previous versions of this specification. In the interests
+ of backward compatibility, it is recommended that implementations
+ support this function under both names for the present; future
+ references to this function as GSS_Verify are deprecated.
+
+ Inputs:
+
+ o context_handle CONTEXT HANDLE,
+
+ o message OCTET STRING,
+
+ o per_msg_token OCTET STRING
+
+ Outputs:
+
+ o qop_state INTEGER,
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the message was successfully
+ verified.
+
+
+
+
+
+
+Linn Standards Track [Page 55]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_DEFECTIVE_TOKEN indicates that consistency checks performed
+ on the received per_msg_token failed, preventing
+ further processing from being performed with that token.
+
+ o GSS_S_BAD_SIG indicates that the received per_msg_token contains
+ an incorrect integrity check for the message.
+
+ o GSS_S_DUPLICATE_TOKEN, GSS_S_OLD_TOKEN, GSS_S_UNSEQ_TOKEN,
+ and GSS_S_GAP_TOKEN values appear in conjunction with the
+ optional per-message replay detection features described
+ in Section 1.2.3; their semantics are described in that section.
+
+ o GSS_S_CONTEXT_EXPIRED indicates that context-related data
+ items have expired, so that the requested operation cannot be
+ performed.
+
+ o GSS_S_CREDENTIALS_EXPIRED indicates that the context is
+ recognized,
+ but that its associated credentials have expired, so
+ that the requested operation cannot be performed.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided.
+
+ o GSS_S_FAILURE indicates that the context is recognized, but
+ that the GSS_VerifyMIC() operation could not be performed for
+ reasons unspecified at the GSS-API level.
+
+ Using the security context referenced by context_handle, verify that
+ the input per_msg_token contains an appropriate integrity check for
+ the input message, and apply any active replay detection or
+ sequencing features. Return an indication of the quality-of-
+ protection applied to the processed message in the qop_state result.
+ Since the GSS_VerifyMIC() routine never provides a confidentiality
+ service, its implementations should not return non-zero values in the
+ confidentiality fields of the output qop_state.
+
+ Mechanisms which do not support per-message protection services
+ should return GSS_S_FAILURE if this routine is called.
+
+2.3.3: GSS_Wrap call
+
+ Note: This call is functionally equivalent to the GSS_Seal call as
+ defined in previous versions of this specification. In the interests
+ of backward compatibility, it is recommended that implementations
+ support this function under both names for the present; future
+ references to this function as GSS_Seal are deprecated.
+
+
+
+
+Linn Standards Track [Page 56]
+
+RFC 2078 GSS-API January 1997
+
+
+ Inputs:
+
+ o context_handle CONTEXT HANDLE,
+
+ o conf_req_flag BOOLEAN,
+
+ o qop_req INTEGER,-0 specifies default QOP
+
+ o input_message OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o conf_state BOOLEAN,
+
+ o output_message OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the input_message was successfully
+ processed and that the output_message is ready for
+ transmission.
+
+ o GSS_S_CONTEXT_EXPIRED indicates that context-related data
+ items have expired, so that the requested operation cannot be
+ performed.
+
+ o GSS_S_CREDENTIALS_EXPIRED indicates that the context is
+ recognized,
+ but that its associated credentials have expired, so
+ that the requested operation cannot be performed.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided.
+
+ o GSS_S_BAD_QOP indicates that the provided QOP value is not
+ recognized or supported for the context.
+
+ o GSS_S_FAILURE indicates that the context is recognized, but
+ that the GSS_Wrap() operation could not be performed for
+ reasons unspecified at the GSS-API level.
+
+ Performs the data origin authentication and data integrity functions
+ of GSS_GetMIC(). If the input conf_req_flag is TRUE, requests that
+ confidentiality be applied to the input_message. Confidentiality may
+
+
+
+Linn Standards Track [Page 57]
+
+RFC 2078 GSS-API January 1997
+
+
+ not be supported in all mech_types or by all implementations; the
+ returned conf_state flag indicates whether confidentiality was
+ provided for the input_message. The qop_req parameter, interpretation
+ of which is discussed in Section 1.2.4, allows quality-of-protection
+ control.
+
+ In all cases, the GSS_Wrap() call yields a single output_message
+ data element containing (optionally enciphered) user data as well as
+ control information.
+
+ Mechanisms which do not support per-message protection services
+ should return GSS_S_FAILURE if this routine is called.
+
+2.3.4: GSS_Unwrap call
+
+ Note: This call is functionally equivalent to the GSS_Unseal call as
+ defined in previous versions of this specification. In the interests
+ of backward compatibility, it is recommended that implementations
+ support this function under both names for the present; future
+ references to this function as GSS_Unseal are deprecated.
+
+ Inputs:
+
+ o context_handle CONTEXT HANDLE,
+
+ o input_message OCTET STRING
+
+ Outputs:
+
+ o conf_state BOOLEAN,
+
+ o qop_state INTEGER,
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_message OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the input_message was
+ successfully processed and that the resulting output_message is
+ available.
+
+ o GSS_S_DEFECTIVE_TOKEN indicates that consistency checks performed
+ on the per_msg_token extracted from the input_message
+ failed, preventing further processing from being performed.
+
+
+
+Linn Standards Track [Page 58]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_BAD_SIG indicates that an incorrect integrity check was
+ detected
+ for the message.
+
+ o GSS_S_DUPLICATE_TOKEN, GSS_S_OLD_TOKEN, GSS_S_UNSEQ_TOKEN,
+ and GSS_S_GAP_TOKEN values appear in conjunction with the
+ optional per-message replay detection features described
+ in Section 1.2.3; their semantics are described in that section.
+
+ o GSS_S_CONTEXT_EXPIRED indicates that context-related data
+ items have expired, so that the requested operation cannot be
+ performed.
+
+ o GSS_S_CREDENTIALS_EXPIRED indicates that the context is
+ recognized,
+ but that its associated credentials have expired, so
+ that the requested operation cannot be performed.
+
+ o GSS_S_NO_CONTEXT indicates that no valid context was recognized
+ for the input context_handle provided.
+
+ o GSS_S_FAILURE indicates that the context is recognized, but
+ that the GSS_Unwrap() operation could not be performed for
+ reasons unspecified at the GSS-API level.
+
+ Processes a data element generated (and optionally enciphered) by
+ GSS_Wrap(), provided as input_message. The returned conf_state value
+ indicates whether confidentiality was applied to the input_message.
+ If conf_state is TRUE, GSS_Unwrap() deciphers the input_message.
+ Returns an indication of the quality-of-protection applied to the
+ processed message in the qop_state result. GSS_Wrap() performs the
+ data integrity and data origin authentication checking functions of
+ GSS_VerifyMIC() on the plaintext data. Plaintext data is returned in
+ output_message.
+
+ Mechanisms which do not support per-message protection services
+ should return GSS_S_FAILURE if this routine is called.
+
+2.4: Support calls
+
+ This group of calls provides support functions useful to GSS-API
+ callers, independent of the state of established contexts. Their
+ characterization with regard to blocking or non-blocking status in
+ terms of network interactions is unspecified.
+
+
+
+
+
+
+
+Linn Standards Track [Page 59]
+
+RFC 2078 GSS-API January 1997
+
+
+2.4.1: GSS_Display_status call
+
+ Inputs:
+
+ o status_value INTEGER,-GSS-API major_status or minor_status
+ return value
+
+ o status_type INTEGER,-1 if major_status, 2 if minor_status
+
+ o mech_type OBJECT IDENTIFIER-mech_type to be used for minor_
+ status translation
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o status_string_set SET OF OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that a valid printable status
+ representation (possibly representing more than one status event
+ encoded within the status_value) is available in the returned
+ status_string_set.
+
+ o GSS_S_BAD_MECH indicates that translation in accordance with an
+ unsupported mech_type was requested, so translation could not
+ be performed.
+
+ o GSS_S_BAD_STATUS indicates that the input status_value was
+ invalid, or that the input status_type carried a value other
+ than 1 or 2, so translation could not be performed.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ Provides a means for callers to translate GSS-API-returned major and
+ minor status codes into printable string representations.
+
+2.4.2: GSS_Indicate_mechs call
+
+ Input:
+
+ o (none)
+
+
+
+
+
+Linn Standards Track [Page 60]
+
+RFC 2078 GSS-API January 1997
+
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o mech_set SET OF OBJECT IDENTIFIER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that a set of available mechanisms has
+ been returned in mech_set.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to determine the set of mechanism types available on
+ the local system. This call is intended for support of specialized
+ callers who need to request non-default mech_type sets from
+ GSS_Acquire_cred(), and should not be needed by other callers.
+
+2.4.3: GSS_Compare_name call
+
+ Inputs:
+
+ o name1 INTERNAL NAME,
+
+ o name2 INTERNAL NAME
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o name_equal BOOLEAN
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that name1 and name2 were comparable,
+ and that the name_equal result indicates whether name1 and
+ name2 represent the same entity.
+
+ o GSS_S_BAD_NAMETYPE indicates that one or both of name1 and
+ name2 contained internal type specifiers uninterpretable
+ by the applicable underlying GSS-API mechanism(s), or that
+ the two names' types are different and incomparable, so that
+ the comparison operation could not be completed.
+
+
+
+Linn Standards Track [Page 61]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_BAD_NAME indicates that one or both of the input names
+ was ill-formed in terms of its internal type specifier, so
+ the comparison operation could not be completed.
+
+ o GSS_S_FAILURE indicates that the call's operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to compare two internal name representations to
+ determine whether they refer to the same entity. If either name
+ presented to GSS_Compare_name() denotes an anonymous principal,
+ GSS_Compare_name() shall indicate FALSE. It is not required that
+ either or both inputs name1 and name2 be MNs; for some
+ implementations and cases, GSS_S_BAD_NAMETYPE may be returned,
+ indicating name incomparability, for the case where neither input
+ name is an MN.
+
+2.4.4: GSS_Display_name call
+
+ Inputs:
+
+ o name INTERNAL NAME
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o name_string OCTET STRING,
+
+ o name_type OBJECT IDENTIFIER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that a valid printable name
+ representation is available in the returned name_string.
+
+ o GSS_S_BAD_NAMETYPE indicates that the provided name was of a
+ type uninterpretable by the applicable underlying GSS-API
+ mechanism(s), so no printable representation could be generated.
+
+ o GSS_S_BAD_NAME indicates that the contents of the provided name
+ were inconsistent with the internally-indicated name type, so
+ no printable representation could be generated.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+
+
+
+Linn Standards Track [Page 62]
+
+RFC 2078 GSS-API January 1997
+
+
+ Allows callers to translate an internal name representation into a
+ printable form with associated namespace type descriptor. The syntax
+ of the printable form is a local matter.
+
+ If the input name represents an anonymous identity, a reserved value
+ (GSS_C_NT_ANONYMOUS) shall be returned for name_type.
+
+2.4.5: GSS_Import_name call
+
+ Inputs:
+
+ o input_name_string OCTET STRING,
+
+ o input_name_type OBJECT IDENTIFIER
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_name INTERNAL NAME
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that a valid name representation is
+ output in output_name and described by the type value in
+ output_name_type.
+
+ o GSS_S_BAD_NAMETYPE indicates that the input_name_type is unsupported
+ by the applicable underlying GSS-API mechanism(s), so the import
+ operation could not be completed.
+
+ o GSS_S_BAD_NAME indicates that the provided input_name_string
+ is ill-formed in terms of the input_name_type, so the import
+ operation could not be completed.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to provide a name representation as a contiguous octet
+ string, designate the type of namespace in conjunction with which it
+ should be parsed, and convert that representation to an internal form
+ suitable for input to other GSS-API routines. The syntax of the
+ input_name_string is defined in conjunction with its associated name
+ type; depending on the input_name_type, the associated
+ input_name_string may or may not be a printable string. Note: The
+ input_name_type argument serves to describe and qualify the
+
+
+
+Linn Standards Track [Page 63]
+
+RFC 2078 GSS-API January 1997
+
+
+ interpretation of the associated input_name_string; it does not
+ specify the data type of the returned output_name.
+
+ If a mechanism claims support for a particular name type, its
+ GSS_Import_name() operation shall be able to accept all possible
+ values conformant to the external name syntax as defined for that
+ name type. These imported values may correspond to:
+
+ (1) locally registered entities (for which credentials may be
+ acquired),
+
+ (2) non-local entities (for which local credentials cannot be
+ acquired, but which may be referenced as targets of initiated
+ security contexts or initiators of accepted security contexts), or
+ to
+
+ (3) neither of the above.
+
+ Determination of whether a particular name belongs to class (1), (2),
+ or (3) as described above is not guaranteed to be performed by the
+ GSS_Import_name() function.
+
+ The internal name generated by a GSS_Import_name() operation may be a
+ single-mechanism MN, and is likely to be an MN within a single-
+ mechanism implementation, but portable callers must not depend on
+ this property (and must not, therefore, assume that the output from
+ GSS_Import_name() can be passed directly to GSS_Export_name() without
+ first being processed through GSS_Canonicalize_name()).
+
+2.4.6: GSS_Release_name call
+
+ Inputs:
+
+ o name INTERNAL NAME
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the storage associated with the
+ input name was successfully released.
+
+ o GSS_S_BAD_NAME indicates that the input name argument did not
+ contain a valid name.
+
+
+
+Linn Standards Track [Page 64]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to release the storage associated with an internal
+ name representation. This call's specific behavior depends on the
+ language and programming environment within which a GSS-API
+ implementation operates, and is therefore detailed within applicable
+ bindings specifications; in particular, this call may be superfluous
+ within bindings where memory management is automatic.
+
+2.4.7: GSS_Release_buffer call
+
+ Inputs:
+
+ o buffer OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the storage associated with the
+ input buffer was successfully released.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to release the storage associated with an OCTET STRING
+ buffer allocated by another GSS-API call. This call's specific
+ behavior depends on the language and programming environment within
+ which a GSS-API implementation operates, and is therefore detailed
+ within applicable bindings specifications; in particular, this call
+ may be superfluous within bindings where memory management is
+ automatic.
+
+2.4.8: GSS_Release_OID_set call
+
+ Inputs:
+
+ o buffer SET OF OBJECT IDENTIFIER
+
+ Outputs:
+
+ o major_status INTEGER,
+
+
+
+
+Linn Standards Track [Page 65]
+
+RFC 2078 GSS-API January 1997
+
+
+ o minor_status INTEGER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the storage associated with the
+ input object identifier set was successfully released.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to release the storage associated with an object
+ identifier set object allocated by another GSS-API call. This call's
+ specific behavior depends on the language and programming environment
+ within which a GSS-API implementation operates, and is therefore
+ detailed within applicable bindings specifications; in particular,
+ this call may be superfluous within bindings where memory management
+ is automatic.
+
+2.4.9: GSS_Create_empty_OID_set call
+
+ Inputs:
+
+ o (none)
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o oid_set SET OF OBJECT IDENTIFIER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates successful completion
+
+ o GSS_S_FAILURE indicates that the operation failed
+
+ Creates an object identifier set containing no object identifiers, to
+ which members may be subsequently added using the
+ GSS_Add_OID_set_member() routine. These routines are intended to be
+ used to construct sets of mechanism object identifiers, for input to
+ GSS_Acquire_cred().
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 66]
+
+RFC 2078 GSS-API January 1997
+
+
+2.4.10: GSS_Add_OID_set_member call
+
+ Inputs:
+
+ o member_oid OBJECT IDENTIFIER,
+
+ o oid_set SET OF OBJECT IDENTIFIER
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates successful completion
+
+ o GSS_S_FAILURE indicates that the operation failed
+
+ Adds an Object Identifier to an Object Identifier set. This routine
+ is intended for use in conjunction with GSS_Create_empty_OID_set()
+ when constructing a set of mechanism OIDs for input to
+ GSS_Acquire_cred().
+
+2.4.11: GSS_Test_OID_set_member call
+
+ Inputs:
+
+ o member OBJECT IDENTIFIER,
+
+ o set SET OF OBJECT IDENTIFIER
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o present BOOLEAN
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates successful completion
+
+ o GSS_S_FAILURE indicates that the operation failed
+
+
+
+
+
+Linn Standards Track [Page 67]
+
+RFC 2078 GSS-API January 1997
+
+
+ Interrogates an Object Identifier set to determine whether a
+ specified Object Identifier is a member. This routine is intended to
+ be used with OID sets returned by GSS_Indicate_mechs(),
+ GSS_Acquire_cred(), and GSS_Inquire_cred().
+
+2.4.12: GSS_Release_OID call
+
+ Inputs:
+
+ o oid OBJECT IDENTIFIER
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates successful completion
+
+ o GSS_S_FAILURE indicates that the operation failed
+
+ Allows the caller to release the storage associated with an OBJECT
+ IDENTIFIER buffer allocated by another GSS-API call. This call's
+ specific behavior depends on the language and programming environment
+ within which a GSS-API implementation operates, and is therefore
+ detailed within applicable bindings specifications; in particular,
+ this call may be superfluous within bindings where memory management
+ is automatic.
+
+2.4.13: GSS_OID_to_str call
+
+ Inputs:
+
+ o oid OBJECT IDENTIFIER
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o oid_str OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates successful completion
+
+
+
+Linn Standards Track [Page 68]
+
+RFC 2078 GSS-API January 1997
+
+
+ o GSS_S_FAILURE indicates that the operation failed
+
+ The function GSS_OID_to_str() returns a string representing the input
+ OID in numeric ASN.1 syntax format (curly-brace enclosed, space-
+ delimited, e.g., "{2 16 840 1 113687 1 2 1}"). The string is
+ releasable using GSS_Release_buffer(). If the input "oid" does not
+ represent a syntactically valid object identifier, GSS_S_FAILURE
+ status is returned and the returned oid_str result is NULL.
+
+2.4.14: GSS_Str_to_OID call
+
+ Inputs:
+
+ o oid_str OCTET STRING
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o oid OBJECT IDENTIFIER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates successful completion
+
+ o GSS_S_FAILURE indicates that the operation failed
+
+ The function GSS_Str_to_OID() constructs and returns an OID from its
+ printable form; implementations should be able to accept the numeric
+ ASN.1 syntax form as described for GSS_OID_to_str(), and this form
+ should be used for portability, but implementations of this routine
+ may also accept other formats (e.g., "1.2.3.3"). The OID is suitable
+ for release using the function GSS_Release_OID(). If the input
+ oid_str cannot be translated into an OID, GSS_S_FAILURE status is
+ returned and the "oid" result is NULL.
+
+2.4.15: GSS_Inquire_names_for_mech call
+
+ Input:
+
+ o input_mech_type OBJECT IDENTIFIER, -- mechanism type
+
+ Outputs:
+
+ o major_status INTEGER,
+
+
+
+
+Linn Standards Track [Page 69]
+
+RFC 2078 GSS-API January 1997
+
+
+ o minor_status INTEGER,
+
+ o name_type_set SET OF OBJECT IDENTIFIER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that the output name_type_set contains
+ a list of name types which are supported by the locally available
+ mechanism identified by input_mech_type.
+
+ o GSS_S_BAD_MECH indicates that the mechanism identified by
+ input_mech_type was unsupported within the local implementation,
+ causing the query to fail.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ Allows callers to determine the set of name types which are
+ supportable by a specific locally-available mechanism.
+
+2.4.16: GSS_Inquire_mechs_for_name call
+
+ Inputs:
+
+ o input_name INTERNAL NAME,
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o mech_types SET OF OBJECT IDENTIFIER
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that a set of object identifiers,
+ corresponding to the set of mechanisms suitable for processing
+ the input_name, is available in mech_types.
+
+ o GSS_S_BAD_NAME indicates that the input_name could not be
+ processed.
+
+ o GSS_S_BAD_NAMETYPE indicates that the type of the input_name
+ is unsupported by the GSS-API implementation.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+
+
+Linn Standards Track [Page 70]
+
+RFC 2078 GSS-API January 1997
+
+
+ This routine returns the mechanism set with which the input_name may
+ be processed. After use, the mech_types object should be freed by
+ the caller via the GSS_Release_OID_set() call. Note: it is
+ anticipated that implementations of GSS_Inquire_mechs_for_name() will
+ commonly operate based on type information describing the
+ capabilities of available mechanisms; it is not guaranteed that all
+ identified mechanisms will necessarily be able to canonicalize (via
+ GSS_Canonicalize_name()) a particular name.
+
+2.4.17: GSS_Canonicalize_name call
+
+ Inputs:
+
+ o input_name INTERNAL NAME,
+
+ o mech_type OBJECT IDENTIFIER -- must be explicit mechanism,
+ not "default" specifier
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_name INTERNAL NAME
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that a mechanism-specific reduction of
+ the input_name, as processed by the mechanism identified by
+ mech_type, is available in output_name.
+
+ o GSS_S_BAD_MECH indicates that the identified mechanism is
+ unsupported.
+
+ o GSS_S_BAD_NAMETYPE indicates that the input name does not
+ contain an element with suitable type for processing by the
+ identified mechanism.
+
+ o GSS_S_BAD_NAME indicates that the input name contains an
+ element with suitable type for processing by the identified
+ mechanism, but that this element could not be processed
+ successfully.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+
+
+
+
+Linn Standards Track [Page 71]
+
+RFC 2078 GSS-API January 1997
+
+
+ This routine reduces a GSS-API internal name, which may in general
+ contain elements corresponding to multiple mechanisms, to a
+ mechanism-specific Mechanism Name (MN) by applying the translations
+ corresponding to the mechanism identified by mech_type.
+
+2.4.18: GSS_Export_name call
+
+ Inputs:
+
+ o input_name INTERNAL NAME, -- required to be MN
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o output_name OCTET STRING
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that a flat representation of the
+ input name is available in output_name.
+
+ o GSS_S_NAME_NOT_MN indicates that the input name contained
+ elements corresponding to multiple mechanisms, so cannot
+ be exported into a single-mechanism flat form.
+
+ o GSS_S_BAD_NAME indicates that the input name was an MN,
+ but could not be processed.
+
+ o GSS_S_BAD_NAMETYPE indicates that the input name was an MN,
+ but that its type is unsupported by the GSS-API implementation.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ This routine creates a flat name representation, suitable for
+ bytewise comparison or for input to GSS_Import_name() in conjunction
+ with the reserved GSS-API Exported Name Object OID, from a internal-
+ form Mechanism Name (MN) as emitted, e.g., by GSS_Canonicalize_name()
+ or GSS_Accept_sec_context().
+
+ The emitted GSS-API Exported Name Object is self-describing; no
+ associated parameter-level OID need be emitted by this call. This
+ flat representation consists of a mechanism-independent wrapper
+ layer, defined in Section 3.2 of this document, enclosing a
+ mechanism-defined name representation.
+
+
+
+Linn Standards Track [Page 72]
+
+RFC 2078 GSS-API January 1997
+
+
+ In all cases, the flat name output by GSS_Export_name() to correspond
+ to a particular input MN must be invariant over time within a
+ particular installation.
+
+ The GSS_S_NAME_NOT_MN status code is provided to enable
+ implementations to reject input names which are not MNs. It is not,
+ however, required for purposes of conformance to this specification
+ that all non-MN input names must necessarily be rejected.
+
+2.4.19: GSS_Duplicate_name call
+
+ Inputs:
+
+ o src_name INTERNAL NAME
+
+ Outputs:
+
+ o major_status INTEGER,
+
+ o minor_status INTEGER,
+
+ o dest_name INTERNAL NAME
+
+ Return major_status codes:
+
+ o GSS_S_COMPLETE indicates that dest_name references an internal
+ name object containing the same name as passed to src_name.
+
+ o GSS_S_BAD_NAME indicates that the input name was invalid.
+
+ o GSS_S_BAD_NAMETYPE indicates that the input name's type
+ is unsupported by the GSS-API implementation.
+
+ o GSS_S_FAILURE indicates that the requested operation could not
+ be performed for reasons unspecified at the GSS-API level.
+
+ This routine takes input internal name src_name, and returns another
+ reference (dest_name) to that name which can be used even if src_name
+ is later freed. (Note: This may be implemented by copying or through
+ use of reference counts.)
+
+3: Data Structure Definitions for GSS-V2 Usage
+
+ Subsections of this section define, for interoperability and
+ portability purposes, certain data structures for use with GSS-V2.
+
+
+
+
+
+
+Linn Standards Track [Page 73]
+
+RFC 2078 GSS-API January 1997
+
+
+3.1: Mechanism-Independent Token Format
+
+ This section specifies a mechanism-independent level of encapsulating
+ representation for the initial token of a GSS-API context
+ establishment sequence, incorporating an identifier of the mechanism
+ type to be used on that context and enabling tokens to be interpreted
+ unambiguously at GSS-API peers. Use of this format is required for
+ initial context establishment tokens of Internet standards-track
+ GSS-API mechanisms; use in non-initial tokens is optional.
+
+ The encoding format for the token tag is derived from ASN.1 and DER
+ (per illustrative ASN.1 syntax included later within this
+ subsection), but its concrete representation is defined directly in
+ terms of octets rather than at the ASN.1 level in order to facilitate
+ interoperable implementation without use of general ASN.1 processing
+ code. The token tag consists of the following elements, in order:
+
+ 1. 0x60 -- Tag for [APPLICATION 0] SEQUENCE; indicates that
+ constructed form, definite length encoding follows.
+
+ 2. Token length octets, specifying length of subsequent data
+ (i.e., the summed lengths of elements 3-5 in this list, and of the
+ mechanism-defined token object following the tag). This element
+ comprises a variable number of octets:
+
+ 2a. If the indicated value is less than 128, it shall be
+ represented in a single octet with bit 8 (high order) set to "0"
+ and the remaining bits representing the value.
+
+ 2b. If the indicated value is 128 or more, it shall be represented
+ in two or more octets, with bit 8 of the first octet set to "1"
+ and the remaining bits of the first octet specifying the number of
+ additional octets. The subsequent octets carry the value, 8 bits
+ per octet, most significant digit first. The minimum number of
+ octets shall be used to encode the length (i.e., no octets
+ representing leading zeros shall be included within the length
+ encoding).
+
+ 3. 0x06 -- Tag for OBJECT IDENTIFIER
+
+ 4. Object identifier length -- length (number of octets) of the
+ encoded object identifier contained in element 5, encoded per
+ rules as described in 2a. and 2b. above.
+
+ 5. Object identifier octets -- variable number of octets, encoded
+ per ASN.1 BER rules:
+
+
+
+
+
+Linn Standards Track [Page 74]
+
+RFC 2078 GSS-API January 1997
+
+
+ 5a. The first octet contains the sum of two values: (1) the top-
+ level object identifier component, multiplied by 40 (decimal), and
+ (2) the second-level object identifier component. This special
+ case is the only point within an object identifier encoding where
+ a single octet represents contents of more than one component.
+
+ 5b. Subsequent octets, if required, encode successively-lower
+ components in the represented object identifier. A component's
+ encoding may span multiple octets, encoding 7 bits per octet (most
+ significant bits first) and with bit 8 set to "1" on all but the
+ final octet in the component's encoding. The minimum number of
+ octets shall be used to encode each component (i.e., no octets
+ representing leading zeros shall be included within a component's
+ encoding).
+
+ (Note: In many implementations, elements 3-5 may be stored and
+ referenced as a contiguous string constant.)
+
+ The token tag is immediately followed by a mechanism-defined token
+ object. Note that no independent size specifier intervenes following
+ the object identifier value to indicate the size of the mechanism-
+ defined token object. While ASN.1 usage within mechanism-defined
+ tokens is permitted, there is no requirement that the mechanism-
+ specific innerContextToken, innerMsgToken, and sealedUserData data
+ elements must employ ASN.1 BER/DER encoding conventions.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 75]
+
+RFC 2078 GSS-API January 1997
+
+
+ The following ASN.1 syntax is included for descriptive purposes only,
+ to illustrate structural relationships among token and tag objects.
+ For interoperability purposes, token and tag encoding shall be
+ performed using the concrete encoding procedures described earlier in
+ this subsection.
+
+ GSS-API DEFINITIONS ::=
+
+ BEGIN
+
+ MechType ::= OBJECT IDENTIFIER
+ -- data structure definitions
+
+ -- callers must be able to distinguish among
+ -- InitialContextToken, SubsequentContextToken,
+ -- PerMsgToken, and SealedMessage data elements
+ -- based on the usage in which they occur
+
+ InitialContextToken ::=
+ -- option indication (delegation, etc.) indicated within
+ -- mechanism-specific token
+ [APPLICATION 0] IMPLICIT SEQUENCE {
+ thisMech MechType,
+ innerContextToken ANY DEFINED BY thisMech
+ -- contents mechanism-specific
+ -- ASN.1 structure not required
+ }
+
+ SubsequentContextToken ::= innerContextToken ANY
+ -- interpretation based on predecessor InitialContextToken
+ -- ASN.1 structure not required
+
+ PerMsgToken ::=
+ -- as emitted by GSS_GetMIC and processed by GSS_VerifyMIC
+ -- ASN.1 structure not required
+ innerMsgToken ANY
+
+ SealedMessage ::=
+ -- as emitted by GSS_Wrap and processed by GSS_Unwrap
+ -- includes internal, mechanism-defined indicator
+ -- of whether or not encrypted
+ -- ASN.1 structure not required
+ sealedUserData ANY
+
+ END
+
+
+
+
+
+
+Linn Standards Track [Page 76]
+
+RFC 2078 GSS-API January 1997
+
+
+3.2: Mechanism-Independent Exported Name Object Format
+
+ This section specifies a mechanism-independent level of encapsulating
+ representation for names exported via the GSS_Export_name() call,
+ including an object identifier representing the exporting mechanism.
+ The format of names encapsulated via this representation shall be
+ defined within individual mechanism drafts. Name objects of this
+ type will be identified with the following Object Identifier:
+
+ {1(iso), 3(org), 6(dod), 1(internet), 5(security), 6(nametypes),
+ 4(gss-api-exported-name)}
+
+ No name type OID is included in this mechanism-independent level of
+ format definition, since (depending on individual mechanism
+ specifications) the enclosed name may be implicitly typed or may be
+ explicitly typed using a means other than OID encoding.
+
+ Length Name Description
+
+ 2 TOK_ID Token Identifier
+ For exported name objects, this
+ must be hex 04 01.
+ 2 MECH_OID_LEN Length of the Mechanism OID
+ MECH_OID_LEN MECH_OID Mechanism OID, in DER
+ 4 NAME_LEN Length of name
+ NAME_LEN NAME Exported name; format defined in
+ applicable mechanism draft.
+
+4: Name Type Definitions
+
+ This section includes definitions for name types and associated
+ syntaxes which are defined in a mechanism-independent fashion at the
+ GSS-API level rather than being defined in individual mechanism
+ specifications.
+
+4.1: Host-Based Service Name Form
+
+ The following Object Identifier value is provided as a means to
+ identify this name form:
+
+ {1(iso), 3(org), 6(dod), 1(internet), 5(security), 6(nametypes),
+ 2(gss-host-based-services)}
+
+ The recommended symbolic name for this type is
+ "GSS_C_NT_HOSTBASED_SERVICE".
+
+
+
+
+
+
+Linn Standards Track [Page 77]
+
+RFC 2078 GSS-API January 1997
+
+
+ This name type is used to represent services associated with host
+ computers. This name form is constructed using two elements,
+ "service" and "hostname", as follows:
+
+ service@hostname
+
+ When a reference to a name of this type is resolved, the "hostname"
+ is canonicalized by attempting a DNS lookup and using the fully-
+ qualified domain name which is returned, or by using the "hostname"
+ as provided if the DNS lookup fails. The canonicalization operation
+ also maps the host's name into lower-case characters.
+
+ The "hostname" element may be omitted. If no "@" separator is
+ included, the entire name is interpreted as the service specifier,
+ with the "hostname" defaulted to the canonicalized name of the local
+ host.
+
+ Values for the "service" element are registered with the IANA.
+
+4.2: User Name Form
+
+ This name form shall be represented by the Object Identifier {iso(1)
+ member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ generic(1) user_name(1)}. The recommended mechanism-independent
+ symbolic name for this type is "GSS_C_NT_USER_NAME". (Note: the same
+ name form and OID is defined within the Kerberos V5 GSS-API
+ mechanism, but the symbolic name recommended there begins with a
+ "GSS_KRB5_NT_" prefix.)
+
+ This name type is used to indicate a named user on a local system.
+ Its interpretation is OS-specific. This name form is constructed as:
+
+ username
+
+4.3: Machine UID Form
+
+ This name form shall be represented by the Object Identifier {iso(1)
+ member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ generic(1) machine_uid_name(2)}. The recommended mechanism-
+ independent symbolic name for this type is
+ "GSS_C_NT_MACHINE_UID_NAME". (Note: the same name form and OID is
+ defined within the Kerberos V5 GSS-API mechanism, but the symbolic
+ name recommended there begins with a "GSS_KRB5_NT_" prefix.)
+
+ This name type is used to indicate a numeric user identifier
+ corresponding to a user on a local system. Its interpretation is
+ OS-specific. The gss_buffer_desc representing a name of this type
+ should contain a locally-significant uid_t, represented in host byte
+
+
+
+Linn Standards Track [Page 78]
+
+RFC 2078 GSS-API January 1997
+
+
+ order. The GSS_Import_name() operation resolves this uid into a
+ username, which is then treated as the User Name Form.
+
+4.4: String UID Form
+
+ This name form shall be represented by the Object Identifier {iso(1)
+ member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ generic(1) string_uid_name(3)}. The recommended symbolic name for
+ this type is "GSS_C_NT_STRING_UID_NAME". (Note: the same name form
+ and OID is defined within the Kerberos V5 GSS-API mechanism, but the
+ symbolic name recommended there begins with a "GSS_KRB5_NT_" prefix.)
+
+ This name type is used to indicate a string of digits representing
+ the numeric user identifier of a user on a local system. Its
+ interpretation is OS-specific. This name type is similar to the
+ Machine UID Form, except that the buffer contains a string
+ representing the uid_t.
+
+5: Mechanism-Specific Example Scenarios
+
+ This section provides illustrative overviews of the use of various
+ candidate mechanism types to support the GSS-API. These discussions
+ are intended primarily for readers familiar with specific security
+ technologies, demonstrating how GSS-API functions can be used and
+ implemented by candidate underlying mechanisms. They should not be
+ regarded as constrictive to implementations or as defining the only
+ means through which GSS-API functions can be realized with a
+ particular underlying technology, and do not demonstrate all GSS-API
+ features with each technology.
+
+5.1: Kerberos V5, single-TGT
+
+ OS-specific login functions yield a TGT to the local realm Kerberos
+ server; TGT is placed in a credentials structure for the client.
+ Client calls GSS_Acquire_cred() to acquire a cred_handle in order to
+ reference the credentials for use in establishing security contexts.
+
+ Client calls GSS_Init_sec_context(). If the requested service is
+ located in a different realm, GSS_Init_sec_context() gets the
+ necessary TGT/key pairs needed to traverse the path from local to
+ target realm; these data are placed in the owner's TGT cache. After
+ any needed remote realm resolution, GSS_Init_sec_context() yields a
+ service ticket to the requested service with a corresponding session
+ key; these data are stored in conjunction with the context. GSS-API
+ code sends KRB_TGS_REQ request(s) and receives KRB_TGS_REP
+ response(s) (in the successful case) or KRB_ERROR.
+
+
+
+
+
+Linn Standards Track [Page 79]
+
+RFC 2078 GSS-API January 1997
+
+
+ Assuming success, GSS_Init_sec_context() builds a Kerberos-formatted
+ KRB_AP_REQ message, and returns it in output_token. The client sends
+ the output_token to the service.
+
+ The service passes the received token as the input_token argument to
+ GSS_Accept_sec_context(), which verifies the authenticator, provides
+ the service with the client's authenticated name, and returns an
+ output_context_handle.
+
+ Both parties now hold the session key associated with the service
+ ticket, and can use this key in subsequent GSS_GetMIC(),
+ GSS_VerifyMIC(), GSS_Wrap(), and GSS_Unwrap() operations.
+
+5.2: Kerberos V5, double-TGT
+
+ TGT acquisition as above.
+
+ Note: To avoid unnecessary frequent invocations of error paths when
+ implementing the GSS-API atop Kerberos V5, it seems appropriate to
+ represent "single-TGT K-V5" and "double-TGT K-V5" with separate
+ mech_types, and this discussion makes that assumption.
+
+ Based on the (specified or defaulted) mech_type,
+ GSS_Init_sec_context() determines that the double-TGT protocol
+ should be employed for the specified target. GSS_Init_sec_context()
+ returns GSS_S_CONTINUE_NEEDED major_status, and its returned
+ output_token contains a request to the service for the service's TGT.
+ (If a service TGT with suitably long remaining lifetime already
+ exists in a cache, it may be usable, obviating the need for this
+ step.) The client passes the output_token to the service. Note: this
+ scenario illustrates a different use for the GSS_S_CONTINUE_NEEDED
+ status return facility than for support of mutual authentication;
+ note that both uses can coexist as successive operations within a
+ single context establishment operation.
+
+ The service passes the received token as the input_token argument to
+ GSS_Accept_sec_context(), which recognizes it as a request for TGT.
+ (Note that current Kerberos V5 defines no intra-protocol mechanism to
+ represent such a request.) GSS_Accept_sec_context() returns
+ GSS_S_CONTINUE_NEEDED major_status and provides the service's TGT in
+ its output_token. The service sends the output_token to the client.
+
+ The client passes the received token as the input_token argument to a
+ continuation of GSS_Init_sec_context(). GSS_Init_sec_context() caches
+ the received service TGT and uses it as part of a service ticket
+ request to the Kerberos authentication server, storing the returned
+ service ticket and session key in conjunction with the context.
+ GSS_Init_sec_context() builds a Kerberos-formatted authenticator,
+
+
+
+Linn Standards Track [Page 80]
+
+RFC 2078 GSS-API January 1997
+
+
+ and returns it in output_token along with GSS_S_COMPLETE return
+ major_status. The client sends the output_token to the service.
+
+ Service passes the received token as the input_token argument to a
+ continuation call to GSS_Accept_sec_context().
+ GSS_Accept_sec_context() verifies the authenticator, provides the
+ service with the client's authenticated name, and returns
+ major_status GSS_S_COMPLETE.
+
+ GSS_GetMIC(), GSS_VerifyMIC(), GSS_Wrap(), and GSS_Unwrap() as
+ above.
+
+5.3: X.509 Authentication Framework
+
+ This example illustrates use of the GSS-API in conjunction with
+ public-key mechanisms, consistent with the X.509 Directory
+ Authentication Framework.
+
+ The GSS_Acquire_cred() call establishes a credentials structure,
+ making the client's private key accessible for use on behalf of the
+ client.
+
+ The client calls GSS_Init_sec_context(), which interrogates the
+ Directory to acquire (and validate) a chain of public-key
+ certificates, thereby collecting the public key of the service. The
+ certificate validation operation determines that suitable integrity
+ checks were applied by trusted authorities and that those
+ certificates have not expired. GSS_Init_sec_context() generates a
+ secret key for use in per-message protection operations on the
+ context, and enciphers that secret key under the service's public
+ key.
+
+ The enciphered secret key, along with an authenticator quantity
+ signed with the client's private key, is included in the output_token
+ from GSS_Init_sec_context(). The output_token also carries a
+ certification path, consisting of a certificate chain leading from
+ the service to the client; a variant approach would defer this path
+ resolution to be performed by the service instead of being asserted
+ by the client. The client application sends the output_token to the
+ service.
+
+ The service passes the received token as the input_token argument to
+ GSS_Accept_sec_context(). GSS_Accept_sec_context() validates the
+ certification path, and as a result determines a certified binding
+ between the client's distinguished name and the client's public key.
+ Given that public key, GSS_Accept_sec_context() can process the
+ input_token's authenticator quantity and verify that the client's
+ private key was used to sign the input_token. At this point, the
+
+
+
+Linn Standards Track [Page 81]
+
+RFC 2078 GSS-API January 1997
+
+
+ client is authenticated to the service. The service uses its private
+ key to decipher the enciphered secret key provided to it for per-
+ message protection operations on the context.
+
+ The client calls GSS_GetMIC() or GSS_Wrap() on a data message, which
+ causes per-message authentication, integrity, and (optional)
+ confidentiality facilities to be applied to that message. The service
+ uses the context's shared secret key to perform corresponding
+ GSS_VerifyMIC() and GSS_Unwrap() calls.
+
+6: Security Considerations
+
+ Security issues are discussed throughout this memo.
+
+7: Related Activities
+
+ In order to implement the GSS-API atop existing, emerging, and future
+ security mechanisms:
+
+ object identifiers must be assigned to candidate GSS-API
+ mechanisms and the name types which they support
+
+ concrete data element formats and processing procedures must be
+ defined for candidate mechanisms
+
+ Calling applications must implement formatting conventions which will
+ enable them to distinguish GSS-API tokens from other data carried in
+ their application protocols.
+
+ Concrete language bindings are required for the programming
+ environments in which the GSS-API is to be employed, as RFC-1509
+ defines for the C programming language and GSS-V1.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 82]
+
+RFC 2078 GSS-API January 1997
+
+
+APPENDIX A
+
+MECHANISM DESIGN CONSTRAINTS
+
+ The following constraints on GSS-API mechanism designs are adopted in
+ response to observed caller protocol requirements, and adherence
+ thereto is anticipated in subsequent descriptions of GSS-API
+ mechanisms to be documented in standards-track Internet
+ specifications.
+
+ It is strongly recommended that mechanisms offering per-message
+ protection services also offer at least one of the replay detection
+ and sequencing services, as mechanisms offering neither of the latter
+ will fail to satisfy recognized requirements of certain candidate
+ caller protocols.
+
+APPENDIX B
+
+ COMPATIBILITY WITH GSS-V1
+
+ It is the intent of this document to define an interface and
+ procedures which preserve compatibility between GSS-V1 (RFC-1508)
+ callers and GSS- V2 providers. All calls defined in GSS-V1 are
+ preserved, and it has been a goal that GSS-V1 callers should be able
+ to operate atop GSS-V2 provider implementations. Certain detailed
+ changes, summarized in this section, have been made in order to
+ resolve omissions identified in GSS-V1.
+
+ The following GSS-V1 constructs, while supported within GSS-V2, are
+ deprecated:
+
+ Names for per-message processing routines: GSS_Seal() deprecated
+ in favor of GSS_Wrap(); GSS_Sign() deprecated in favor of
+ GSS_GetMIC(); GSS_Unseal() deprecated in favor of GSS_Unwrap();
+ GSS_Verify() deprecated in favor of GSS_VerifyMIC().
+
+ GSS_Delete_sec_context() facility for context_token usage,
+ allowing mechanisms to signal context deletion, is retained for
+ compatibility with GSS-V1. For current usage, it is recommended
+ that both peers to a context invoke GSS_Delete_sec_context()
+ independently, passing a null output_context_token buffer to
+ indicate that no context_token is required. Implementations of
+ GSS_Delete_sec_context() should delete relevant locally-stored
+ context information.
+
+
+
+
+
+
+
+Linn Standards Track [Page 83]
+
+RFC 2078 GSS-API January 1997
+
+
+ This GSS-V2 specification adds the following calls which are not
+ present in GSS-V1:
+
+ Credential management calls: GSS_Add_cred(),
+ GSS_Inquire_cred_by_mech().
+
+ Context-level calls: GSS_Inquire_context(), GSS_Wrap_size_limit(),
+ GSS_Export_sec_context(), GSS_Import_sec_context().
+
+ Per-message calls: No new calls. Existing calls have been renamed.
+
+ Support calls: GSS_Create_empty_OID_set(),
+ GSS_Add_OID_set_member(), GSS_Test_OID_set_member(),
+ GSS_Release_OID(), GSS_OID_to_str(), GSS_Str_to_OID(),
+ GSS_Inquire_names_for_mech(), GSS_Inquire_mechs_for_name(),
+ GSS_Canonicalize_name(), GSS_Export_name(), GSS_Duplicate_name().
+
+ This GSS-V2 specification introduces three new facilities applicable
+ to security contexts, indicated using the following context state
+ values which are not present in GSS-V1:
+
+ anon_state, set TRUE to indicate that a context's initiator is
+ anonymous from the viewpoint of the target; Section 1.2.5 of this
+ specification provides a summary description of the GSS-V2
+ anonymity support facility, support and use of which is optional.
+
+ prot_ready_state, set TRUE to indicate that a context may be used
+ for per-message protection before final completion of context
+ establishment; Section 1.2.7 of this specification provides a
+ summary description of the GSS-V2 facility enabling mechanisms to
+ selectively permit per-message protection during context
+ establishment, support and use of which is optional.
+
+ trans_state, set TRUE to indicate that a context is transferable to
+ another process using the GSS-V2 GSS_Export_sec_context() facility.
+
+ These state values are represented (at the C bindings level) in
+ positions within a bit vector which are unused in GSS-V1, and may be
+ safely ignored by GSS-V1 callers.
+
+ Relative to GSS-V1, GSS-V2 provides additional guidance to GSS-API
+ implementors in the following areas: implementation robustness,
+ credential management, behavior in multi-mechanism configurations,
+ naming support, and inclusion of optional sequencing services. The
+ token tagging facility as defined in GSS-V2, Section 3.1, is now
+ described directly in terms of octets to facilitate interoperable
+ implementation without general ASN.1 processing code; the
+ corresponding ASN.1 syntax, included for descriptive purposes, is
+
+
+
+Linn Standards Track [Page 84]
+
+RFC 2078 GSS-API January 1997
+
+
+ unchanged from that in GSS-V1. For use in conjunction with added
+ naming support facilities, a new Exported Name Object construct is
+ added. Additional name types are introduced in Section 4.
+
+ This GSS-V2 specification adds the following major_status values
+ which are not defined in GSS-V1:
+
+ GSS_S_BAD_QOP unsupported QOP value
+ GSS_S_UNAUTHORIZED operation unauthorized
+ GSS_S_UNAVAILABLE operation unavailable
+ GSS_S_DUPLICATE_ELEMENT duplicate credential element requested
+ GSS_S_NAME_NOT_MN name contains multi-mechanism elements
+ GSS_S_GAP_TOKEN skipped predecessor token(s)
+ detected
+
+ Of these added status codes, only two values are defined to be
+ returnable by calls existing in GSS-V1: GSS_S_BAD_QOP (returnable by
+ GSS_GetMIC() and GSS_Wrap()), and GSS_S_GAP_TOKEN (returnable by
+ GSS_VerifyMIC() and GSS_Unwrap()).
+
+ Additionally, GSS-V2 descriptions of certain calls present in GSS-V1
+ have been updated to allow return of additional major_status values
+ from the set as defined in GSS-V1: GSS_Inquire_cred() has
+ GSS_S_DEFECTIVE_CREDENTIAL and GSS_S_CREDENTIALS_EXPIRED defined as
+ returnable, GSS_Init_sec_context() has GSS_S_OLD_TOKEN,
+ GSS_S_DUPLICATE_TOKEN, and GSS_S_BAD_MECH defined as returnable, and
+ GSS_Accept_sec_context() has GSS_S_BAD_MECH defined as returnable.
+
+Author's Address
+
+ John Linn
+ OpenVision Technologies
+ One Main St.
+ Cambridge, MA 02142 USA
+
+ Phone: +1 617.374.2245
+ EMail: John.Linn@ov.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Linn Standards Track [Page 85]
+
diff --git a/crypto/heimdal/doc/standardisation/rfc2203.txt b/crypto/heimdal/doc/standardisation/rfc2203.txt
new file mode 100644
index 000000000000..2f6a8a0d0f37
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/rfc2203.txt
@@ -0,0 +1,1291 @@
+
+
+
+
+
+
+Network Working Group M. Eisler
+Request for Comments: 2203 A. Chiu
+Category: Standards Track L. Ling
+ September 1997
+
+
+ RPCSEC_GSS Protocol Specification
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Abstract
+
+ This memo describes an ONC/RPC security flavor that allows RPC
+ protocols to access the Generic Security Services Application
+ Programming Interface (referred to henceforth as GSS-API).
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
+ 2. The ONC RPC Message Protocol . . . . . . . . . . . . . . . . . 2
+ 3. Flavor Number Assignment . . . . . . . . . . . . . . . . . . . 3
+ 4. New auth_stat Values . . . . . . . . . . . . . . . . . . . . . 3
+ 5. Elements of the RPCSEC_GSS Security Protocol . . . . . . . . . 3
+ 5.1. Version Selection . . . . . . . . . . . . . . . . . . . . . 5
+ 5.2. Context Creation . . . . . . . . . . . . . . . . . . . . . . 5
+ 5.2.1. Mechanism and QOP Selection . . . . . . . . . . . . . . . 5
+ 5.2.2. Context Creation Requests . . . . . . . . . . . . . . . . 6
+ 5.2.3. Context Creation Responses . . . . . . . . . . . . . . . . 8
+ 5.2.3.1. Context Creation Response - Successful Acceptance . . . 8
+ 5.2.3.1.1. Client Processing of Successful Context Creation
+ Responses . . . . . . . . . . . . . . . . . . . . . . 9
+ 5.2.3.2. Context Creation Response - Unsuccessful Cases . . . . . 9
+ 5.3. RPC Data Exchange . . . . . . . . . . . . . . . . . . . . 10
+ 5.3.1. RPC Request Header . . . . . . . . . . . . . . . . . . . 10
+ 5.3.2. RPC Request Data . . . . . . . . . . . . . . . . . . . . 11
+ 5.3.2.1. RPC Request Data - No Data Integrity . . . . . . . . . 11
+ 5.3.2.2. RPC Request Data - With Data Integrity . . . . . . . . 11
+ 5.3.2.3. RPC Request Data - With Data Privacy . . . . . . . . . 12
+ 5.3.3. Server Processing of RPC Data Requests . . . . . . . . . 12
+ 5.3.3.1. Context Management . . . . . . . . . . . . . . . . . . 12
+ 5.3.3.2. Server Reply - Request Accepted . . . . . . . . . . . 14
+ 5.3.3.3. Server Reply - Request Denied . . . . . . . . . . . . 15
+
+
+
+Eisler, et. al. Standards Track [Page 1]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ 5.3.3.4. Mapping of GSS-API Errors to Server Responses . . . . 16
+ 5.3.3.4.1. GSS_GetMIC() Failure . . . . . . . . . . . . . . . . 16
+ 5.3.3.4.2. GSS_VerifyMIC() Failure . . . . . . . . . . . . . . 16
+ 5.3.3.4.3. GSS_Unwrap() Failure . . . . . . . . . . . . . . . . 16
+ 5.3.3.4.4. GSS_Wrap() Failure . . . . . . . . . . . . . . . . . 16
+ 5.4. Context Destruction . . . . . . . . . . . . . . . . . . . 17
+ 6. Set of GSS-API Mechanisms . . . . . . . . . . . . . . . . . 17
+ 7. Security Considerations . . . . . . . . . . . . . . . . . . 18
+ 7.1. Privacy of Call Header . . . . . . . . . . . . . . . . . . 18
+ 7.2. Sequence Number Attacks . . . . . . . . . . . . . . . . . 18
+ 7.2.1. Sequence Numbers Above the Window . . . . . . . . . . . 18
+ 7.2.2. Sequence Numbers Within or Below the Window . . . . . . 18
+ 7.3. Message Stealing Attacks . . . . . . . . . . . . . . . . . 19
+ Appendix A. GSS-API Major Status Codes . . . . . . . . . . . . . 20
+ Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 22
+ Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 23
+
+1. Introduction
+
+ This document describes the protocol used by the RPCSEC_GSS security
+ flavor. Security flavors have been called authentication flavors for
+ historical reasons. This memo recognizes that there are two other
+ security services besides authentication, integrity, and privacy, and
+ so defines a new RPCSEC_GSS security flavor.
+
+ The protocol is described using the XDR language [Srinivasan-xdr].
+ The reader is assumed to be familiar with ONC RPC and the security
+ flavor mechanism [Srinivasan-rpc]. The reader is also assumed to be
+ familiar with the GSS-API framework [Linn]. The RPCSEC_GSS security
+ flavor uses GSS-API interfaces to provide security services that are
+ independent of the underlying security mechanism.
+
+2. The ONC RPC Message Protocol
+
+ This memo refers to the following XDR types of the ONC RPC protocol,
+ which are described in the document entitled Remote Procedure Call
+ Protocol Specification Version 2 [Srinivasan-rpc]:
+
+ msg_type
+ reply_stat
+ auth_flavor
+ accept_stat
+ reject_stat
+ auth_stat
+ opaque_auth
+ rpc_msg
+ call_body
+ reply_body
+
+
+
+Eisler, et. al. Standards Track [Page 2]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ accepted_reply
+ rejected_reply
+
+3. Flavor Number Assignment
+
+ The RPCSEC_GSS security flavor has been assigned the value of 6:
+
+ enum auth_flavor {
+ ...
+ RPCSEC_GSS = 6 /* RPCSEC_GSS security flavor */
+ };
+
+4. New auth_stat Values
+
+ RPCSEC_GSS requires the addition of two new values to the auth_stat
+ enumerated type definition:
+
+ enum auth_stat {
+ ...
+ /*
+ * RPCSEC_GSS errors
+ */
+ RPCSEC_GSS_CREDPROBLEM = 13,
+ RPCSEC_GSS_CTXPROBLEM = 14
+ };
+
+ The descriptions of these two new values are defined later in this
+ memo.
+
+5. Elements of the RPCSEC_GSS Security Protocol
+
+ An RPC session based on the RPCSEC_GSS security flavor consists of
+ three phases: context creation, RPC data exchange, and context
+ destruction. In the following discussion, protocol elements for
+ these three phases are described.
+
+ The following description of the RPCSEC_GSS protocol uses some of the
+ definitions within XDR language description of the RPC protocol.
+
+ Context creation and destruction use control messages that are not
+ dispatched to service procedures registered by an RPC server. The
+ program and version numbers used in these control messages are the
+ same as the RPC service's program and version numbers. The procedure
+ number used is NULLPROC (zero). A field in the credential
+ information (the gss_proc field which is defined in the
+ rpc_gss_cred_t structure below) specifies whether a message is to be
+ interpreted as a control message or a regular RPC message. If this
+ field is set to RPCSEC_GSS_DATA, no control action is implied; in
+
+
+
+Eisler, et. al. Standards Track [Page 3]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ this case, it is a regular data message. If this field is set to any
+ other value, a control action is implied. This is described in the
+ following sections.
+
+ Just as with normal RPC data exchange messages, the transaction
+ identifier (the xid field in struct rpc_msg), should be set to unique
+ values on each call for context creation and context destruction.
+
+ The following definitions are used for describing the protocol.
+
+ /* RPCSEC_GSS control procedures */
+
+
+ enum rpc_gss_proc_t {
+ RPCSEC_GSS_DATA = 0,
+ RPCSEC_GSS_INIT = 1,
+ RPCSEC_GSS_CONTINUE_INIT = 2,
+ RPCSEC_GSS_DESTROY = 3
+ };
+
+ /* RPCSEC_GSS services */
+
+ enum rpc_gss_service_t {
+ /* Note: the enumerated value for 0 is reserved. */
+ rpc_gss_svc_none = 1,
+ rpc_gss_svc_integrity = 2,
+ rpc_gss_svc_privacy = 3
+ };
+
+ /* Credential */
+
+ /*
+ * Note: version 0 is reserved for possible future
+ * definition of a version negotiation protocol
+ *
+ */
+ #define RPCSEC_GSS_VERS_1 1
+
+ struct rpc_gss_cred_t {
+ union switch (unsigned int version) { /* version of
+ RPCSEC_GSS */
+ case RPCSEC_GSS_VERS_1:
+ struct {
+ rpc_gss_proc_t gss_proc; /* control procedure */
+ unsigned int seq_num; /* sequence number */
+ rpc_gss_service_t service; /* service used */
+ opaque handle<>; /* context handle */
+ } rpc_gss_cred_vers_1_t;
+
+
+
+Eisler, et. al. Standards Track [Page 4]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ }
+ };
+
+ /* Maximum sequence number value */
+
+ #define MAXSEQ 0x80000000
+
+5.1. Version Selection
+
+ This document defines just one protocol version (RPCSEC_GSS_VERS_1).
+ The client should assume that the server supports RPCSEC_GSS_VERS_1
+ and issue a Context Creation message (as described in the section
+ RPCSEC_GSS_VERS_1, the RPC response will have a reply_stat of
+ MSG_DENIED, a rejection status of AUTH_ERROR, and an auth_stat of
+ AUTH_REJECTED_CRED.
+
+5.2. Context Creation
+
+ Before RPC data is exchanged on a session using the RPCSEC_GSS
+ flavor, a context must be set up between the client and the server.
+ Context creation may involve zero or more RPC exchanges. The number
+ of exchanges depends on the security mechanism.
+
+5.2.1. Mechanism and QOP Selection
+
+ There is no facility in the RPCSEC_GSS protocol to negotiate GSS-API
+ mechanism identifiers or QOP values. At minimum, it is expected that
+ implementations of the RPCSEC_GSS protocol provide a means to:
+
+ * specify mechanism identifiers, QOP values, and RPCSEC_GSS
+ service values on the client side, and to
+
+ * enforce mechanism identifiers, QOP values, and RPCSEC_GSS
+ service values on a per-request basis on the server side.
+
+ It is necessary that above capabilities exist so that applications
+ have the means to conform the required set of required set of
+ <mechanism, QOP, service> tuples (See the section entitled Set of
+ GSS-API Mechanisms). An application may negotiate <mechanism, QOP,
+ service> selection within its protocol or via an out of band
+ protocol. Hence it may be necessary for RPCSEC_GSS implementations to
+ provide programming interfaces for the specification and enforcement
+ of <mechanism, QOP, service>.
+
+ Additionally, implementations may depend on negotiation schemes
+ constructed as pseudo-mechanisms under the GSS-API. Because such
+ schemes are below the GSS-API layer, the RPCSEC_GSS protocol, as
+ specified in this document, can make use of them.
+
+
+
+Eisler, et. al. Standards Track [Page 5]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+5.2.2. Context Creation Requests
+
+ The first RPC request from the client to the server initiates context
+ creation. Within the RPC message protocol's call_body structure,
+ rpcvers is set to 2. prog and vers are always those for the service
+ being accessed. The proc is always set to NULLPROC (zero).
+
+ Within the RPC message protocol's cred structure, flavor is set to
+ RPCSEC_GSS (6). The opaque data of the cred structure (the body
+ field) constituting the credential encodes the rpc_gss_cred_t
+ structure defined previously.
+
+ The values of the fields contained in the rpc_gss_cred_t structure
+ are set as follows. The version field is set to the version of the
+ RPCSEC_GSS protocol the client wants to use. The remainder of this
+ memo documents version RPCSEC_GSS_VERS_1 of RPCSEC_GSS, and so the
+ version field would be set to RPCSEC_GSS_VERS_1. The gss_proc field
+ must be set to RPCSEC_GSS_INIT for the first creation request. In
+ subsequent creation requests, the gss_proc field must be set to
+ RPCSEC_GSS_CONTINUE_INIT. In a creation request, the seq_num and
+ service fields are undefined and both must be ignored by the server.
+ In the first creation request, the handle field is NULL (opaque data
+ of zero length). In subsequent creation requests, handle must be
+ equal to the value returned by the server. The handle field serves
+ as the identifier for the context, and will not change for the
+ duration of the context, including responses to
+ RPCSEC_GSS_CONTINUE_INIT.
+
+ The verifier field in the RPC message header is also described by the
+ opaque_auth structure. All creation requests have the NULL verifier
+ (AUTH_NONE flavor with zero length opaque data).
+
+ Following the verifier are the call data (procedure specific
+ parameters). Note that the proc field of the call_body structure is
+ set to NULLPROC, and thus normally there would be zero octets
+ following the verifier. However, since there is no RPC data exchange
+ during a context creation, it is safe to transfer information
+ following the verifier. It is necessary to "overload" the call data
+ in this way, rather than pack the GSS-API token into the RPC header,
+ because RPC Version 2 restricts the amount of data that can be sent
+ in the header. The opaque body of the credential and verifier fields
+ can be each at most 400 octets long, and GSS tokens can be longer
+ than 800 octets.
+
+
+
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 6]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ The call data for a context creation request is described by the
+ following structure for all creation requests:
+
+ struct rpc_gss_init_arg {
+ opaque gss_token<>;
+ };
+
+ Here, gss_token is the token returned by the call to GSS-API's
+ GSS_Init_sec_context() routine, opaquely encoded. The value of this
+ field will likely be different in each creation request, if there is
+ more than one creation request. If no token is returned by the call
+ to GSS_Init_sec_context(), the context must have been created
+ (assuming no errors), and there will not be any more creation
+ requests.
+
+ When GSS_Init_sec_context() is called, the parameters
+ replay_det_req_flag and sequence_req_flag must be turned off. The
+ reasons for this are:
+
+ * ONC RPC can be used over unreliable transports and provides no
+ layer to reliably re-assemble messages. Thus it is possible for
+ gaps in message sequencing to occur, as well as out of order
+ messages.
+
+ * RPC servers can be multi-threaded, and thus the order in which
+ GSS-API messages are signed or wrapped can be different from the
+ order in which the messages are verified or unwrapped, even if
+ the requests are sent on reliable transports.
+
+ * To maximize convenience of implementation, the order in which an
+ ONC RPC entity will verify the header and verify/unwrap the body
+ of an RPC call or reply is left unspecified.
+
+ The RPCSEC_GSS protocol provides for protection from replay attack,
+ yet tolerates out-of-order delivery or processing of messages and
+ tolerates dropped requests.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 7]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+5.2.3. Context Creation Responses
+
+5.2.3.1. Context Creation Response - Successful Acceptance
+
+ The response to a successful creation request has an MSG_ACCEPTED
+ response with a status of SUCCESS. The results field encodes a
+ response with the following structure:
+
+ struct rpc_gss_init_res {
+ opaque handle<>;
+ unsigned int gss_major;
+ unsigned int gss_minor;
+ unsigned int seq_window;
+ opaque gss_token<>;
+ };
+
+ Here, handle is non-NULL opaque data that serves as the context
+ identifier. The client must use this value in all subsequent requests
+ whether control messages or otherwise). The gss_major and gss_minor
+ fields contain the results of the call to GSS_Accept_sec_context()
+ executed by the server. The values for the gss_major field are
+ defined in Appendix A of this document. The values for the gss_minor
+ field are GSS-API mechanism specific and are defined in the
+ mechanism's specification. If gss_major is not one of GSS_S_COMPLETE
+ or GSS_S_CONTINUE_NEEDED, the context setup has failed; in this case
+ handle and gss_token must be set to NULL by the server. The value of
+ gss_minor is dependent on the value of gss_major and the security
+ mechanism used. The gss_token field contains any token returned by
+ the GSS_Accept_sec_context() call executed by the server. A token
+ may be returned for both successful values of gss_major. If the
+ value is GSS_S_COMPLETE, it indicates that the server is not
+ expecting any more tokens, and the RPC Data Exchange phase must begin
+ on the subsequent request from the client. If the value is
+ GSS_S_CONTINUE_NEEDED, the server is expecting another token. Hence
+ the client must send at least one more creation request (with
+ gss_proc set to RPCSEC_GSS_CONTINUE_INIT in the request's credential)
+ carrying the required token.
+
+ In a successful response, the seq_window field is set to the sequence
+ window length supported by the server for this context. This window
+ specifies the maximum number of client requests that may be
+ outstanding for this context. The server will accept "seq_window"
+ requests at a time, and these may be out of order. The client may
+ use this number to determine the number of threads that can
+ simultaneously send requests on this context.
+
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 8]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ If gss_major is GSS_S_COMPLETE, the verifier's (the verf element in
+ the response) flavor field is set to RPCSEC_GSS, and the body field
+ set to the checksum of the seq_window (in network order). The QOP
+ used for this checksum is 0 (zero), which is the default QOP. For
+ all other values of gss_major, a NULL verifier (AUTH_NONE flavor with
+ zero-length opaque data) is used.
+
+5.2.3.1.1. Client Processing of Successful Context Creation Responses
+
+ If the value of gss_major in the response is GSS_S_CONTINUE_NEEDED,
+ then the client, per the GSS-API specification, must invoke
+ GSS_Init_sec_context() using the token returned in gss_token in the
+ context creation response. The client must then generate a context
+ creation request, with gss_proc set to RPCSEC_GSS_CONTINUE_INIT.
+
+ If the value of gss_major in the response is GSS_S_COMPLETE, and if
+ the client's previous invocation of GSS_Init_sec_context() returned a
+ gss_major value of GSS_S_CONTINUE_NEEDED, then the client, per the
+ GSS-API specification, must invoke GSS_Init_sec_context() using the
+ token returned in gss_token in the context creation response. If
+ GSS_Init_sec_context() returns GSS_S_COMPLETE, the context is
+ successfully set up, and the RPC data exchange phase must begin on
+ the subsequent request from the client.
+
+5.2.3.2. Context Creation Response - Unsuccessful Cases
+
+ An MSG_ACCEPTED reply (to a creation request) with an acceptance
+ status of other than SUCCESS has a NULL verifier (flavor set to
+ AUTH_NONE, and zero length opaque data in the body field), and is
+ formulated as usual for different status values.
+
+ An MSG_DENIED reply (to a creation request) is also formulated as
+ usual. Note that MSG_DENIED could be returned because the server's
+ RPC implementation does not recognize the RPCSEC_GSS security flavor.
+ RFC 1831 does not specify the appropriate reply status in this
+ instance, but common implementation practice appears to be to return
+ a rejection status of AUTH_ERROR with an auth_stat of
+ AUTH_REJECTEDCRED. Even though two new values (RPCSEC_GSS_CREDPROBLEM
+ and RPCSEC_GSS_CTXPROBLEM) have been defined for the auth_stat type,
+ neither of these two can be returned in responses to context creation
+ requests. The auth_stat new values can be used for responses to
+ normal (data) requests. This is described later.
+
+ MSG_DENIED might also be returned if the RPCSEC_GSS version number in
+ the credential is not supported on the server. In that case, the
+ server returns a rejection status of AUTH_ERROR, with an auth_stat of
+
+ AUTH_REJECTED_CRED.
+
+
+
+Eisler, et. al. Standards Track [Page 9]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+5.3. RPC Data Exchange
+
+ The data exchange phase is entered after a context has been
+ successfully set up. The format of the data exchanged depends on the
+ security service used for the request. Although clients can change
+ the security service and QOP used on a per-request basis, this may
+ not be acceptable to all RPC services; some RPC services may "lock"
+ the data exchange phase into using the QOP and service used on the
+ first data exchange message. For all three modes of service (no data
+ integrity, data integrity, data privacy), the RPC request header has
+ the same format.
+
+5.3.1. RPC Request Header
+
+ The credential has the opaque_auth structure described earlier. The
+ flavor field is set to RPCSEC_GSS. The credential body is created by
+ XDR encoding the rpc_gss_cred_t structure listed earlier into an
+ octet stream, and then opaquely encoding this octet stream as the
+ body field.
+
+ Values of the fields contained in the rpc_gss_cred_t structure are
+ set as follows. The version field is set to same version value that
+ was used to create the context, which within the scope of this memo
+ will always be RPCSEC_GSS_VERS_1. The gss_proc field is set to
+ RPCSEC_GSS_DATA. The service field is set to indicate the desired
+ service (one of rpc_gss_svc_none, rpc_gss_svc_integrity, or
+ rpc_gss_svc_privacy). The handle field is set to the context handle
+ value received from the RPC server during context creation. The
+ seq_num field can start at any value below MAXSEQ, and must be
+ incremented (by one or more) for successive requests. Use of
+ sequence numbers is described in detail when server processing of the
+ request is discussed.
+
+ The verifier has the opaque_auth structure described earlier. The
+ flavor field is set to RPCSEC_GSS. The body field is set as follows.
+ The checksum of the RPC header (up to and including the credential)
+ is computed using the GSS_GetMIC() call with the desired QOP. This
+ returns the checksum as an opaque octet stream and its length. This
+ is encoded into the body field. Note that the QOP is not explicitly
+ specified anywhere in the request. It is implicit in the checksum or
+ encrypted data. The same QOP value as is used for the header
+ checksum must also be used for the data (for checksumming or
+ encrypting), unless the service used for the request is
+ rpc_gss_svc_none.
+
+
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 10]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+5.3.2. RPC Request Data
+
+5.3.2.1. RPC Request Data - No Data Integrity
+
+ If the service specified is rpc_gss_svc_none, the data (procedure
+ arguments) are not integrity or privacy protected. They are sent in
+ exactly the same way as they would be if the AUTH_NONE flavor were
+ used (following the verifier). Note, however, that since the RPC
+ header is integrity protected, the sender will still be authenticated
+ in this case.
+
+5.3.2.2. RPC Request Data - With Data Integrity
+
+ When data integrity is used, the request data is represented as
+ follows:
+
+ struct rpc_gss_integ_data {
+ opaque databody_integ<>;
+ opaque checksum<>;
+ };
+
+ The databody_integ field is created as follows. A structure
+ consisting of a sequence number followed by the procedure arguments
+ is constructed. This is shown below as the type rpc_gss_data_t:
+
+ struct rpc_gss_data_t {
+ unsigned int seq_num;
+ proc_req_arg_t arg;
+ };
+
+ Here, seq_num must have the same value as in the credential. The
+ type proc_req_arg_t is the procedure specific XDR type describing the
+ procedure arguments (and so is not specified here). The octet stream
+ corresponding to the XDR encoded rpc_gss_data_t structure and its
+ length are placed in the databody_integ field. Note that because the
+ XDR type of databody_integ is opaque, the XDR encoding of
+ databody_integ will include an initial four octet length field,
+ followed by the XDR encoded octet stream of rpc_gss_data_t.
+
+ The checksum field represents the checksum of the XDR encoded octet
+ stream corresponding to the XDR encoded rpc_gss_data_t structure
+ (note, this is not the checksum of the databody_integ field). This
+ is obtained using the GSS_GetMIC() call, with the same QOP as was
+ used to compute the header checksum (in the verifier). The
+
+
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 11]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ GSS_GetMIC() call returns the checksum as an opaque octet stream and
+ its length. The checksum field of struct rpc_gss_integ_data has an
+ XDR type of opaque. Thus the checksum length from GSS_GetMIC() is
+ encoded as a four octet length field, followed by the checksum,
+ padded to a multiple of four octets.
+
+5.3.2.3. RPC Request Data - With Data Privacy
+
+ When data privacy is used, the request data is represented as
+ follows:
+
+ struct rpc_gss_priv_data {
+ opaque databody_priv<>
+ };
+
+ The databody_priv field is created as follows. The rpc_gss_data_t
+ structure described earlier is constructed again in the same way as
+ for the case of data integrity. Next, the GSS_Wrap() call is invoked
+ to encrypt the octet stream corresponding to the rpc_gss_data_t
+ structure, using the same value for QOP (argument qop_req to
+ GSS_Wrap()) as was used for the header checksum (in the verifier) and
+ conf_req_flag (an argument to GSS_Wrap()) of TRUE. The GSS_Wrap()
+ call returns an opaque octet stream (representing the encrypted
+ rpc_gss_data_t structure) and its length, and this is encoded as the
+ databody_priv field. Since databody_priv has an XDR type of opaque,
+ the length returned by GSS_Wrap() is encoded as the four octet
+ length, followed by the encrypted octet stream (padded to a multiple
+ of four octets).
+
+5.3.3. Server Processing of RPC Data Requests
+
+5.3.3.1. Context Management
+
+ When a request is received by the server, the following are verified
+ to be acceptable:
+
+ * the version number in the credential
+
+ * the service specified in the credential
+
+ * the context handle specified in the credential
+
+ * the header checksum in the verifier (via GSS_VerifyMIC())
+
+ * the sequence number (seq_num) specified in the credential (more
+ on this follows)
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 12]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ The gss_proc field in the credential must be set to RPCSEC_GSS_DATA
+ for data requests (otherwise, the message will be interpreted as a
+ control message).
+
+ The server maintains a window of "seq_window" sequence numbers,
+ starting with the last sequence number seen and extending backwards.
+ If a sequence number higher than the last number seen is received
+ (AND if GSS_VerifyMIC() on the header checksum from the verifier
+ returns GSS_S_COMPLETE), the window is moved forward to the new
+ sequence number. If the last sequence number seen is N, the server
+ is prepared to receive requests with sequence numbers in the range N
+ through (N - seq_window + 1), both inclusive. If the sequence number
+ received falls below this range, it is silently discarded. If the
+ sequence number is within this range, and the server has not seen it,
+ the request is accepted, and the server turns on a bit to "remember"
+ that this sequence number has been seen. If the server determines
+ that it has already seen a sequence number within the window, the
+ request is silently discarded. The server should select a seq_window
+ value based on the number requests it expects to process
+ simultaneously. For example, in a threaded implementation seq_window
+ might be equal to the number of server threads. There are no known
+ security issues with selecting a large window. The primary issue is
+ how much space the server is willing to allocate to keep track of
+ requests received within the window.
+
+ The reason for discarding requests silently is that the server is
+ unable to determine if the duplicate or out of range request was due
+ to a sequencing problem in the client, network, or the operating
+ system, or due to some quirk in routing, or a replay attack by an
+ intruder. Discarding the request allows the client to recover after
+ timing out, if indeed the duplication was unintentional or well
+ intended. Note that a consequence of the silent discard is that
+ clients may increment the seq_num by more than one. The effect of
+ this is that the window will move forward more quickly. It is not
+ believed that there is any benefit to doing this.
+
+ Note that the sequence number algorithm requires that the client
+ increment the sequence number even if it is retrying a request with
+ the same RPC transaction identifier. It is not infrequent for
+ clients to get into a situation where they send two or more attempts
+ and a slow server sends the reply for the first attempt. With
+ RPCSEC_GSS, each request and reply will have a unique sequence
+ number. If the client wishes to improve turn around time on the RPC
+ call, it can cache the RPCSEC_GSS sequence number of each request it
+ sends. Then when it receives a response with a matching RPC
+ transaction identifier, it can compute the checksum of each sequence
+ number in the cache to try to match the checksum in the reply's
+ verifier.
+
+
+
+Eisler, et. al. Standards Track [Page 13]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ The data is decoded according to the service specified in the
+ credential. In the case of integrity or privacy, the server ensures
+ that the QOP value is acceptable, and that it is the same as that
+ used for the header checksum in the verifier. Also, in the case of
+ integrity or privacy, the server will reject the message (with a
+ reply status of MSG_ACCEPTED, and an acceptance status of
+ GARBAGE_ARGS) if the sequence number embedded in the request body is
+ different from the sequence number in the credential.
+
+5.3.3.2. Server Reply - Request Accepted
+
+ An MSG_ACCEPTED reply to a request in the data exchange phase will
+ have the verifier's (the verf element in the response) flavor field
+ set to RPCSEC_GSS, and the body field set to the checksum (the output
+ of GSS_GetMIC()) of the sequence number (in network order) of the
+ corresponding request. The QOP used is the same as the QOP used for
+ the corresponding request.
+
+ If the status of the reply is not SUCCESS, the rest of the message is
+ formatted as usual.
+
+ If the status of the message is SUCCESS, the format of the rest of
+ the message depends on the service specified in the corresponding
+ request message. Basically, what follows the verifier in this case
+ are the procedure results, formatted in different ways depending on
+ the requested service.
+
+ If no data integrity was requested, the procedure results are
+ formatted as for the AUTH_NONE security flavor.
+
+ If data integrity was requested, the results are encoded in exactly
+ the same way as the procedure arguments were in the corresponding
+ request. See the section 'RPC Request Data - With Data Integrity.'
+ The only difference is that the structure representing the
+ procedure's result - proc_res_arg_t - must be substituted in place of
+ the request argument structure proc_req_arg_t. The QOP used for the
+ checksum must be the same as that used for constructing the reply
+ verifier.
+
+ If data privacy was requested, the results are encoded in exactly the
+ same way as the procedure arguments were in the corresponding
+ request. See the section 'RPC Request Data - With Data Privacy.' The
+ QOP used for encryption must be the same as that used for
+ constructing the reply verifier.
+
+
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 14]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+5.3.3.3. Server Reply - Request Denied
+
+ An MSG_DENIED reply (to a data request) is formulated as usual. Two
+ new values (RPCSEC_GSS_CREDPROBLEM and RPCSEC_GSS_CTXPROBLEM) have
+ been defined for the auth_stat type. When the reason for denial of
+ the request is a reject_stat of AUTH_ERROR, one of the two new
+ auth_stat values could be returned in addition to the existing
+ values. These two new values have special significance from the
+ existing reasons for denial of a request.
+
+ The server maintains a list of contexts for the clients that are
+ currently in session with it. Normally, a context is destroyed when
+ the client ends the session corresponding to it. However, due to
+ resource constraints, the server may destroy a context prematurely
+ (on an LRU basis, or if the server machine is rebooted, for example).
+ In this case, when a client request comes in, there may not be a
+ context corresponding to its handle. The server rejects the request,
+ with the reason RPCSEC_GSS_CREDPROBLEM in this case. Upon receiving
+ this error, the client must refresh the context - that is,
+ reestablish it after destroying the old one - and try the request
+ again. This error is also returned if the context handle matches
+ that of a different context that was allocated after the client's
+ context was destroyed (this will be detected by a failure in
+ verifying the header checksum).
+
+ If the GSS_VerifyMIC() call on the header checksum (contained in the
+ verifier) fails to return GSS_S_COMPLETE, the server rejects the
+ request and returns an auth_stat of RPCSEC_GSS_CREDPROBLEM.
+
+ When the client's sequence number exceeds the maximum the server will
+ allow, the server will reject the request with the reason
+ RPCSEC_GSS_CTXPROBLEM. Also, if security credentials become stale
+ while in use (due to ticket expiry in the case of the Kerberos V5
+ mechanism, for example), the failures which result cause the
+ RPCSEC_GSS_CTXPROBLEM reason to be returned. In these cases also,
+ the client must refresh the context, and retry the request.
+
+ For other errors, retrying will not rectify the problem and the
+ client must not refresh the context until the problem causing the
+ client request to be denied is rectified.
+
+ If the version field in the credential does not match the version of
+ RPCSEC_GSS that was used when the context was created, the
+ AUTH_BADCRED value is returned.
+
+ If there is a problem with the credential, such a bad length, illegal
+ control procedure, or an illegal service, the appropriate auth_stat
+ status is AUTH_BADCRED.
+
+
+
+Eisler, et. al. Standards Track [Page 15]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ Other errors can be returned as appropriate.
+
+5.3.3.4. Mapping of GSS-API Errors to Server Responses
+
+ During the data exchange phase, the server may invoke GSS_GetMIC(),
+ GSS_VerifyMIC(), GSS_Unwrap(), and GSS_Wrap(). If any of these
+ routines fail to return GSS_S_COMPLETE, then various unsuccessful
+ responses can be returned. The are described as follows for each of
+ the aforementioned four interfaces.
+
+5.3.3.4.1. GSS_GetMIC() Failure
+
+ When GSS_GetMIC() is called to generate the verifier in the response,
+ a failure results in an RPC response with a reply status of
+ MSG_DENIED, reject status of AUTH_ERROR and an auth status of
+ RPCSEC_GSS_CTXPROBLEM.
+
+ When GSS_GetMIC() is called to sign the call results (service is
+ rpc_gss_svc_integrity), a failure results in no RPC response being
+ sent. Since ONC RPC server applications will typically control when a
+ response is sent, the failure indication will be returned to the
+ server application and it can take appropriate action (such as
+ logging the error).
+
+5.3.3.4.2. GSS_VerifyMIC() Failure
+
+ When GSS_VerifyMIC() is called to verify the verifier in request, a
+ failure results in an RPC response with a reply status of MSG_DENIED,
+ reject status of AUTH_ERROR and an auth status of
+ RPCSEC_GSS_CREDPROBLEM.
+
+ When GSS_VerifyMIC() is called to verify the call arguments (service
+ is rpc_gss_svc_integrity), a failure results in an RPC response with
+ a reply status of MSG_ACCEPTED, and an acceptance status of
+ GARBAGE_ARGS.
+
+5.3.3.4.3. GSS_Unwrap() Failure
+
+ When GSS_Unwrap() is called to decrypt the call arguments (service is
+ rpc_gss_svc_privacy), a failure results in an RPC response with a
+ reply status of MSG_ACCEPTED, and an acceptance status of
+ GARBAGE_ARGS.
+
+5.3.3.4.4. GSS_Wrap() Failure
+
+ When GSS_Wrap() is called to encrypt the call results (service is
+ rpc_gss_svc_privacy), a failure results in no RPC response being
+ sent. Since ONC RPC server applications will typically control when a
+
+
+
+Eisler, et. al. Standards Track [Page 16]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ response is sent, the failure indication will be returned to the
+ application and it can take appropriate action (such as logging the
+ error).
+
+5.4. Context Destruction
+
+ When the client is done using the session, it must send a control
+ message informing the server that it no longer requires the context.
+ This message is formulated just like a data request packet, with the
+ following differences: the credential has gss_proc set to
+ RPCSEC_GSS_DESTROY, the procedure specified in the header is
+ NULLPROC, and there are no procedure arguments. The sequence number
+ in the request must be valid, and the header checksum in the verifier
+ must be valid, for the server to accept the message. The server
+ sends a response as it would to a data request. The client and
+ server must then destroy the context for the session.
+
+ If the request to destroy the context fails for some reason, the
+ client need not take any special action. The server must be prepared
+ to deal with situations where clients never inform the server that
+ they no longer are in session and so don't need the server to
+ maintain a context. An LRU mechanism or an aging mechanism should be
+ employed by the server to clean up in such cases.
+
+6. Set of GSS-API Mechanisms
+
+ RPCSEC_GSS is effectively a "pass-through" to the GSS-API layer, and
+ as such it is inappropriate for the RPCSEC_GSS specification to
+ enumerate a minimum set of required security mechanisms and/or
+ quality of protections.
+
+ If an application protocol specification references RPCSEC_GSS, the
+ protocol specification must list a mandatory set of { mechanism, QOP,
+ service } triples, such that an implementation cannot claim
+ conformance to the protocol specification unless it implements the
+ set of triples. Within each triple, mechanism is a GSS-API security
+ mechanism, QOP is a valid quality-of-protection within the mechanism,
+ and service is either rpc_gss_svc_integrity or rpc_gss_svc_privacy.
+
+ For example, a network filing protocol built on RPC that depends on
+ RPCSEC_GSS for security, might require that Kerberos V5 with the
+ default QOP using the rpc_gss_svc_integrity service be supported by
+ implementations conforming to the network filing protocol
+ specification.
+
+
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 17]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+7. Security Considerations
+
+7.1. Privacy of Call Header
+
+ The reader will note that for the privacy option, only the call
+ arguments and results are encrypted. Information about the
+ application in the form of RPC program number, program version
+ number, and program procedure number is transmitted in the clear.
+ Encrypting these fields in the RPC call header would have changed the
+ size and format of the call header. This would have required revising
+ the RPC protocol which was beyond the scope of this proposal. Storing
+ the encrypted numbers in the credential would have obviated a
+ protocol change, but would have introduced more overloading of fields
+ and would have made implementations of RPC more complex. Even if the
+ fields were encrypted somehow, in most cases an attacker can
+ determine the program number and version number by examining the
+ destination address of the request and querying the rpcbind service
+ on the destination host [Srinivasan-bind]. In any case, even by not
+ encrypting the three numbers, RPCSEC_GSS still improves the state of
+ security over what existing RPC services have had available
+ previously. Implementors of new RPC services that are concerned about
+ this risk may opt to design in a "sub-procedure" field that is
+ included in the service specific call arguments.
+
+7.2. Sequence Number Attacks
+
+7.2.1. Sequence Numbers Above the Window
+
+ An attacker cannot coax the server into raising the sequence number
+ beyond the range the legitimate client is aware of (and thus engineer
+ a denial of server attack) without constructing an RPC request that
+ will pass the header checksum. If the cost of verifying the header
+ checksum is sufficiently large (depending on the speed of the
+ processor doing the checksum and the cost of checksum algorithm), it
+ is possible to envision a denial of service attack (vandalism, in the
+ form of wasting processing resources) whereby the attacker sends
+ requests that are above the window. The simplest method might be for
+ the attacker to monitor the network traffic and then choose a
+ sequence number that is far above the current sequence number. Then
+ the attacker can send bogus requests using the above window sequence
+ number.
+
+7.2.2. Sequence Numbers Within or Below the Window
+
+ If the attacker sends requests that are within or below the window,
+ then even if the header checksum is successfully verified, the server
+ will silently discard the requests because the server assumes it has
+ already processed the request. In this case, a server can optimize by
+
+
+
+Eisler, et. al. Standards Track [Page 18]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ skipping the header checksum verification if the sequence number is
+ below the window, or if it is within the window, not attempt the
+ checksum verification if the sequence number has already been seen.
+
+7.3. Message Stealing Attacks
+
+ This proposal does not address attacks where an attacker can block or
+ steal messages without being detected by the server. To implement
+ such protection would be tantamount to assuming a state in the RPC
+ service. RPCSEC_GSS does not worsen this situation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 19]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+Appendix A. GSS-API Major Status Codes
+
+ The GSS-API definition [Linn] does not include numerical values for
+ the various GSS-API major status codes. It is expected that this will
+ be addressed in future RFC. Until then, this appendix defines the
+ values for each GSS-API major status code listed in the GSS-API
+ definition. If in the future, the GSS-API definition defines values
+ for the codes that are different than what follows, then implementors
+ of RPCSEC_GSS will be obliged to map them into the values defined
+ below. If in the future, the GSS-API definition defines additional
+ status codes not defined below, then the RPCSEC_GSS definition will
+ subsume those additional values.
+
+ Here are the definitions of each GSS_S_* major status that the
+ implementor of RPCSEC_GSS can expect in the gss_major major field of
+ rpc_gss_init_res. These definitions are not in RPC description
+ language form. The numbers are in base 16 (hexadecimal):
+
+ GSS_S_COMPLETE 0x00000000
+ GSS_S_CONTINUE_NEEDED 0x00000001
+ GSS_S_DUPLICATE_TOKEN 0x00000002
+ GSS_S_OLD_TOKEN 0x00000004
+ GSS_S_UNSEQ_TOKEN 0x00000008
+ GSS_S_GAP_TOKEN 0x00000010
+ GSS_S_BAD_MECH 0x00010000
+ GSS_S_BAD_NAME 0x00020000
+ GSS_S_BAD_NAMETYPE 0x00030000
+ GSS_S_BAD_BINDINGS 0x00040000
+ GSS_S_BAD_STATUS 0x00050000
+ GSS_S_BAD_MIC 0x00060000
+ GSS_S_BAD_SIG 0x00060000
+ GSS_S_NO_CRED 0x00070000
+ GSS_S_NO_CONTEXT 0x00080000
+ GSS_S_DEFECTIVE_TOKEN 0x00090000
+ GSS_S_DEFECTIVE_CREDENTIAL 0x000a0000
+ GSS_S_CREDENTIALS_EXPIRED 0x000b0000
+ GSS_S_CONTEXT_EXPIRED 0x000c0000
+ GSS_S_FAILURE 0x000d0000
+ GSS_S_BAD_QOP 0x000e0000
+ GSS_S_UNAUTHORIZED 0x000f0000
+ GSS_S_UNAVAILABLE 0x00100000
+ GSS_S_DUPLICATE_ELEMENT 0x00110000
+ GSS_S_NAME_NOT_MN 0x00120000
+ GSS_S_CALL_INACCESSIBLE_READ 0x01000000
+ GSS_S_CALL_INACCESSIBLE_WRITE 0x02000000
+ GSS_S_CALL_BAD_STRUCTURE 0x03000000
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 20]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+ Note that the GSS-API major status is split into three fields as
+ follows:
+
+ Most Significant Bit Least Significant Bit
+ |------------------------------------------------------------|
+ | Calling Error | Routine Error | Supplementary Info |
+ |------------------------------------------------------------|
+ Bit 31 24 23 16 15 0
+
+ Up to one status in the Calling Error field can be logically ORed
+ with up to one status in the Routine Error field which in turn can be
+ logically ORed with zero or more statuses in the Supplementary Info
+ field. If the resulting major status has a non-zero Calling Error
+ and/or a non-zero Routine Error, then the applicable GSS-API
+ operation has failed. For purposes of RPCSEC_GSS, this means that
+ the GSS_Accept_sec_context() call executed by the server has failed.
+
+ If the major status is equal GSS_S_COMPLETE, then this indicates the
+ absence of any Errors or Supplementary Info.
+
+ The meanings of most of the GSS_S_* status are defined in the GSS-API
+ definition, which the exceptions of:
+
+ GSS_S_BAD_MIC This code has the same meaning as GSS_S_BAD_SIG.
+
+ GSS_S_CALL_INACCESSIBLE_READ
+ A required input parameter could not be read.
+
+ GSS_S_CALL_INACCESSIBLE_WRITE
+ A required input parameter could not be written.
+
+ GSS_S_CALL_BAD_STRUCTURE
+ A parameter was malformed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 21]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+Acknowledgements
+
+ Much of the protocol was based on the AUTH_GSSAPI security flavor
+ developed by Open Vision Technologies [Jaspan]. In particular, we
+ acknowledge Barry Jaspan, Marc Horowitz, John Linn, and Ellen
+ McDermott.
+
+ Raj Srinivasan designed RPCSEC_GSS [Eisler] with input from Mike
+ Eisler. Raj, Roland Schemers, Lin Ling, and Alex Chiu contributed to
+ Sun Microsystems' implementation of RPCSEC_GSS.
+
+ Brent Callaghan, Marc Horowitz, Barry Jaspan, John Linn, Hilarie
+ Orman, Martin Rex, Ted Ts'o, and John Wroclawski analyzed the
+ specification and gave valuable feedback.
+
+ Steve Nahm and Kathy Slattery reviewed various drafts of this
+ specification.
+
+ Much of content of Appendix A was excerpted from John Wray's Work in
+ Progress on GSS-API Version 2 C-bindings.
+
+References
+
+ [Eisler] Eisler, M., Schemers, R., and Srinivasan, R.
+ (1996). "Security Mechanism Independence in ONC
+ RPC," Proceedings of the Sixth Annual USENIX
+ Security Symposium, pp. 51-65.
+
+ [Jaspan] Jaspan, B. (1995). "GSS-API Security for ONC
+ RPC," `95 Proceedings of The Internet Society
+ Symposium on Network and Distributed System
+ Security, pp. 144- 151.
+
+ [Linn] Linn, J., "Generic Security Service Application
+ Program Interface, Version 2", RFC 2078, January
+ 1997.
+
+ [Srinivasan-bind] Srinivasan, R., "Binding Protocols for
+ ONC RPC Version 2", RFC 1833, August 1995.
+
+ [Srinivasan-rpc] Srinivasan, R., "RPC: Remote Procedure Call
+ Protocol Specification Version 2", RFC 1831,
+ August 1995.
+
+ [Srinivasan-xdr] Srinivasan, R., "XDR: External Data
+ Representation Standard", RFC 1832, August 1995.
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 22]
+
+RFC 2203 RPCSEC_GSS Protocol Specification September 1997
+
+
+Authors' Addresses
+
+ Michael Eisler
+ Sun Microsystems, Inc.
+ M/S UCOS03
+ 2550 Garcia Avenue
+ Mountain View, CA 94043
+
+ Phone: +1 (719) 599-9026
+ EMail: mre@eng.sun.com
+
+
+ Alex Chiu
+ Sun Microsystems, Inc.
+ M/S UMPK17-203
+ 2550 Garcia Avenue
+ Mountain View, CA 94043
+
+ Phone: +1 (415) 786-6465
+ EMail: hacker@eng.sun.com
+
+
+ Lin Ling
+ Sun Microsystems, Inc.
+ M/S UMPK17-201
+ 2550 Garcia Avenue
+ Mountain View, CA 94043
+
+ Phone: +1 (415) 786-5084
+ EMail: lling@eng.sun.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eisler, et. al. Standards Track [Page 23]
+
diff --git a/crypto/heimdal/doc/standardisation/rfc2228.txt b/crypto/heimdal/doc/standardisation/rfc2228.txt
new file mode 100644
index 000000000000..1fbfcbfa09fc
--- /dev/null
+++ b/crypto/heimdal/doc/standardisation/rfc2228.txt
@@ -0,0 +1,1515 @@
+
+
+
+
+
+
+Network Working Group M. Horowitz
+Request for Comments: 2228 Cygnus Solutions
+Updates: 959 S. Lunt
+Category: Standards Track Bellcore
+ October 1997
+
+ FTP Security Extensions
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1997). All Rights Reserved.
+
+Abstract
+
+ This document defines extensions to the FTP specification STD 9, RFC
+ 959, "FILE TRANSFER PROTOCOL (FTP)" (October 1985). These extensions
+ provide strong authentication, integrity, and confidentiality on both
+ the control and data channels with the introduction of new optional
+ commands, replies, and file transfer encodings.
+
+ The following new optional commands are introduced in this
+ specification:
+
+ AUTH (Authentication/Security Mechanism),
+ ADAT (Authentication/Security Data),
+ PROT (Data Channel Protection Level),
+ PBSZ (Protection Buffer Size),
+ CCC (Clear Command Channel),
+ MIC (Integrity Protected Command),
+ CONF (Confidentiality Protected Command), and
+ ENC (Privacy Protected Command).
+
+ A new class of reply types (6yz) is also introduced for protected
+ replies.
+
+ None of the above commands are required to be implemented, but
+ interdependencies exist. These dependencies are documented with the
+ commands.
+
+ Note that this specification is compatible with STD 9, RFC 959.
+
+
+
+Horowitz & Lunt Standards Track [Page 1]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+1. Introduction
+
+ The File Transfer Protocol (FTP) currently defined in STD 9, RFC 959
+ and in place on the Internet uses usernames and passwords passed in
+ cleartext to authenticate clients to servers (via the USER and PASS
+ commands). Except for services such as "anonymous" FTP archives,
+ this represents a security risk whereby passwords can be stolen
+ through monitoring of local and wide-area networks. This either aids
+ potential attackers through password exposure and/or limits
+ accessibility of files by FTP servers who cannot or will not accept
+ the inherent security risks.
+
+ Aside from the problem of authenticating users in a secure manner,
+ there is also the problem of authenticating servers, protecting
+ sensitive data and/or verifying its integrity. An attacker may be
+ able to access valuable or sensitive data merely by monitoring a
+ network, or through active means may be able to delete or modify the
+ data being transferred so as to corrupt its integrity. An active
+ attacker may also initiate spurious file transfers to and from a site
+ of the attacker's choice, and may invoke other commands on the
+ server. FTP does not currently have any provision for the encryption
+ or verification of the authenticity of commands, replies, or
+ transferred data. Note that these security services have value even
+ to anonymous file access.
+
+ Current practice for sending files securely is generally either:
+
+ 1. via FTP of files pre-encrypted under keys which are manually
+ distributed,
+
+ 2. via electronic mail containing an encoding of a file encrypted
+ under keys which are manually distributed,
+
+ 3. via a PEM message, or
+
+ 4. via the rcp command enhanced to use Kerberos.
+
+ None of these means could be considered even a de facto standard, and
+ none are truly interactive. A need exists to securely transfer files
+ using FTP in a secure manner which is supported within the FTP
+ protocol in a consistent manner and which takes advantage of existing
+ security infrastructure and technology. Extensions are necessary to
+ the FTP specification if these security services are to be introduced
+ into the protocol in an interoperable way.
+
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 2]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ Although the FTP control connection follows the Telnet protocol, and
+ Telnet has defined an authentication and encryption option [TELNET-
+ SEC], [RFC-1123] explicitly forbids the use of Telnet option
+ negotiation over the control connection (other than Synch and IP).
+
+ Also, the Telnet authentication and encryption option does not
+ provide for integrity protection only (without confidentiality), and
+ does not address the protection of the data channel.
+
+2. FTP Security Overview
+
+ At the highest level, the FTP security extensions seek to provide an
+ abstract mechanism for authenticating and/or authorizing connections,
+ and integrity and/or confidentiality protecting commands, replies,
+ and data transfers.
+
+ In the context of FTP security, authentication is the establishment
+ of a client's identity and/or a server's identity in a secure way,
+ usually using cryptographic techniques. The basic FTP protocol does
+ not have a concept of authentication.
+
+ Authorization is the process of validating a user for login. The
+ basic authorization process involves the USER, PASS, and ACCT
+ commands. With the FTP security extensions, authentication
+ established using a security mechanism may also be used to make the
+ authorization decision.
+
+ Without the security extensions, authentication of the client, as
+ this term is usually understood, never happens. FTP authorization is
+ accomplished with a password, passed on the network in the clear as
+ the argument to the PASS command. The possessor of this password is
+ assumed to be authorized to transfer files as the user named in the
+ USER command, but the identity of the client is never securely
+ established.
+
+ An FTP security interaction begins with a client telling the server
+ what security mechanism it wants to use with the AUTH command. The
+ server will either accept this mechanism, reject this mechanism, or,
+ in the case of a server which does not implement the security
+ extensions, reject the command completely. The client may try
+ multiple security mechanisms until it requests one which the server
+ accepts. This allows a rudimentary form of negotiation to take
+ place. (If more complex negotiation is desired, this may be
+ implemented as a security mechanism.) The server's reply will
+ indicate if the client must respond with additional data for the
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 3]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ security mechanism to interpret. If none is needed, this will
+ usually mean that the mechanism is one where the password (specified
+ by the PASS command) is to be interpreted differently, such as with a
+ token or one-time password system.
+
+ If the server requires additional security information, then the
+ client and server will enter into a security data exchange. The
+ client will send an ADAT command containing the first block of
+ security data. The server's reply will indicate if the data exchange
+ is complete, if there was an error, or if more data is needed. The
+ server's reply can optionally contain security data for the client to
+ interpret. If more data is needed, the client will send another ADAT
+ command containing the next block of data, and await the server's
+ reply. This exchange can continue as many times as necessary. Once
+ this exchange completes, the client and server have established a
+ security association. This security association may include
+ authentication (client, server, or mutual) and keying information for
+ integrity and/or confidentiality, depending on the mechanism in use.
+
+ The term "security data" here is carefully chosen. The purpose of
+ the security data exchange is to establish a security association,
+ which might not actually include any authentication at all, between
+ the client and the server as described above. For instance, a
+ Diffie-Hellman exchange establishes a secret key, but no
+ authentication takes place. If an FTP server has an RSA key pair but
+ the client does not, then the client can authenticate the server, but
+ the server cannot authenticate the client.
+
+ Once a security association is established, authentication which is a
+ part of this association may be used instead of or in addition to the
+ standard username/password exchange for authorizing a user to connect
+ to the server. A username specified by the USER command is always
+ required to specify the identity to be used on the server.
+
+ In order to prevent an attacker from inserting or deleting commands
+ on the control stream, if the security association supports
+ integrity, then the server and client must use integrity protection
+ on the control stream, unless it first transmits a CCC command to
+ turn off this requirement. Integrity protection is performed with
+ the MIC and ENC commands, and the 63z reply codes. The CCC command
+ and its reply must be transmitted with integrity protection.
+ Commands and replies may be transmitted without integrity (that is,
+ in the clear or with confidentiality only) only if no security
+ association is established, the negotiated security association does
+ not support integrity, or the CCC command has succeeded.
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 4]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ Once the client and server have negotiated with the PBSZ command an
+ acceptable buffer size for encapsulating protected data over the data
+ channel, the security mechanism may also be used to protect data
+ channel transfers.
+
+ Policy is not specified by this document. In particular, client and
+ server implementations may choose to implement restrictions on what
+ operations can be performed depending on the security association
+ which exists. For example, a server may require that a client
+ authorize via a security mechanism rather than using a password,
+ require that the client provide a one-time password from a token,
+ require at least integrity protection on the command channel, or
+ require that certain files only be transmitted encrypted. An
+ anonymous ftp client might refuse to do file transfers without
+ integrity protection in order to insure the validity of files
+ downloaded.
+
+ No particular set of functionality is required, except as
+ dependencies described in the next section. This means that none of
+ authentication, integrity, or confidentiality are required of an
+ implementation, although a mechanism which does none of these is not
+ of much use. For example, it is acceptable for a mechanism to
+ implement only integrity protection, one-way authentication and/or
+ encryption, encryption without any authentication or integrity
+ protection, or any other subset of functionality if policy or
+ technical considerations make this desirable. Of course, one peer
+ might require as a matter of policy stronger protection than the
+ other is able to provide, preventing perfect interoperability.
+
+3. New FTP Commands
+
+ The following commands are optional, but dependent on each other.
+ They are extensions to the FTP Access Control Commands.
+
+ The reply codes documented here are generally described as
+ recommended, rather than required. The intent is that reply codes
+ describing the full range of success and failure modes exist, but
+ that servers be allowed to limit information presented to the client.
+ For example, a server might implement a particular security
+ mechanism, but have a policy restriction against using it. The
+ server should respond with a 534 reply code in this case, but may
+ respond with a 504 reply code if it does not wish to divulge that the
+ disallowed mechanism is supported. If the server does choose to use
+ a different reply code than the recommended one, it should try to use
+ a reply code which only differs in the last digit. In all cases, the
+ server must use a reply code which is documented as returnable from
+ the command received, and this reply code must begin with the same
+ digit as the recommended reply code for the situation.
+
+
+
+Horowitz & Lunt Standards Track [Page 5]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ AUTHENTICATION/SECURITY MECHANISM (AUTH)
+
+ The argument field is a Telnet string identifying a supported
+ mechanism. This string is case-insensitive. Values must be
+ registered with the IANA, except that values beginning with "X-"
+ are reserved for local use.
+
+ If the server does not recognize the AUTH command, it must respond
+ with reply code 500. This is intended to encompass the large
+ deployed base of non-security-aware ftp servers, which will
+ respond with reply code 500 to any unrecognized command. If the
+ server does recognize the AUTH command but does not implement the
+ security extensions, it should respond with reply code 502.
+
+ If the server does not understand the named security mechanism, it
+ should respond with reply code 504.
+
+ If the server is not willing to accept the named security
+ mechanism, it should respond with reply code 534.
+
+ If the server is not able to accept the named security mechanism,
+ such as if a required resource is unavailable, it should respond
+ with reply code 431.
+
+ If the server is willing to accept the named security mechanism,
+ but requires security data, it must respond with reply code 334.
+
+ If the server is willing to accept the named security mechanism,
+ and does not require any security data, it must respond with reply
+ code 234.
+
+ If the server is responding with a 334 reply code, it may include
+ security data as described in the next section.
+
+ Some servers will allow the AUTH command to be reissued in order
+ to establish new authentication. The AUTH command, if accepted,
+ removes any state associated with prior FTP Security commands.
+ The server must also require that the user reauthorize (that is,
+ reissue some or all of the USER, PASS, and ACCT commands) in this
+ case (see section 4 for an explanation of "authorize" in this
+ context).
+
+
+
+
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 6]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ AUTHENTICATION/SECURITY DATA (ADAT)
+
+ The argument field is a Telnet string representing base 64 encoded
+ security data (see Section 9, "Base 64 Encoding"). If a reply
+ code indicating success is returned, the server may also use a
+ string of the form "ADAT=base64data" as the text part of the reply
+ if it wishes to convey security data back to the client.
+
+ The data in both cases is specific to the security mechanism
+ specified by the previous AUTH command. The ADAT command, and the
+ associated replies, allow the client and server to conduct an
+ arbitrary security protocol. The security data exchange must
+ include enough information for both peers to be aware of which
+ optional features are available. For example, if the client does
+ not support data encryption, the server must be made aware of
+ this, so it will know not to send encrypted command channel
+ replies. It is strongly recommended that the security mechanism
+ provide sequencing on the command channel, to insure that commands
+ are not deleted, reordered, or replayed.
+
+ The ADAT command must be preceded by a successful AUTH command,
+ and cannot be issued once a security data exchange completes
+ (successfully or unsuccessfully), unless it is preceded by an AUTH
+ command to reset the security state.
+
+ If the server has not yet received an AUTH command, or if a prior
+ security data exchange completed, but the security state has not
+ been reset with an AUTH command, it should respond with reply code
+ 503.
+
+ If the server cannot base 64 decode the argument, it should
+ respond with reply code 501.
+
+ If the server rejects the security data (if a checksum fails, for
+ instance), it should respond with reply code 535.
+
+ If the server accepts the security data, and requires additional
+ data, it should respond with reply code 335.
+
+ If the server accepts the security data, but does not require any
+ additional data (i.e., the security data exchange has completed
+ successfully), it must respond with reply code 235.
+
+ If the server is responding with a 235 or 335 reply code, then it
+ may include security data in the text part of the reply as
+ specified above.
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 7]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ If the ADAT command returns an error, the security data exchange
+ will fail, and the client must reset its internal security state.
+ If the client becomes unsynchronized with the server (for example,
+ the server sends a 234 reply code to an AUTH command, but the
+ client has more data to transmit), then the client must reset the
+ server's security state.
+
+ PROTECTION BUFFER SIZE (PBSZ)
+
+ The argument is a decimal integer representing the maximum size,
+ in bytes, of the encoded data blocks to be sent or received during
+ file transfer. This number shall be no greater than can be
+ represented in a 32-bit unsigned integer.
+
+ This command allows the FTP client and server to negotiate a
+ maximum protected buffer size for the connection. There is no
+ default size; the client must issue a PBSZ command before it can
+ issue the first PROT command.
+
+ The PBSZ command must be preceded by a successful security data
+ exchange.
+
+ If the server cannot parse the argument, or if it will not fit in
+ 32 bits, it should respond with a 501 reply code.
+
+ If the server has not completed a security data exchange with the
+ client, it should respond with a 503 reply code.
+
+ Otherwise, the server must reply with a 200 reply code. If the
+ size provided by the client is too large for the server, it must
+ use a string of the form "PBSZ=number" in the text part of the
+ reply to indicate a smaller buffer size. The client and the
+ server must use the smaller of the two buffer sizes if both buffer
+ sizes are specified.
+
+ DATA CHANNEL PROTECTION LEVEL (PROT)
+
+ The argument is a single Telnet character code specifying the data
+ channel protection level.
+
+ This command indicates to the server what type of data channel
+ protection the client and server will be using. The following
+ codes are assigned:
+
+ C - Clear
+ S - Safe
+ E - Confidential
+ P - Private
+
+
+
+Horowitz & Lunt Standards Track [Page 8]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ The default protection level if no other level is specified is
+ Clear. The Clear protection level indicates that the data channel
+ will carry the raw data of the file transfer, with no security
+ applied. The Safe protection level indicates that the data will
+ be integrity protected. The Confidential protection level
+ indicates that the data will be confidentiality protected. The
+ Private protection level indicates that the data will be integrity
+ and confidentiality protected.
+
+ It is reasonable for a security mechanism not to provide all data
+ channel protection levels. It is also reasonable for a mechanism
+ to provide more protection at a level than is required (for
+ instance, a mechanism might provide Confidential protection, but
+ include integrity-protection in that encoding, due to API or other
+ considerations).
+
+ The PROT command must be preceded by a successful protection
+ buffer size negotiation.
+
+ If the server does not understand the specified protection level,
+ it should respond with reply code 504.
+
+ If the current security mechanism does not support the specified
+ protection level, the server should respond with reply code 536.
+
+ If the server has not completed a protection buffer size
+ negotiation with the client, it should respond with a 503 reply
+ code.
+
+ The PROT command will be rejected and the server should reply 503
+ if no previous PBSZ command was issued.
+
+ If the server is not willing to accept the specified protection
+ level, it should respond with reply code 534.
+
+ If the server is not able to accept the specified protection
+ level, such as if a required resource is unavailable, it should
+ respond with reply code 431.
+
+ Otherwise, the server must reply with a 200 reply code to indicate
+ that the specified protection level is accepted.
+
+ CLEAR COMMAND CHANNEL (CCC)
+
+ This command does not take an argument.
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 9]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ It is desirable in some environments to use a security mechanism
+ to authenticate and/or authorize the client and server, but not to
+ perform any integrity checking on the subsequent commands. This
+ might be used in an environment where IP security is in place,
+ insuring that the hosts are authenticated and that TCP streams
+ cannot be tampered, but where user authentication is desired.
+
+ If unprotected commands are allowed on any connection, then an
+ attacker could insert a command on the control stream, and the
+ server would have no way to know that it was invalid. In order to
+ prevent such attacks, once a security data exchange completes
+ successfully, if the security mechanism supports integrity, then
+ integrity (via the MIC or ENC command, and 631 or 632 reply) must
+ be used, until the CCC command is issued to enable non-integrity
+ protected control channel messages. The CCC command itself must
+ be integrity protected.
+
+ Once the CCC command completes successfully, if a command is not
+ protected, then the reply to that command must also not be
+ protected. This is to support interoperability with clients which
+ do not support protection once the CCC command has been issued.
+
+ This command must be preceded by a successful security data
+ exchange.
+
+ If the command is not integrity-protected, the server must respond
+ with a 533 reply code.
+
+ If the server is not willing to turn off the integrity
+ requirement, it should respond with a 534 reply code.
+
+ Otherwise, the server must reply with a 200 reply code to indicate
+ that unprotected commands and replies may now be used on the
+ command channel.
+
+ INTEGRITY PROTECTED COMMAND (MIC) and
+ CONFIDENTIALITY PROTECTED COMMAND (CONF) and
+ PRIVACY PROTECTED COMMAND (ENC)
+
+ The argument field of MIC is a Telnet string consisting of a base
+ 64 encoded "safe" message produced by a security mechanism
+ specific message integrity procedure. The argument field of CONF
+ is a Telnet string consisting of a base 64 encoded "confidential"
+ message produced by a security mechanism specific confidentiality
+ procedure. The argument field of ENC is a Telnet string
+ consisting of a base 64 encoded "private" message produced by a
+ security mechanism specific message integrity and confidentiality
+ procedure.
+
+
+
+Horowitz & Lunt Standards Track [Page 10]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ The server will decode and/or verify the encoded message.
+
+ This command must be preceded by a successful security data
+ exchange.
+
+ A server may require that the first command after a successful
+ security data exchange be CCC, and not implement the protection
+ commands at all. In this case, the server should respond with a
+ 502 reply code.
+
+ If the server cannot base 64 decode the argument, it should
+ respond with a 501 reply code.
+
+ If the server has not completed a security data exchange with the
+ client, it should respond with a 503 reply code.
+
+ If the server has completed a security data exchange with the
+ client using a mechanism which supports integrity, and requires a
+ CCC command due to policy or implementation limitations, it should
+ respond with a 503 reply code.
+
+ If the server rejects the command because it is not supported by
+ the current security mechanism, the server should respond with
+ reply code 537.
+
+ If the server rejects the command (if a checksum fails, for
+ instance), it should respond with reply code 535.
+
+ If the server is not willing to accept the command (if privacy is
+ required by policy, for instance, or if a CONF command is received
+ before a CCC command), it should respond with reply code 533.
+
+ Otherwise, the command will be interpreted as an FTP command. An
+ end-of-line code need not be included, but if one is included, it
+ must be a Telnet end-of-line code, not a local end-of-line code.
+
+ The server may require that, under some or all circumstances, all
+ commands be protected. In this case, it should make a 533 reply
+ to commands other than MIC, CONF, and ENC.
+
+4. Login Authorization
+
+ The security data exchange may, among other things, establish the
+ identity of the client in a secure way to the server. This identity
+ may be used as one input to the login authorization process.
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 11]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ In response to the FTP login commands (AUTH, PASS, ACCT), the server
+ may choose to change the sequence of commands and replies specified
+ by RFC 959 as follows. There are also some new replies available.
+
+ If the server is willing to allow the user named by the USER command
+ to log in based on the identity established by the security data
+ exchange, it should respond with reply code 232.
+
+ If the security mechanism requires a challenge/response password, it
+ should respond to the USER command with reply code 336. The text
+ part of the reply should contain the challenge. The client must
+ display the challenge to the user before prompting for the password
+ in this case. This is particularly relevant to more sophisticated
+ clients or graphical user interfaces which provide dialog boxes or
+ other modal input. These clients should be careful not to prompt for
+ the password before the username has been sent to the server, in case
+ the user needs the challenge in the 336 reply to construct a valid
+ password.
+
+5. New FTP Replies
+
+ The new reply codes are divided into two classes. The first class is
+ new replies made necessary by the new FTP Security commands. The
+ second class is a new reply type to indicate protected replies.
+
+ 5.1. New individual reply codes
+
+ 232 User logged in, authorized by security data exchange.
+ 234 Security data exchange complete.
+ 235 [ADAT=base64data]
+ ; This reply indicates that the security data exchange
+ ; completed successfully. The square brackets are not
+ ; to be included in the reply, but indicate that
+ ; security data in the reply is optional.
+
+ 334 [ADAT=base64data]
+ ; This reply indicates that the requested security mechanism
+ ; is ok, and includes security data to be used by the client
+ ; to construct the next command. The square brackets are not
+ ; to be included in the reply, but indicate that
+ ; security data in the reply is optional.
+ 335 [ADAT=base64data]
+ ; This reply indicates that the security data is
+ ; acceptable, and more is required to complete the
+ ; security data exchange. The square brackets
+ ; are not to be included in the reply, but indicate
+ ; that security data in the reply is optional.
+
+
+
+
+Horowitz & Lunt Standards Track [Page 12]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ 336 Username okay, need password. Challenge is "...."
+ ; The exact representation of the challenge should be chosen
+ ; by the mechanism to be sensible to the human user of the
+ ; system.
+
+ 431 Need some unavailable resource to process security.
+
+ 533 Command protection level denied for policy reasons.
+ 534 Request denied for policy reasons.
+ 535 Failed security check (hash, sequence, etc).
+ 536 Requested PROT level not supported by mechanism.
+ 537 Command protection level not supported by security mechanism.
+
+ 5.2. Protected replies.
+
+ One new reply type is introduced:
+
+ 6yz Protected reply
+
+ There are three reply codes of this type. The first, reply
+ code 631 indicates an integrity protected reply. The
+ second, reply code 632, indicates a confidentiality and
+ integrity protected reply. the third, reply code 633,
+ indicates a confidentiality protected reply.
+
+ The text part of a 631 reply is a Telnet string consisting
+ of a base 64 encoded "safe" message produced by a security
+ mechanism specific message integrity procedure. The text
+ part of a 632 reply is a Telnet string consisting of a base
+ 64 encoded "private" message produced by a security
+ mechanism specific message confidentiality and integrity
+ procedure. The text part of a 633 reply is a Telnet string
+ consisting of a base 64 encoded "confidential" message
+ produced by a security mechanism specific message
+ confidentiality procedure.
+
+ The client will decode and verify the encoded reply. How
+ failures decoding or verifying replies are handled is
+ implementation-specific. An end-of-line code need not be
+ included, but if one is included, it must be a Telnet end-
+ of-line code, not a local end-of-line code.
+
+ A protected reply may only be sent if a security data
+ exchange has succeeded.
+
+ The 63z reply may be a multiline reply. In this case, the
+ plaintext reply must be broken up into a number of
+ fragments. Each fragment must be protected, then base 64
+
+
+
+Horowitz & Lunt Standards Track [Page 13]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ encoded in order into a separate line of the multiline
+ reply. There need not be any correspondence between the
+ line breaks in the plaintext reply and the encoded reply.
+ Telnet end-of-line codes must appear in the plaintext of the
+ encoded reply, except for the final end-of-line code, which
+ is optional.
+
+ The multiline reply must be formatted more strictly than the
+ continuation specification in RFC 959. In particular, each
+ line before the last must be formed by the reply code,
+ followed immediately by a hyphen, followed by a base 64
+ encoded fragment of the reply.
+
+ For example, if the plaintext reply is
+
+ 123-First line
+ Second line
+ 234 A line beginning with numbers
+ 123 The last line
+
+ then the resulting protected reply could be any of the
+ following (the first example has a line break only to fit
+ within the margins):
+
+ 631 base64(protect("123-First line\r\nSecond line\r\n 234 A line
+ 631-base64(protect("123-First line\r\n"))
+ 631-base64(protect("Second line\r\n"))
+ 631-base64(protect(" 234 A line beginning with numbers\r\n"))
+ 631 base64(protect("123 The last line"))
+
+ 631-base64(protect("123-First line\r\nSecond line\r\n 234 A line b"))
+ 631 base64(protect("eginning with numbers\r\n123 The last line\r\n"))
+
+6. Data Channel Encapsulation
+
+ When data transfers are protected between the client and server (in
+ either direction), certain transformations and encapsulations must be
+ performed so that the recipient can properly decode the transmitted
+ file.
+
+ The sender must apply all protection services after transformations
+ associated with the representation type, file structure, and transfer
+ mode have been performed. The data sent over the data channel is,
+ for the purposes of protection, to be treated as a byte stream.
+
+ When performing a data transfer in an authenticated manner, the
+ authentication checks are performed on individual blocks of the file,
+ rather than on the file as a whole. Consequently, it is possible for
+
+
+
+Horowitz & Lunt Standards Track [Page 14]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ insertion attacks to insert blocks into the data stream (i.e.,
+ replays) that authenticate correctly, but result in a corrupted file
+ being undetected by the receiver. To guard against such attacks, the
+ specific security mechanism employed should include mechanisms to
+ protect against such attacks. Many GSS-API mechanisms usable with
+ the specification in Appendix I, and the Kerberos mechanism in
+ Appendix II do so.
+
+ The sender must take the input byte stream, and break it up into
+ blocks such that each block, when encoded using a security mechanism
+ specific procedure, will be no larger than the buffer size negotiated
+ by the client with the PBSZ command. Each block must be encoded,
+ then transmitted with the length of the encoded block prepended as a
+ four byte unsigned integer, most significant byte first.
+
+ When the end of the file is reached, the sender must encode a block
+ of zero bytes, and send this final block to the recipient before
+ closing the data connection.
+
+ The recipient will read the four byte length, read a block of data
+ that many bytes long, then decode and verify this block with a
+ security mechanism specific procedure. This must be repeated until a
+ block encoding a buffer of zero bytes is received. This indicates
+ the end of the encoded byte stream.
+
+ Any transformations associated with the representation type, file
+ structure, and transfer mode are to be performed by the recipient on
+ the byte stream resulting from the above process.
+
+ When using block transfer mode, the sender's (cleartext) buffer size
+ is independent of the block size.
+
+ The server will reply 534 to a STOR, STOU, RETR, LIST, NLST, or APPE
+ command if the current protection level is not at the level dictated
+ by the server's security requirements for the particular file
+ transfer.
+
+ If any data protection services fail at any time during data transfer
+ at the server end (including an attempt to send a buffer size greater
+ than the negotiated maximum), the server will send a 535 reply to the
+ data transfer command (either STOR, STOU, RETR, LIST, NLST, or APPE).
+
+
+
+
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 15]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+7. Potential policy considerations
+
+ While there are no restrictions on client and server policy, there
+ are a few recommendations which an implementation should implement.
+
+ - Once a security data exchange takes place, a server should require
+ all commands be protected (with integrity and/or confidentiality),
+ and it should protect all replies. Replies should use the same
+ level of protection as the command which produced them. This
+ includes replies which indicate failure of the MIC, CONF, and ENC
+ commands. In particular, it is not meaningful to require that
+ AUTH and ADAT be protected; it is meaningful and useful to require
+ that PROT and PBSZ be protected. In particular, the use of CCC is
+ not recommended, but is defined in the interest of
+ interoperability between implementations which might desire such
+ functionality.
+
+ - A client should encrypt the PASS command whenever possible. It is
+ reasonable for the server to refuse to accept a non-encrypted PASS
+ command if the server knows encryption is available.
+
+ - Although no security commands are required to be implemented, it
+ is recommended that an implementation provide all commands which
+ can be implemented, given the mechanisms supported and the policy
+ considerations of the site (export controls, for instance).
+
+8. Declarative specifications
+
+ These sections are modelled after sections 5.3 and 5.4 of RFC 959,
+ which describe the same information, except for the standard FTP
+ commands and replies.
+
+ 8.1. FTP Security commands and arguments
+
+ AUTH <SP> <mechanism-name> <CRLF>
+ ADAT <SP> <base64data> <CRLF>
+ PROT <SP> <prot-code> <CRLF>
+ PBSZ <SP> <decimal-integer> <CRLF>
+ MIC <SP> <base64data> <CRLF>
+ CONF <SP> <base64data> <CRLF>
+ ENC <SP> <base64data> <CRLF>
+
+ <mechanism-name> ::= <string>
+ <base64data> ::= <string>
+ ; must be formatted as described in section 9
+ <prot-code> ::= C | S | E | P
+ <decimal-integer> ::= any decimal integer from 1 to (2^32)-1
+
+
+
+
+Horowitz & Lunt Standards Track [Page 16]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ 8.2. Command-Reply sequences
+
+ Security Association Setup
+ AUTH
+ 234
+ 334
+ 502, 504, 534, 431
+ 500, 501, 421
+ ADAT
+ 235
+ 335
+ 503, 501, 535
+ 500, 501, 421
+ Data protection negotiation commands
+ PBSZ
+ 200
+ 503
+ 500, 501, 421, 530
+ PROT
+ 200
+ 504, 536, 503, 534, 431
+ 500, 501, 421, 530
+ Command channel protection commands
+ MIC
+ 535, 533
+ 500, 501, 421
+ CONF
+ 535, 533
+ 500, 501, 421
+ ENC
+ 535, 533
+ 500, 501, 421
+ Security-Enhanced login commands (only new replies listed)
+ USER
+ 232
+ 336
+ Data channel commands (only new replies listed)
+ STOR
+ 534, 535
+ STOU
+ 534, 535
+ RETR
+ 534, 535
+
+
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 17]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ LIST
+ 534, 535
+ NLST
+ 534, 535
+ APPE
+ 534, 535
+
+ In addition to these reply codes, any security command can return
+ 500, 501, 502, 533, or 421. Any ftp command can return a reply
+ code encapsulated in a 631, 632, or 633 reply once a security data
+ exchange has completed successfully.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 18]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+9. State Diagrams
+
+ This section includes a state diagram which demonstrates the flow of
+ authentication and authorization in a security enhanced FTP
+ implementation. The rectangular blocks show states where the client
+ must issue a command, and the diamond blocks show states where the
+ server must issue a response.
+
+
+ ,------------------, USER
+ __\| Unauthenticated |_________\
+ | /| (new connection) | /|
+ | `------------------' |
+ | | |
+ | | AUTH |
+ | V |
+ | / \ |
+ | 4yz,5yz / \ 234 |
+ |<--------< >------------->. |
+ | \ / | |
+ | \_/ | |
+ | | | |
+ | | 334 | |
+ | V | |
+ | ,--------------------, | |
+ | | Need Security Data |<--. | |
+ | `--------------------' | | |
+ | | | | |
+ | | ADAT | | |
+ | V | | |
+ | / \ | | |
+ | 4yz,5yz / \ 335 | | |
+ `<--------< >-----------' | |
+ \ / | |
+ \_/ | |
+ | | |
+ | 235 | |
+ V | |
+ ,---------------. | |
+ ,--->| Authenticated |<--------' | After the client and server
+ | `---------------' | have completed authenti-
+ | | | cation, command must be
+ | | USER | integrity-protected if
+ | | | integrity is available. The
+ | |<-------------------' CCC command may be issued to
+ | V relax this restriction.
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 19]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ | / \
+ | 4yz,5yz / \ 2yz
+ |<--------< >------------->.
+ | \ / |
+ | \_/ |
+ | | |
+ | | 3yz |
+ | V |
+ | ,---------------. |
+ | | Need Password | |
+ | `---------------' |
+ | | |
+ | | PASS |
+ | V |
+ | / \ |
+ | 4yz,5yz / \ 2yz |
+ |<--------< >------------->|
+ | \ / |
+ | \_/ |
+ | | |
+ | | 3yz |
+ | V |
+ | ,--------------. |
+ | | Need Account | |
+ | `--------------' |
+ | | |
+ | | ACCT |
+ | V |
+ | / \ |
+ | 4yz,5yz / \ 2yz |
+ `<--------< >------------->|
+ \ / |
+ \_/ |
+ | |
+ | 3yz |
+ V |
+ ,-------------. |
+ | Authorized |/________|
+ | (Logged in) |\
+ `-------------'
+
+
+
+
+
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 20]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+10. Base 64 Encoding
+
+ Base 64 encoding is the same as the Printable Encoding described in
+ Section 4.3.2.4 of [RFC-1421], except that line breaks must not be
+ included. This encoding is defined as follows.
+
+ Proceeding from left to right, the bit string resulting from the
+ mechanism specific protection routine is encoded into characters
+ which are universally representable at all sites, though not
+ necessarily with the same bit patterns (e.g., although the character
+ "E" is represented in an ASCII-based system as hexadecimal 45 and as
+ hexadecimal C5 in an EBCDIC-based system, the local significance of
+ the two representations is equivalent).
+
+ A 64-character subset of International Alphabet IA5 is used, enabling
+ 6 bits to be represented per printable character. (The proposed
+ subset of characters is represented identically in IA5 and ASCII.)
+ The character "=" signifies a special processing function used for
+ padding within the printable encoding procedure.
+
+ The encoding process represents 24-bit groups of input bits as output
+ strings of 4 encoded characters. Proceeding from left to right
+ across a 24-bit input group output from the security mechanism
+ specific message protection procedure, each 6-bit group is used as an
+ index into an array of 64 printable characters, namely "[A-Z][a-
+ z][0-9]+/". The character referenced by the index is placed in the
+ output string. These characters are selected so as to be universally
+ representable, and the set excludes characters with particular
+ significance to Telnet (e.g., "<CR>", "<LF>", IAC).
+
+ Special processing is performed if fewer than 24 bits are available
+ in an input group at the end of a message. A full encoding quantum
+ is always completed at the end of a message. When fewer than 24
+ input bits are available in an input group, zero bits are added (on
+ the right) to form an integral number of 6-bit groups. Output
+ character positions which are not required to represent actual input
+ data are set to the character "=". Since all canonically encoded
+ output is an integral number of octets, only the following cases can
+ arise: (1) the final quantum of encoding input is an integral
+ multiple of 24 bits; here, the final unit of encoded output will be
+ an integral multiple of 4 characters with no "=" padding, (2) the
+ final quantum of encoding input is exactly 8 bits; here, the final
+ unit of encoded output will be two characters followed by two "="
+ padding characters, or (3) the final quantum of encoding input is
+ exactly 16 bits; here, the final unit of encoded output will be three
+ characters followed by one "=" padding character.
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 21]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ Implementors must keep in mind that the base 64 encodings in ADAT,
+ MIC, CONF, and ENC commands, and in 63z replies may be arbitrarily
+ long. Thus, the entire line must be read before it can be processed.
+ Several successive reads on the control channel may be necessary. It
+ is not appropriate to for a server to reject a command containing a
+ base 64 encoding simply because it is too long (assuming that the
+ decoding is otherwise well formed in the context in which it was
+ sent).
+
+ Case must not be ignored when reading commands and replies containing
+ base 64 encodings.
+
+11. Security Considerations
+
+ This entire document deals with security considerations related to
+ the File Transfer Protocol.
+
+ Third party file transfers cannot be secured using these extensions,
+ since a security context cannot be established between two servers
+ using these facilities (no control connection exists between servers
+ over which to pass ADAT tokens). Further work in this area is
+ deferred.
+
+12. Acknowledgements
+
+ I would like to thank the members of the CAT WG, as well as all
+ participants in discussions on the "cat-ietf@mit.edu" mailing list,
+ for their contributions to this document. I would especially like to
+ thank Sam Sjogren, John Linn, Ted Ts'o, Jordan Brown, Michael Kogut,
+ Derrick Brashear, John Gardiner Myers, Denis Pinkas, and Karri Balk
+ for their contributions to this work. Of course, without Steve Lunt,
+ the author of the first six revisions of this document, it would not
+ exist at all.
+
+13. References
+
+ [TELNET-SEC] Borman, D., "Telnet Authentication and Encryption
+ Option", Work in Progress.
+
+ [RFC-1123] Braden, R., "Requirements for Internet Hosts --
+ Application and Support", STD 3, RFC 1123, October 1989.
+
+ [RFC-1421] Linn, J., "Privacy Enhancement for Internet Electronic
+ Mail: Part I: Message Encryption and Authentication Procedures",
+ RFC 1421, February 1993.
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 22]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+14. Author's Address
+
+ Marc Horowitz
+ Cygnus Solutions
+ 955 Massachusetts Avenue
+ Cambridge, MA 02139
+
+ Phone: +1 617 354 7688
+ EMail: marc@cygnus.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 23]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+Appendix I: Specification under the GSSAPI
+
+ In order to maximise the utility of new security mechanisms, it is
+ desirable that new mechanisms be implemented as GSSAPI mechanisms
+ rather than as FTP security mechanisms. This will enable existing
+ ftp implementations to support the new mechanisms more easily, since
+ little or no code will need to be changed. In addition, the
+ mechanism will be usable by other protocols, such as IMAP, which are
+ built on top of the GSSAPI, with no additional specification or
+ implementation work needed by the mechanism designers.
+
+ The security mechanism name (for the AUTH command) associated with
+ all mechanisms employing the GSSAPI is GSSAPI. If the server
+ supports a security mechanism employing the GSSAPI, it must respond
+ with a 334 reply code indicating that an ADAT command is expected
+ next.
+
+ The client must begin the authentication exchange by calling
+ GSS_Init_Sec_Context, passing in 0 for input_context_handle
+ (initially), and a targ_name equal to output_name from
+ GSS_Import_Name called with input_name_type of Host-Based Service and
+ input_name_string of "ftp@hostname" where "hostname" is the fully
+ qualified host name of the server with all letters in lower case.
+ (Failing this, the client may try again using input_name_string of
+ "host@hostname".) The output_token must then be base 64 encoded and
+ sent to the server as the argument to an ADAT command. If
+ GSS_Init_Sec_Context returns GSS_S_CONTINUE_NEEDED, then the client
+ must expect a token to be returned in the reply to the ADAT command.
+ This token must subsequently be passed to another call to
+ GSS_Init_Sec_Context. In this case, if GSS_Init_Sec_Context returns
+ no output_token, then the reply code from the server for the previous
+ ADAT command must have been 235. If GSS_Init_Sec_Context returns
+ GSS_S_COMPLETE, then no further tokens are expected from the server,
+ and the client must consider the server authenticated.
+
+ The server must base 64 decode the argument to the ADAT command and
+ pass the resultant token to GSS_Accept_Sec_Context as input_token,
+ setting acceptor_cred_handle to NULL (for "use default credentials"),
+ and 0 for input_context_handle (initially). If an output_token is
+ returned, it must be base 64 encoded and returned to the client by
+ including "ADAT=base64string" in the text of the reply. If
+ GSS_Accept_Sec_Context returns GSS_S_COMPLETE, the reply code must be
+ 235, and the server must consider the client authenticated. If
+ GSS_Accept_Sec_Context returns GSS_S_CONTINUE_NEEDED, the reply code
+ must be 335. Otherwise, the reply code should be 535, and the text
+ of the reply should contain a descriptive error message.
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 24]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ The chan_bindings input to GSS_Init_Sec_Context and
+ GSS_Accept_Sec_Context should use the client internet address and
+ server internet address as the initiator and acceptor addresses,
+ respectively. The address type for both should be GSS_C_AF_INET. No
+ application data should be specified.
+
+ Since GSSAPI supports anonymous peers to security contexts, it is
+ possible that the client's authentication of the server does not
+ actually establish an identity.
+
+ The procedure associated with MIC commands, 631 replies, and Safe
+ file transfers is:
+
+ GSS_Wrap for the sender, with conf_flag == FALSE
+
+ GSS_Unwrap for the receiver
+
+ The procedure associated with ENC commands, 632 replies, and Private
+ file transfers is:
+
+ GSS_Wrap for the sender, with conf_flag == TRUE
+ GSS_Unwrap for the receiver
+
+ CONF commands and 633 replies are not supported.
+
+ Both the client and server should inspect the value of conf_avail to
+ determine whether the peer supports confidentiality services.
+
+ When the security state is reset (when AUTH is received a second
+ time, or when REIN is received), this should be done by calling the
+ GSS_Delete_sec_context function.
+
+Appendix II: Specification under Kerberos version 4
+
+ The security mechanism name (for the AUTH command) associated with
+ Kerberos Version 4 is KERBEROS_V4. If the server supports
+ KERBEROS_V4, it must respond with a 334 reply code indicating that an
+ ADAT command is expected next.
+
+ The client must retrieve a ticket for the Kerberos principal
+ "ftp.hostname@realm" by calling krb_mk_req(3) with a principal name
+ of "ftp", an instance equal to the first part of the canonical host
+ name of the server with all letters in lower case (as returned by
+ krb_get_phost(3)), the server's realm name (as returned by
+ krb_realmofhost(3)), and an arbitrary checksum. The ticket must then
+ be base 64 encoded and sent as the argument to an ADAT command.
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 25]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+ If the "ftp" principal name is not a registered principal in the
+ Kerberos database, then the client may fall back on the "rcmd"
+ principal name (same instance and realm). However, servers must
+ accept only one or the other of these principal names, and must not
+ be willing to accept either. Generally, if the server has a key for
+ the "ftp" principal in its srvtab, then that principal only must be
+ used, otherwise the "rcmd" principal only must be used.
+
+ The server must base 64 decode the argument to the ADAT command and
+ pass the result to krb_rd_req(3). The server must add one to the
+ checksum from the authenticator, convert the result to network byte
+ order (most significant byte first), and sign it using
+ krb_mk_safe(3), and base 64 encode the result. Upon success, the
+ server must reply to the client with a 235 code and include
+ "ADAT=base64string" in the text of the reply. Upon failure, the
+ server should reply 535.
+
+ Upon receipt of the 235 reply from the server, the client must parse
+ the text of the reply for the base 64 encoded data, decode it,
+ convert it from network byte order, and pass the result to
+ krb_rd_safe(3). The client must consider the server authenticated if
+ the resultant checksum is equal to one plus the value previously
+ sent.
+
+ The procedure associated with MIC commands, 631 replies, and Safe
+ file transfers is:
+
+ krb_mk_safe(3) for the sender
+ krb_rd_safe(3) for the receiver
+
+ The procedure associated with ENC commands, 632 replies, and Private
+ file transfers is:
+
+ krb_mk_priv(3) for the sender
+ krb_rd_priv(3) for the receiver
+
+ CONF commands and 633 replies are not supported.
+
+ Note that this specification for KERBEROS_V4 contains no provision
+ for negotiating alternate means for integrity and confidentiality
+ routines. Note also that the ADAT exchange does not convey whether
+ the peer supports confidentiality services.
+
+ In order to stay within the allowed PBSZ, implementors must take note
+ that a cleartext buffer will grow by 31 bytes when processed by
+ krb_mk_safe(3) and will grow by 26 bytes when processed by
+ krb_mk_priv(3).
+
+
+
+
+Horowitz & Lunt Standards Track [Page 26]
+
+RFC 2228 FTP Security Extensions October 1997
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (1997). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implmentation may be prepared, copied, published
+ andand distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Horowitz & Lunt Standards Track [Page 27]
+
diff --git a/crypto/heimdal/doc/whatis.texi b/crypto/heimdal/doc/whatis.texi
new file mode 100644
index 000000000000..97d4da2aa505
--- /dev/null
+++ b/crypto/heimdal/doc/whatis.texi
@@ -0,0 +1,149 @@
+@node What is Kerberos?, Building and Installing, Introduction, Top
+@chapter What is Kerberos?
+
+@quotation
+@flushleft
+ Now this Cerberus had three heads of dogs,
+ the tail of a dragon, and on his back the
+ heads of all sorts of snakes.
+ --- Pseudo-Apollodorus Library 2.5.12
+@end flushleft
+@end quotation
+
+Kerberos is a system for authenticating users and services on a network.
+It is built upon the assumption that the network is ``unsafe''. For
+example, data sent over the network can be eavesdropped and altered, and
+addresses can also be faked. Therefore they cannot be used for
+authentication purposes.
+@cindex authentication
+
+Kerberos is a trusted third-party service. That means that there is a
+third party (the kerberos server) that is trusted by all the entities on
+the network (users and services, usually called @dfn{principals}). All
+principals share a secret password (or key) with the kerberos server and
+this enables principals to verify that the messages from the kerberos
+server are authentic. Thus trusting the kerberos server, users and
+services can authenticate each other.
+
+@section Basic mechanism
+
+@ifinfo
+@macro sub{arg}
+<\arg\>
+@end macro
+@end ifinfo
+
+@tex
+@def@xsub#1{$_{#1}$}
+@global@let@sub=@xsub
+@end tex
+
+@ifhtml
+@macro sub{arg}
+<\arg\>
+@end macro
+@end ifhtml
+
+@quotation
+@strong{Note:} This discussion is about Kerberos version 4, but version
+5 works similarly.
+@end quotation
+
+In Kerberos, principals use @dfn{tickets} to prove that they are who
+they claim to be. In the following example, @var{A} is the initiator of
+the authentication exchange, usually a user, and @var{B} is the service
+that @var{A} wishes to use.
+
+To obtain a ticket for a specific service, @var{A} sends a ticket
+request to the kerberos server. The request contains @var{A}'s and
+@var{B}'s names (along with some other fields). The kerberos server
+checks that both @var{A} and @var{B} are valid principals.
+
+Having verified the validity of the principals, it creates a packet
+containing @var{A}'s and @var{B}'s names, @var{A}'s network address
+(@var{A@sub{addr}}), the current time (@var{t@sub{issue}}), the lifetime
+of the ticket (@var{life}), and a secret @dfn{session key}
+@cindex session key
+(@var{K@sub{AB}}). This packet is encrypted with @var{B}'s secret key
+(@var{K@sub{B}}). The actual ticket (@var{T@sub{AB}}) looks like this:
+(@{@var{A}, @var{B}, @var{A@sub{addr}}, @var{t@sub{issue}}, @var{life},
+@var{K@sub{AB}}@}@var{K@sub{B}}).
+
+The reply to @var{A} consists of the ticket (@var{T@sub{AB}}), @var{B}'s
+name, the current time, the lifetime of the ticket, and the session key, all
+encrypted in @var{A}'s secret key (@{@var{B}, @var{t@sub{issue}},
+@var{life}, @var{K@sub{AB}}, @var{T@sub{AB}}@}@var{K@sub{A}}). @var{A}
+decrypts the reply and retains it for later use.
+
+@sp 1
+
+Before sending a message to @var{B}, @var{A} creates an authenticator
+consisting of @var{A}'s name, @var{A}'s address, the current time, and a
+``checksum'' chosen by @var{A}, all encrypted with the secret session
+key (@{@var{A}, @var{A@sub{addr}}, @var{t@sub{current}},
+@var{checksum}@}@var{K@sub{AB}}). This is sent together with the ticket
+received from the kerberos server to @var{B}. Upon reception, @var{B}
+decrypts the ticket using @var{B}'s secret key. Since the ticket
+contains the session key that the authenticator was encrypted with,
+@var{B} can now also decrypt the authenticator. To verify that @var{A}
+really is @var{A}, @var{B} now has to compare the contents of the ticket
+with that of the authenticator. If everything matches, @var{B} now
+considers @var{A} as properly authenticated.
+
+@c (here we should have some more explanations)
+
+@section Different attacks
+
+@subheading Impersonating A
+
+An impostor, @var{C} could steal the authenticator and the ticket as it
+is transmitted across the network, and use them to impersonate
+@var{A}. The address in the ticket and the authenticator was added to
+make it more difficult to perform this attack. To succeed @var{C} will
+have to either use the same machine as @var{A} or fake the source
+addresses of the packets. By including the time stamp in the
+authenticator, @var{C} does not have much time in which to mount the
+attack.
+
+@subheading Impersonating B
+
+@var{C} can hijack @var{B}'s network address, and when @var{A} sends
+her credentials, @var{C} just pretend to verify them. @var{C} can't
+be sure that she is talking to @var{A}.
+
+@section Defense strategies
+
+It would be possible to add a @dfn{replay cache}
+@cindex replay cache
+to the server side. The idea is to save the authenticators sent during
+the last few minutes, so that @var{B} can detect when someone is trying
+to retransmit an already used message. This is somewhat impractical
+(mostly regarding efficiency), and is not part of Kerberos 4; MIT
+Kerberos 5 contains it.
+
+To authenticate @var{B}, @var{A} might request that @var{B} sends
+something back that proves that @var{B} has access to the session
+key. An example of this is the checksum that @var{A} sent as part of the
+authenticator. One typical procedure is to add one to the checksum,
+encrypt it with the session key and send it back to @var{A}. This is
+called @dfn{mutual authentication}.
+
+The session key can also be used to add cryptographic checksums to the
+messages sent between @var{A} and @var{B} (known as @dfn{message
+integrity}). Encryption can also be added (@dfn{message
+confidentiality}). This is probably the best approach in all cases.
+@cindex integrity
+@cindex confidentiality
+
+@section Further reading
+
+The original paper on Kerberos from 1988 is @cite{Kerberos: An
+Authentication Service for Open Network Systems}, by Jennifer Steiner,
+Clifford Neuman and Jeffrey I. Schiller.
+
+A less technical description can be found in @cite{Designing an
+Authentication System: a Dialogue in Four Scenes} by Bill Bryant, also
+from 1988.
+
+These documents can be found on our web-page at
+@url{http://www.pdc.kth.se/kth-krb/}.
diff --git a/crypto/heimdal/doc/win2k.texi b/crypto/heimdal/doc/win2k.texi
new file mode 100644
index 000000000000..f5ec057f1689
--- /dev/null
+++ b/crypto/heimdal/doc/win2k.texi
@@ -0,0 +1,57 @@
+@node Windows 2000 compatability, Acknowledgments, Kerberos 4 issues, Top
+@comment node-name, next, previous, up
+@chapter Windows 2000 compatability
+
+Windows 2000 (formerly known as Windows NT 5) from Microsoft implements
+Kerberos 5. Their implementation, however, has some quirks,
+peculiarities, and bugs. This chapter is a short summary of the things
+that we have found out while trying to test Heimdal against Windows
+2000. Another big problem with the Kerberos implementation in Windows
+2000 is the almost complete lack of documentation.
+
+This information should apply to Heimdal @value{VERSION} and Windows
+2000 RC1. It's of course subject all the time and mostly consists of
+our not so inspired guesses. Hopefully it's still somewhat useful.
+
+@menu
+* Encryption types::
+* Authorization data::
+@end menu
+
+@node Encryption types, Authorization data, Windows 2000 compatability, Windows 2000 compatability
+@comment node-name, next, previous, up
+@section Encryption types
+
+Windows 2000 supports both the standard DES encryptions (des-cbc-crc and
+des-cbc-md5) and its own proprietary encryption that is based on md4 and
+rc4 and which you cannot get hold of how it works with a NDA. To enable
+a given principal to use DES, it needs to have DES keys in the database.
+To do this, you need to enable DES keys for the particular principal
+with the user administration tool and then change the password.
+
+@node Authorization data, , Encryption types, Windows 2000 compatability
+@comment node-name, next, previous, up
+@section Authorization data
+
+The Windows 2000 KDC also adds extra authorization data in tickets.
+It is at this point unclear what triggers it to do this. The format of
+this data is unknown and according to Microsoft, subject to change. A
+simple way of getting hold of the data to be able to understand it
+better is described here.
+
+@enumerate
+@item Find the client example on using the SSPI in the SDK documentation.
+@item Change ``AuthSamp'' in the source code to lowercase.
+@item Build the program.
+@item Add the ``authsamp'' principal with a known password to the
+database. Make sure it has a DES key.
+@item Run @kbd{ktutil add} to add the key for that principal to a
+keytab.
+@item Run @kbd{appl/test/nt_gss_server -p 2000 -s authsamp
+--dump-auth=file} where file is an appropriate file.
+@item It should authenticate and dump for you the authorization data in
+the file.
+@item The tool @kbd{lib/asn1/asn1_print} is somewhat useful for
+analyzing the data.
+@end enumerate
+
diff --git a/crypto/heimdal/etc/services.append b/crypto/heimdal/etc/services.append
new file mode 100644
index 000000000000..e3a31f975ef6
--- /dev/null
+++ b/crypto/heimdal/etc/services.append
@@ -0,0 +1,27 @@
+#
+# $Id: services.append,v 1.4 1999/07/23 21:36:03 assar Exp $
+#
+# Kerberos services
+#
+kerberos 88/udp kerberos-sec # Kerberos v5 UDP
+kerberos 88/tcp kerberos-sec # Kerberos v5 TCP
+kpasswd 464/udp # password changing
+kpasswd 464/tdp # password changing
+klogin 543/tcp # Kerberos authenticated rlogin
+kshell 544/tcp krcmd # and remote shell
+ekshell 545/tcp # Kerberos encrypted remote shell -kfall
+ekshell2 2106/tcp # What U of Colorado @ Boulder uses?
+kerberos-adm 749/udp # v5 kadmin
+kerberos-adm 749/tcp # v5 kadmin
+kerberos-iv 750/udp kdc # Kerberos authentication--udp
+kerberos-iv 750/tcp kdc # Kerberos authentication--tcp
+kerberos_master 751/udp # v4 kadmin
+kerberos_master 751/tcp # v4 kadmin
+krb_prop 754/tcp hprop # Kerberos slave propagation
+kpop 1109/tcp # Pop with Kerberos
+eklogin 2105/tcp # Kerberos encrypted rlogin
+rkinit 2108/tcp # Kerberos remote kinit
+kf 2110/tcp # forward credentials
+kx 2111/tcp # X over kerberos
+kip 2112/tcp # IP over kerberos
+kauth 2120/tcp # Remote kauth
diff --git a/crypto/heimdal/include/Makefile.am b/crypto/heimdal/include/Makefile.am
new file mode 100644
index 000000000000..f9d240b3c67a
--- /dev/null
+++ b/crypto/heimdal/include/Makefile.am
@@ -0,0 +1,50 @@
+# $Id: Makefile.am,v 1.30 1999/12/21 17:03:11 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+SUBDIRS = kadm5
+
+noinst_PROGRAMS = bits
+CHECK_LOCAL =
+
+INCLUDES = -DHOST=\"$(CANONICAL_HOST)\"
+
+include_HEADERS = krb5-types.h
+
+krb5-types.h: bits$(EXEEXT)
+ ./bits$(EXEEXT) krb5-types.h
+
+CLEANFILES = \
+ asn1.h \
+ asn1_err.h \
+ base64.h \
+ com_err.h \
+ com_right.h \
+ der.h \
+ des.h \
+ editline.h \
+ err.h \
+ getarg.h \
+ glob.h \
+ gssapi.h \
+ hdb.h \
+ hdb_asn1.h \
+ hdb_err.h \
+ heim_err.h \
+ kafs.h \
+ krb5-protos.h \
+ krb5-private.h \
+ krb5-types.h \
+ krb5.h \
+ krb5_err.h \
+ md4.h \
+ md5.h \
+ otp.h \
+ parse_time.h \
+ parse_units.h \
+ resolve.h \
+ roken-common.h \
+ roken.h \
+ sha.h \
+ sl.h \
+ xdbm.h
diff --git a/crypto/heimdal/include/Makefile.in b/crypto/heimdal/include/Makefile.in
new file mode 100644
index 000000000000..dd2344374b6b
--- /dev/null
+++ b/crypto/heimdal/include/Makefile.in
@@ -0,0 +1,748 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.30 1999/12/21 17:03:11 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -DHOST=\"$(CANONICAL_HOST)\"
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+CHECK_LOCAL =
+
+SUBDIRS = kadm5
+
+noinst_PROGRAMS = bits
+
+include_HEADERS = krb5-types.h
+
+CLEANFILES = asn1.h asn1_err.h base64.h com_err.h com_right.h der.h des.h editline.h err.h getarg.h glob.h gssapi.h hdb.h hdb_asn1.h hdb_err.h heim_err.h kafs.h krb5-protos.h krb5-private.h krb5-types.h krb5.h krb5_err.h md4.h md5.h otp.h parse_time.h parse_units.h resolve.h roken-common.h roken.h sha.h sl.h xdbm.h
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+noinst_PROGRAMS = bits$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+bits_SOURCES = bits.c
+bits_OBJECTS = bits.$(OBJEXT)
+bits_LDADD = $(LDADD)
+bits_DEPENDENCIES =
+bits_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(include_HEADERS)
+
+DIST_COMMON = ./stamp-h.in Makefile.am Makefile.in config.h.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = bits.c
+OBJECTS = bits.$(OBJEXT)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=include/config.h \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+bits$(EXEEXT): $(bits_OBJECTS) $(bits_DEPENDENCIES)
+ @rm -f bits$(EXEEXT)
+ $(LINK) $(bits_LDFLAGS) $(bits_OBJECTS) $(bits_LDADD) $(LIBS)
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = include
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-recursive
+
+install-data-am: install-includeHEADERS install-data-local
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-includeHEADERS
+uninstall: uninstall-recursive
+all-am: Makefile $(PROGRAMS) $(HEADERS) config.h all-local
+all-redirect: all-recursive-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-hdr mostlyclean-noinstPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-hdr clean-noinstPROGRAMS clean-compile clean-libtool \
+ clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-hdr distclean-noinstPROGRAMS distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+
+maintainer-clean-am: maintainer-clean-hdr \
+ maintainer-clean-noinstPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool uninstall-includeHEADERS \
+install-includeHEADERS install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+all-recursive-am install-exec-am install-exec install-data-local \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-local all-redirect all-am all installdirs-am installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+krb5-types.h: bits$(EXEEXT)
+ ./bits$(EXEEXT) krb5-types.h
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/include/bits.c b/crypto/heimdal/include/bits.c
new file mode 100644
index 000000000000..5eb9bd0d2013
--- /dev/null
+++ b/crypto/heimdal/include/bits.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: bits.c,v 1.16 1999/12/02 17:04:57 joda Exp $");
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+static void
+my_strupr(char *s)
+{
+ char *p = s;
+
+ while(*p){
+ if(islower((unsigned char)*p))
+ *p = toupper((unsigned char)*p);
+ p++;
+ }
+}
+
+
+#define BITSIZE(TYPE) \
+{ \
+ int b = 0; TYPE x = 1, zero = 0; char *pre = "u_"; \
+ char tmp[128], tmp2[128]; \
+ while(x){ x <<= 1; b++; if(x < zero) pre=""; } \
+ if(b >= len){ \
+ int tabs; \
+ sprintf(tmp, "%sint%d_t" , pre, len); \
+ sprintf(tmp2, "typedef %s %s;", #TYPE, tmp); \
+ my_strupr(tmp); \
+ tabs = 5 - strlen(tmp2) / 8; \
+ fprintf(f, "%s", tmp2); \
+ while(tabs-- > 0) fprintf(f, "\t"); \
+ fprintf(f, "/* %2d bits */\n", b); \
+ return; \
+ } \
+}
+
+static void
+try_signed(FILE *f, int len)
+{
+ BITSIZE(signed char);
+ BITSIZE(short);
+ BITSIZE(int);
+ BITSIZE(long);
+#ifdef HAVE_LONG_LONG
+ BITSIZE(long long);
+#endif
+ fprintf(f, "/* There is no %d bit type */\n", len);
+}
+
+static void
+try_unsigned(FILE *f, int len)
+{
+ BITSIZE(unsigned char);
+ BITSIZE(unsigned short);
+ BITSIZE(unsigned int);
+ BITSIZE(unsigned long);
+#ifdef HAVE_LONG_LONG
+ BITSIZE(unsigned long long);
+#endif
+ fprintf(f, "/* There is no %d bit type */\n", len);
+}
+
+static int
+print_bt(FILE *f, int flag)
+{
+ if(flag == 0){
+ fprintf(f, "/* For compatibility with various type definitions */\n");
+ fprintf(f, "#ifndef __BIT_TYPES_DEFINED__\n");
+ fprintf(f, "#define __BIT_TYPES_DEFINED__\n");
+ fprintf(f, "\n");
+ }
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ FILE *f;
+ int flag;
+ char *fn, *hb;
+
+ if(argc < 2){
+ fn = "bits.h";
+ hb = "__BITS_H__";
+ f = stdout;
+ } else {
+ char *p;
+ fn = argv[1];
+ hb = malloc(strlen(fn) + 5);
+ sprintf(hb, "__%s__", fn);
+ for(p = hb; *p; p++){
+ if(!isalnum((unsigned char)*p))
+ *p = '_';
+ }
+ f = fopen(argv[1], "w");
+ }
+ fprintf(f, "/* %s -- this file was generated for %s by\n", fn, HOST);
+ fprintf(f, " %*s %s */\n\n", (int)strlen(fn), "",
+ "$Id: bits.c,v 1.16 1999/12/02 17:04:57 joda Exp $");
+ fprintf(f, "#ifndef %s\n", hb);
+ fprintf(f, "#define %s\n", hb);
+ fprintf(f, "\n");
+#ifdef HAVE_SYS_TYPES_H
+ fprintf(f, "#include <sys/types.h>\n");
+#endif
+#ifdef HAVE_INTTYPES_H
+ fprintf(f, "#include <inttypes.h>\n");
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+ fprintf(f, "#include <sys/bitypes.h>\n");
+#endif
+#ifdef HAVE_BIND_BITYPES_H
+ fprintf(f, "#include <bind/bitypes.h>\n");
+#endif
+#ifdef HAVE_NETINET_IN6_MACHTYPES_H
+ fprintf(f, "#include <netinet/in6_machtypes.h>\n");
+#endif
+ fprintf(f, "\n");
+
+ flag = 0;
+#ifndef HAVE_INT8_T
+ flag = print_bt(f, flag);
+ try_signed (f, 8);
+#endif /* HAVE_INT8_T */
+#ifndef HAVE_INT16_T
+ flag = print_bt(f, flag);
+ try_signed (f, 16);
+#endif /* HAVE_INT16_T */
+#ifndef HAVE_INT32_T
+ flag = print_bt(f, flag);
+ try_signed (f, 32);
+#endif /* HAVE_INT32_T */
+#if 0
+#ifndef HAVE_INT64_T
+ flag = print_bt(f, flag);
+ try_signed (f, 64);
+#endif /* HAVE_INT64_T */
+#endif
+
+#ifndef HAVE_U_INT8_T
+ flag = print_bt(f, flag);
+ try_unsigned (f, 8);
+#endif /* HAVE_INT8_T */
+#ifndef HAVE_U_INT16_T
+ flag = print_bt(f, flag);
+ try_unsigned (f, 16);
+#endif /* HAVE_U_INT16_T */
+#ifndef HAVE_U_INT32_T
+ flag = print_bt(f, flag);
+ try_unsigned (f, 32);
+#endif /* HAVE_U_INT32_T */
+#if 0
+#ifndef HAVE_U_INT64_T
+ flag = print_bt(f, flag);
+ try_unsigned (f, 64);
+#endif /* HAVE_U_INT64_T */
+#endif
+
+ if(flag){
+ fprintf(f, "\n");
+ fprintf(f, "#endif /* __BIT_TYPES_DEFINED__ */\n\n");
+ }
+ fprintf(f, "#endif /* %s */\n", hb);
+ return 0;
+}
diff --git a/crypto/heimdal/include/config.h.in b/crypto/heimdal/include/config.h.in
new file mode 100644
index 000000000000..6cbd298470e5
--- /dev/null
+++ b/crypto/heimdal/include/config.h.in
@@ -0,0 +1,1164 @@
+/* include/config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef pid_t
+
+/* Define as the return type of signal handlers (int or void). */
+#undef RETSIGTYPE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm. */
+#undef TM_IN_SYS_TIME
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define if the X Window System is missing or not being used. */
+#undef X_DISPLAY_MISSING
+
+/* Define if lex declares yytext as a char * by default, not a char[]. */
+#undef YYTEXT_POINTER
+
+/* Define if you have the XauFileName function. */
+#undef HAVE_XAUFILENAME
+
+/* Define if you have the XauReadAuth function. */
+#undef HAVE_XAUREADAUTH
+
+/* Define if you have the XauWriteAuth function. */
+#undef HAVE_XAUWRITEAUTH
+
+/* Define if you have the _getpty function. */
+#undef HAVE__GETPTY
+
+/* Define if you have the _scrsize function. */
+#undef HAVE__SCRSIZE
+
+/* Define if you have the asnprintf function. */
+#undef HAVE_ASNPRINTF
+
+/* Define if you have the asprintf function. */
+#undef HAVE_ASPRINTF
+
+/* Define if you have the cap_set_proc function. */
+#undef HAVE_CAP_SET_PROC
+
+/* Define if you have the cgetent function. */
+#undef HAVE_CGETENT
+
+/* Define if you have the chown function. */
+#undef HAVE_CHOWN
+
+/* Define if you have the copyhostent function. */
+#undef HAVE_COPYHOSTENT
+
+/* Define if you have the crypt function. */
+#undef HAVE_CRYPT
+
+/* Define if you have the daemon function. */
+#undef HAVE_DAEMON
+
+/* Define if you have the dbm_firstkey function. */
+#undef HAVE_DBM_FIRSTKEY
+
+/* Define if you have the dbopen function. */
+#undef HAVE_DBOPEN
+
+/* Define if you have the dlopen function. */
+#undef HAVE_DLOPEN
+
+/* Define if you have the dn_expand function. */
+#undef HAVE_DN_EXPAND
+
+/* Define if you have the el_init function. */
+#undef HAVE_EL_INIT
+
+/* Define if you have the err function. */
+#undef HAVE_ERR
+
+/* Define if you have the errx function. */
+#undef HAVE_ERRX
+
+/* Define if you have the fchown function. */
+#undef HAVE_FCHOWN
+
+/* Define if you have the fcntl function. */
+#undef HAVE_FCNTL
+
+/* Define if you have the flock function. */
+#undef HAVE_FLOCK
+
+/* Define if you have the fnmatch function. */
+#undef HAVE_FNMATCH
+
+/* Define if you have the freeaddrinfo function. */
+#undef HAVE_FREEADDRINFO
+
+/* Define if you have the freehostent function. */
+#undef HAVE_FREEHOSTENT
+
+/* Define if you have the gai_strerror function. */
+#undef HAVE_GAI_STRERROR
+
+/* Define if you have the getaddrinfo function. */
+#undef HAVE_GETADDRINFO
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getdtablesize function. */
+#undef HAVE_GETDTABLESIZE
+
+/* Define if you have the getegid function. */
+#undef HAVE_GETEGID
+
+/* Define if you have the geteuid function. */
+#undef HAVE_GETEUID
+
+/* Define if you have the getgid function. */
+#undef HAVE_GETGID
+
+/* Define if you have the gethostbyname function. */
+#undef HAVE_GETHOSTBYNAME
+
+/* Define if you have the gethostbyname2 function. */
+#undef HAVE_GETHOSTBYNAME2
+
+/* Define if you have the gethostname function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define if you have the getipnodebyaddr function. */
+#undef HAVE_GETIPNODEBYADDR
+
+/* Define if you have the getipnodebyname function. */
+#undef HAVE_GETIPNODEBYNAME
+
+/* Define if you have the getlogin function. */
+#undef HAVE_GETLOGIN
+
+/* Define if you have the getmsg function. */
+#undef HAVE_GETMSG
+
+/* Define if you have the getnameinfo function. */
+#undef HAVE_GETNAMEINFO
+
+/* Define if you have the getopt function. */
+#undef HAVE_GETOPT
+
+/* Define if you have the getpwnam_r function. */
+#undef HAVE_GETPWNAM_R
+
+/* Define if you have the getrlimit function. */
+#undef HAVE_GETRLIMIT
+
+/* Define if you have the getsockopt function. */
+#undef HAVE_GETSOCKOPT
+
+/* Define if you have the getspnam function. */
+#undef HAVE_GETSPNAM
+
+/* Define if you have the gettimeofday function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define if you have the getudbnam function. */
+#undef HAVE_GETUDBNAM
+
+/* Define if you have the getuid function. */
+#undef HAVE_GETUID
+
+/* Define if you have the getusershell function. */
+#undef HAVE_GETUSERSHELL
+
+/* Define if you have the grantpt function. */
+#undef HAVE_GRANTPT
+
+/* Define if you have the hstrerror function. */
+#undef HAVE_HSTRERROR
+
+/* Define if you have the inet_aton function. */
+#undef HAVE_INET_ATON
+
+/* Define if you have the inet_ntop function. */
+#undef HAVE_INET_NTOP
+
+/* Define if you have the inet_pton function. */
+#undef HAVE_INET_PTON
+
+/* Define if you have the initgroups function. */
+#undef HAVE_INITGROUPS
+
+/* Define if you have the innetgr function. */
+#undef HAVE_INNETGR
+
+/* Define if you have the iruserok function. */
+#undef HAVE_IRUSEROK
+
+/* Define if you have the krb_disable_debug function. */
+#undef HAVE_KRB_DISABLE_DEBUG
+
+/* Define if you have the krb_enable_debug function. */
+#undef HAVE_KRB_ENABLE_DEBUG
+
+/* Define if you have the krb_get_our_ip_for_realm function. */
+#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
+
+/* Define if you have the logwtmp function. */
+#undef HAVE_LOGWTMP
+
+/* Define if you have the lstat function. */
+#undef HAVE_LSTAT
+
+/* Define if you have the memmove function. */
+#undef HAVE_MEMMOVE
+
+/* Define if you have the mkstemp function. */
+#undef HAVE_MKSTEMP
+
+/* Define if you have the mktime function. */
+#undef HAVE_MKTIME
+
+/* Define if you have the ptsname function. */
+#undef HAVE_PTSNAME
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the rand function. */
+#undef HAVE_RAND
+
+/* Define if you have the random function. */
+#undef HAVE_RANDOM
+
+/* Define if you have the rcmd function. */
+#undef HAVE_RCMD
+
+/* Define if you have the readv function. */
+#undef HAVE_READV
+
+/* Define if you have the recvmsg function. */
+#undef HAVE_RECVMSG
+
+/* Define if you have the res_search function. */
+#undef HAVE_RES_SEARCH
+
+/* Define if you have the revoke function. */
+#undef HAVE_REVOKE
+
+/* Define if you have the sa_family_t function. */
+#undef HAVE_SA_FAMILY_T
+
+/* Define if you have the select function. */
+#undef HAVE_SELECT
+
+/* Define if you have the sendmsg function. */
+#undef HAVE_SENDMSG
+
+/* Define if you have the setegid function. */
+#undef HAVE_SETEGID
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the seteuid function. */
+#undef HAVE_SETEUID
+
+/* Define if you have the setitimer function. */
+#undef HAVE_SETITIMER
+
+/* Define if you have the setlim function. */
+#undef HAVE_SETLIM
+
+/* Define if you have the setlogin function. */
+#undef HAVE_SETLOGIN
+
+/* Define if you have the setpcred function. */
+#undef HAVE_SETPCRED
+
+/* Define if you have the setpgid function. */
+#undef HAVE_SETPGID
+
+/* Define if you have the setproctitle function. */
+#undef HAVE_SETPROCTITLE
+
+/* Define if you have the setregid function. */
+#undef HAVE_SETREGID
+
+/* Define if you have the setresgid function. */
+#undef HAVE_SETRESGID
+
+/* Define if you have the setresuid function. */
+#undef HAVE_SETRESUID
+
+/* Define if you have the setreuid function. */
+#undef HAVE_SETREUID
+
+/* Define if you have the setsid function. */
+#undef HAVE_SETSID
+
+/* Define if you have the setsockopt function. */
+#undef HAVE_SETSOCKOPT
+
+/* Define if you have the setutent function. */
+#undef HAVE_SETUTENT
+
+/* Define if you have the sgi_getcapabilitybyname function. */
+#undef HAVE_SGI_GETCAPABILITYBYNAME
+
+/* Define if you have the sigaction function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the socket function. */
+#undef HAVE_SOCKET
+
+/* Define if you have the socklen_t function. */
+#undef HAVE_SOCKLEN_T
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strdup function. */
+#undef HAVE_STRDUP
+
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
+
+/* Define if you have the strftime function. */
+#undef HAVE_STRFTIME
+
+/* Define if you have the strlcat function. */
+#undef HAVE_STRLCAT
+
+/* Define if you have the strlcpy function. */
+#undef HAVE_STRLCPY
+
+/* Define if you have the strlwr function. */
+#undef HAVE_STRLWR
+
+/* Define if you have the strncasecmp function. */
+#undef HAVE_STRNCASECMP
+
+/* Define if you have the strndup function. */
+#undef HAVE_STRNDUP
+
+/* Define if you have the strnlen function. */
+#undef HAVE_STRNLEN
+
+/* Define if you have the strptime function. */
+#undef HAVE_STRPTIME
+
+/* Define if you have the strsep function. */
+#undef HAVE_STRSEP
+
+/* Define if you have the strstr function. */
+#undef HAVE_STRSTR
+
+/* Define if you have the strtok_r function. */
+#undef HAVE_STRTOK_R
+
+/* Define if you have the struct_addrinfo function. */
+#undef HAVE_STRUCT_ADDRINFO
+
+/* Define if you have the struct_sockaddr function. */
+#undef HAVE_STRUCT_SOCKADDR
+
+/* Define if you have the struct_sockaddr_storage function. */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE
+
+/* Define if you have the strupr function. */
+#undef HAVE_STRUPR
+
+/* Define if you have the swab function. */
+#undef HAVE_SWAB
+
+/* Define if you have the sysconf function. */
+#undef HAVE_SYSCONF
+
+/* Define if you have the sysctl function. */
+#undef HAVE_SYSCTL
+
+/* Define if you have the syslog function. */
+#undef HAVE_SYSLOG
+
+/* Define if you have the tgetent function. */
+#undef HAVE_TGETENT
+
+/* Define if you have the timegm function. */
+#undef HAVE_TIMEGM
+
+/* Define if you have the ttyname function. */
+#undef HAVE_TTYNAME
+
+/* Define if you have the ttyslot function. */
+#undef HAVE_TTYSLOT
+
+/* Define if you have the umask function. */
+#undef HAVE_UMASK
+
+/* Define if you have the uname function. */
+#undef HAVE_UNAME
+
+/* Define if you have the unlockpt function. */
+#undef HAVE_UNLOCKPT
+
+/* Define if you have the unsetenv function. */
+#undef HAVE_UNSETENV
+
+/* Define if you have the vasnprintf function. */
+#undef HAVE_VASNPRINTF
+
+/* Define if you have the vasprintf function. */
+#undef HAVE_VASPRINTF
+
+/* Define if you have the verr function. */
+#undef HAVE_VERR
+
+/* Define if you have the verrx function. */
+#undef HAVE_VERRX
+
+/* Define if you have the vhangup function. */
+#undef HAVE_VHANGUP
+
+/* Define if you have the vsyslog function. */
+#undef HAVE_VSYSLOG
+
+/* Define if you have the vwarn function. */
+#undef HAVE_VWARN
+
+/* Define if you have the vwarnx function. */
+#undef HAVE_VWARNX
+
+/* Define if you have the warn function. */
+#undef HAVE_WARN
+
+/* Define if you have the warnx function. */
+#undef HAVE_WARNX
+
+/* Define if you have the writev function. */
+#undef HAVE_WRITEV
+
+/* Define if you have the yp_get_default_domain function. */
+#undef HAVE_YP_GET_DEFAULT_DOMAIN
+
+/* Define if you have the <arpa/ftp.h> header file. */
+#undef HAVE_ARPA_FTP_H
+
+/* Define if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define if you have the <arpa/nameser.h> header file. */
+#undef HAVE_ARPA_NAMESER_H
+
+/* Define if you have the <arpa/telnet.h> header file. */
+#undef HAVE_ARPA_TELNET_H
+
+/* Define if you have the <bind/bitypes.h> header file. */
+#undef HAVE_BIND_BITYPES_H
+
+/* Define if you have the <bsdsetjmp.h> header file. */
+#undef HAVE_BSDSETJMP_H
+
+/* Define if you have the <capability.h> header file. */
+#undef HAVE_CAPABILITY_H
+
+/* Define if you have the <crypt.h> header file. */
+#undef HAVE_CRYPT_H
+
+/* Define if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define if you have the <db.h> header file. */
+#undef HAVE_DB_H
+
+/* Define if you have the <db_185.h> header file. */
+#undef HAVE_DB_185_H
+
+/* Define if you have the <dbm.h> header file. */
+#undef HAVE_DBM_H
+
+/* Define if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define if you have the <err.h> header file. */
+#undef HAVE_ERR_H
+
+/* Define if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
+/* Define if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
+/* Define if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <maillock.h> header file. */
+#undef HAVE_MAILLOCK_H
+
+/* Define if you have the <ndbm.h> header file. */
+#undef HAVE_NDBM_H
+
+/* Define if you have the <net/if.h> header file. */
+#undef HAVE_NET_IF_H
+
+/* Define if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define if you have the <netinet/in6.h> header file. */
+#undef HAVE_NETINET_IN6_H
+
+/* Define if you have the <netinet/in6_machtypes.h> header file. */
+#undef HAVE_NETINET_IN6_MACHTYPES_H
+
+/* Define if you have the <netinet/in6_var.h> header file. */
+#undef HAVE_NETINET_IN6_VAR_H
+
+/* Define if you have the <netinet/in_systm.h> header file. */
+#undef HAVE_NETINET_IN_SYSTM_H
+
+/* Define if you have the <netinet/ip.h> header file. */
+#undef HAVE_NETINET_IP_H
+
+/* Define if you have the <netinet/tcp.h> header file. */
+#undef HAVE_NETINET_TCP_H
+
+/* Define if you have the <netinet6/in6.h> header file. */
+#undef HAVE_NETINET6_IN6_H
+
+/* Define if you have the <netinfo/ni.h> header file. */
+#undef HAVE_NETINFO_NI_H
+
+/* Define if you have the <paths.h> header file. */
+#undef HAVE_PATHS_H
+
+/* Define if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define if you have the <pty.h> header file. */
+#undef HAVE_PTY_H
+
+/* Define if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define if you have the <resolv.h> header file. */
+#undef HAVE_RESOLV_H
+
+/* Define if you have the <rpcsvc/dbm.h> header file. */
+#undef HAVE_RPCSVC_DBM_H
+
+/* Define if you have the <sac.h> header file. */
+#undef HAVE_SAC_H
+
+/* Define if you have the <security/pam_modules.h> header file. */
+#undef HAVE_SECURITY_PAM_MODULES_H
+
+/* Define if you have the <sgtty.h> header file. */
+#undef HAVE_SGTTY_H
+
+/* Define if you have the <shadow.h> header file. */
+#undef HAVE_SHADOW_H
+
+/* Define if you have the <siad.h> header file. */
+#undef HAVE_SIAD_H
+
+/* Define if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define if you have the <standards.h> header file. */
+#undef HAVE_STANDARDS_H
+
+/* Define if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
+/* Define if you have the <sys/bitypes.h> header file. */
+#undef HAVE_SYS_BITYPES_H
+
+/* Define if you have the <sys/capability.h> header file. */
+#undef HAVE_SYS_CAPABILITY_H
+
+/* Define if you have the <sys/category.h> header file. */
+#undef HAVE_SYS_CATEGORY_H
+
+/* Define if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/filio.h> header file. */
+#undef HAVE_SYS_FILIO_H
+
+/* Define if you have the <sys/ioccom.h> header file. */
+#undef HAVE_SYS_IOCCOM_H
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/proc.h> header file. */
+#undef HAVE_SYS_PROC_H
+
+/* Define if you have the <sys/pty.h> header file. */
+#undef HAVE_SYS_PTY_H
+
+/* Define if you have the <sys/ptyio.h> header file. */
+#undef HAVE_SYS_PTYIO_H
+
+/* Define if you have the <sys/ptyvar.h> header file. */
+#undef HAVE_SYS_PTYVAR_H
+
+/* Define if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define if you have the <sys/sockio.h> header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/str_tty.h> header file. */
+#undef HAVE_SYS_STR_TTY_H
+
+/* Define if you have the <sys/stream.h> header file. */
+#undef HAVE_SYS_STREAM_H
+
+/* Define if you have the <sys/stropts.h> header file. */
+#undef HAVE_SYS_STROPTS_H
+
+/* Define if you have the <sys/strtty.h> header file. */
+#undef HAVE_SYS_STRTTY_H
+
+/* Define if you have the <sys/syscall.h> header file. */
+#undef HAVE_SYS_SYSCALL_H
+
+/* Define if you have the <sys/sysctl.h> header file. */
+#undef HAVE_SYS_SYSCTL_H
+
+/* Define if you have the <sys/termio.h> header file. */
+#undef HAVE_SYS_TERMIO_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <sys/timeb.h> header file. */
+#undef HAVE_SYS_TIMEB_H
+
+/* Define if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define if you have the <sys/tty.h> header file. */
+#undef HAVE_SYS_TTY_H
+
+/* Define if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
+/* Define if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
+/* Define if you have the <sys/utsname.h> header file. */
+#undef HAVE_SYS_UTSNAME_H
+
+/* Define if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define if you have the <term.h> header file. */
+#undef HAVE_TERM_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the <tmpdir.h> header file. */
+#undef HAVE_TMPDIR_H
+
+/* Define if you have the <udb.h> header file. */
+#undef HAVE_UDB_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <util.h> header file. */
+#undef HAVE_UTIL_H
+
+/* Define if you have the <utmp.h> header file. */
+#undef HAVE_UTMP_H
+
+/* Define if you have the <utmpx.h> header file. */
+#undef HAVE_UTMPX_H
+
+/* Define if you have the X11 library (-lX11). */
+#undef HAVE_LIBX11
+
+/* Define if you have the Xau library (-lXau). */
+#undef HAVE_LIBXAU
+
+/* Define if you have the c_r library (-lc_r). */
+#undef HAVE_LIBC_R
+
+/* Define if you have the crypt library (-lcrypt). */
+#undef HAVE_LIBCRYPT
+
+/* Define if you have the curses library (-lcurses). */
+#undef HAVE_LIBCURSES
+
+/* Define if you have the dl library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define if you have the edit library (-ledit). */
+#undef HAVE_LIBEDIT
+
+/* Define if you have the gdbm library (-lgdbm). */
+#undef HAVE_LIBGDBM
+
+/* Define if you have the inet6 library (-linet6). */
+#undef HAVE_LIBINET6
+
+/* Define if you have the ip6 library (-lip6). */
+#undef HAVE_LIBIP6
+
+/* Define if you have the ncurses library (-lncurses). */
+#undef HAVE_LIBNCURSES
+
+/* Define if you have the ndbm library (-lndbm). */
+#undef HAVE_LIBNDBM
+
+/* Define if you have the nsl library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define if you have the resolv library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define if you have the socket library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define if you have the syslog library (-lsyslog). */
+#undef HAVE_LIBSYSLOG
+
+/* Define if you have the termcap library (-ltermcap). */
+#undef HAVE_LIBTERMCAP
+
+/* Define if you have the util library (-lutil). */
+#undef HAVE_LIBUTIL
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to what version of SunOS you are running. */
+#undef SunOS
+
+/* define if your compiler has __attribute__ */
+#undef HAVE___ATTRIBUTE__
+
+/* Define if you have the krb4 package. */
+#undef KRB4
+
+/* define if krb_put_int takes four arguments. */
+#undef HAVE_FOUR_VALUED_KRB_PUT_INT
+
+/* Define to one if your krb.h doesn't */
+#undef KRB_VERIFY_SECURE
+
+/* Define to two if your krb.h doesn't */
+#undef KRB_VERIFY_SECURE_FAIL
+
+/* Define to zero if your krb.h doesn't */
+#undef KRB_VERIFY_NOT_SECURE
+
+/* Enable Kerberos 5 support in applications. */
+#undef KRB5
+
+/* Define if you want to use the KDC as a kaserver. */
+#undef KASERVER
+
+/* Define if you want support in hprop for reading kaserver databases */
+#undef KASERVER_DB
+
+/* Define if you want OTP support in applications. */
+#undef OTP
+
+/* Define to enable basic OSF C2 support. */
+#undef HAVE_OSFC2
+
+/* Define if you have the readline package. */
+#undef READLINE
+
+/* Define if you have the hesiod package. */
+#undef HESIOD
+
+/* define if target is big endian */
+#undef WORDS_BIGENDIAN
+
+/* define if sys/param.h defines the endiness */
+#undef ENDIANESS_IN_SYS_PARAM_H
+
+/* Define this to what the type ssize_t should be. */
+#undef ssize_t
+
+/* Define this to what the type mode_t should be. */
+#undef mode_t
+
+/* Define this to what the type sig_atomic_t should be. */
+#undef sig_atomic_t
+
+/* Define if you want to use Netinfo instead of krb5.conf. */
+#undef HAVE_NETINFO
+
+/* Define if you have IPv6. */
+#undef HAVE_IPV6
+
+/* define if you have a working snprintf */
+#undef HAVE_SNPRINTF
+
+/* define if the system is missing a prototype for snprintf() */
+#undef NEED_SNPRINTF_PROTO
+
+/* define if you have a working vsnprintf */
+#undef HAVE_VSNPRINTF
+
+/* define if the system is missing a prototype for vsnprintf() */
+#undef NEED_VSNPRINTF_PROTO
+
+/* define if you have a glob() that groks
+ GLOB_BRACE, GLOB_NOCHECK, GLOB_QUOTE, and GLOB_TILDE */
+#undef HAVE_GLOB
+
+/* define if the system is missing a prototype for glob() */
+#undef NEED_GLOB_PROTO
+
+/* Define if getlogin has POSIX flavour (and not BSD). */
+#undef POSIX_GETLOGIN
+
+/* Define if getpwnam_r has POSIX flavour. */
+#undef POSIX_GETPWNAM_R
+
+/* Define if signal handlers return void. */
+#undef VOID_RETSIGTYPE
+
+/* define if the system is missing a prototype for hstrerror() */
+#undef NEED_HSTRERROR_PROTO
+
+/* define if the system is missing a prototype for asprintf() */
+#undef NEED_ASPRINTF_PROTO
+
+/* define if the system is missing a prototype for vasprintf() */
+#undef NEED_VASPRINTF_PROTO
+
+/* define if the system is missing a prototype for asnprintf() */
+#undef NEED_ASNPRINTF_PROTO
+
+/* define if the system is missing a prototype for vasnprintf() */
+#undef NEED_VASNPRINTF_PROTO
+
+/* define if the system is missing a prototype for setenv() */
+#undef NEED_SETENV_PROTO
+
+/* define if the system is missing a prototype for unsetenv() */
+#undef NEED_UNSETENV_PROTO
+
+/* define if the system is missing a prototype for gethostname() */
+#undef NEED_GETHOSTNAME_PROTO
+
+/* define if the system is missing a prototype for mkstemp() */
+#undef NEED_MKSTEMP_PROTO
+
+/* define if the system is missing a prototype for getusershell() */
+#undef NEED_GETUSERSHELL_PROTO
+
+/* define if the system is missing a prototype for inet_aton() */
+#undef NEED_INET_ATON_PROTO
+
+/* Define if realloc(NULL) doesn't work. */
+#undef BROKEN_REALLOC
+
+/* define if prototype of gethostbyname is compatible with
+ struct hostent *gethostbyname(const char *) */
+#undef GETHOSTBYNAME_PROTO_COMPATIBLE
+
+/* define if prototype of gethostbyaddr is compatible with
+ struct hostent *gethostbyaddr(const void *, size_t, int) */
+#undef GETHOSTBYADDR_PROTO_COMPATIBLE
+
+/* define if prototype of getservbyname is compatible with
+ struct servent *getservbyname(const char *, const char *) */
+#undef GETSERVBYNAME_PROTO_COMPATIBLE
+
+/* define if prototype of openlog is compatible with
+ void openlog(const char *, int, int) */
+#undef OPENLOG_PROTO_COMPATIBLE
+
+/* define if the system is missing a prototype for crypt() */
+#undef NEED_CRYPT_PROTO
+
+/* define if the system is missing a prototype for strtok_r() */
+#undef NEED_STRTOK_R_PROTO
+
+/* define if the system is missing a prototype for strsep() */
+#undef NEED_STRSEP_PROTO
+
+/* define if you have h_errno */
+#undef HAVE_H_ERRNO
+
+/* define if your system declares h_errno */
+#undef HAVE_H_ERRNO_DECLARATION
+
+/* define if you have h_errlist */
+#undef HAVE_H_ERRLIST
+
+/* define if your system declares h_errlist */
+#undef HAVE_H_ERRLIST_DECLARATION
+
+/* define if you have h_nerr */
+#undef HAVE_H_NERR
+
+/* define if your system declares h_nerr */
+#undef HAVE_H_NERR_DECLARATION
+
+/* define if you have __progname */
+#undef HAVE___PROGNAME
+
+/* define if your system declares __progname */
+#undef HAVE___PROGNAME_DECLARATION
+
+/* define if your system declares optarg */
+#undef HAVE_OPTARG_DECLARATION
+
+/* define if your system declares optind */
+#undef HAVE_OPTIND_DECLARATION
+
+/* define if your system declares opterr */
+#undef HAVE_OPTERR_DECLARATION
+
+/* define if your system declares optopt */
+#undef HAVE_OPTOPT_DECLARATION
+
+/* define if your system declares environ */
+#undef HAVE_ENVIRON_DECLARATION
+
+/* Define if struct utmp has field ut_addr. */
+#undef HAVE_STRUCT_UTMP_UT_ADDR
+
+/* Define if struct utmp has field ut_host. */
+#undef HAVE_STRUCT_UTMP_UT_HOST
+
+/* Define if struct utmp has field ut_id. */
+#undef HAVE_STRUCT_UTMP_UT_ID
+
+/* Define if struct utmp has field ut_pid. */
+#undef HAVE_STRUCT_UTMP_UT_PID
+
+/* Define if struct utmp has field ut_type. */
+#undef HAVE_STRUCT_UTMP_UT_TYPE
+
+/* Define if struct utmp has field ut_user. */
+#undef HAVE_STRUCT_UTMP_UT_USER
+
+/* Define if struct utmpx has field ut_exit. */
+#undef HAVE_STRUCT_UTMPX_UT_EXIT
+
+/* Define if struct utmpx has field ut_syslen. */
+#undef HAVE_STRUCT_UTMPX_UT_SYSLEN
+
+/* Define if struct tm has field tm_gmtoff. */
+#undef HAVE_STRUCT_TM_TM_GMTOFF
+
+/* Define if struct tm has field tm_zone. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
+/* define if you have timezone */
+#undef HAVE_TIMEZONE
+
+/* define if your system declares timezone */
+#undef HAVE_TIMEZONE_DECLARATION
+
+/* define if struct winsize is declared in sys/termios.h */
+#undef HAVE_STRUCT_WINSIZE
+
+/* define if struct winsize has ws_xpixel */
+#undef HAVE_WS_XPIXEL
+
+/* define if struct winsize has ws_ypixel */
+#undef HAVE_WS_YPIXEL
+
+/* define if you have struct spwd */
+#undef HAVE_STRUCT_SPWD
+
+/* Define if struct sockaddr has field sa_len. */
+#undef HAVE_STRUCT_SOCKADDR_SA_LEN
+
+/* Define if el_init takes four arguments. */
+#undef HAVE_FOUR_VALUED_EL_INIT
+
+/* Define if you have a readline compatible library. */
+#undef HAVE_READLINE
+
+/* Define if you want authentication support in telnet. */
+#undef AUTHENTICATION
+
+/* Define if you want encryption support in telnet. */
+#undef ENCRYPTION
+
+/* Define if you want to use DES encryption in telnet. */
+#undef DES_ENCRYPTION
+
+/* Define this to enable diagnostics in telnet. */
+#undef DIAGNOSTICS
+
+/* Define this to enable old environment option in telnet. */
+#undef OLD_ENVIRON
+
+/* Define this if you want support for broken ENV_{VAR,VAL} telnets. */
+#undef ENV_HACK
+
+/* Define if you have streams ptys. */
+#undef STREAMSPTY
+
+
+#undef BINDIR
+#undef LIBDIR
+#undef LIBEXECDIR
+#undef SBINDIR
+
+#undef HAVE_INT8_T
+#undef HAVE_INT16_T
+#undef HAVE_INT32_T
+#undef HAVE_INT64_T
+#undef HAVE_U_INT8_T
+#undef HAVE_U_INT16_T
+#undef HAVE_U_INT32_T
+#undef HAVE_U_INT64_T
+
+#if defined(HAVE_FOUR_VALUED_KRB_PUT_INT) || !defined(KRB4)
+#define KRB_PUT_INT(F, T, L, S) krb_put_int((F), (T), (L), (S))
+#else
+#define KRB_PUT_INT(F, T, L, S) krb_put_int((F), (T), (S))
+#endif
+
+#ifdef BROKEN_REALLOC
+#define realloc(X, Y) isoc_realloc((X), (Y))
+#define isoc_realloc(X, Y) ((X) ? realloc((X), (Y)) : malloc(Y))
+#endif
+
+#ifdef VOID_RETSIGTYPE
+#define SIGRETURN(x) return
+#else
+#define SIGRETURN(x) return (RETSIGTYPE)(x)
+#endif
+
+#define RCSID(msg) \
+static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg }
+
+#undef PROTOTYPES
+
+/* Maximum values on all known systems */
+#define MaxHostNameLen (64+4)
+#define MaxPathLen (1024+4)
+
+#if defined(HAVE_SGTTY_H) && defined(__NeXT__)
+#define SGTTY
+#endif
+
+/*
+ * Define NDBM if you are using the 4.3 ndbm library (which is part of
+ * libc). If not defined, 4.2 dbm will be assumed.
+ */
+#if defined(HAVE_DBM_FIRSTKEY)
+#define NDBM
+#endif
+
+/* telnet stuff ----------------------------------------------- */
+
+#if defined(ENCRYPTION) && !defined(AUTHENTICATION)
+#define AUTHENTICATION 1
+#endif
+
+/* Set this to the default system lead string for telnetd
+ * can contain %-escapes: %s=sysname, %m=machine, %r=os-release
+ * %v=os-version, %t=tty, %h=hostname, %d=date and time
+ */
+#undef USE_IM
+
+/* Used with login -p */
+#undef LOGIN_ARGS
+
+/* set this to a sensible login */
+#ifndef LOGIN_PATH
+#define LOGIN_PATH BINDIR "/login"
+#endif
+
+/* random defines */
+
+/*
+ * Defining this enables lots of useful (and used) extensions on
+ * glibc-based systems such as Linux
+ */
+
+#define _GNU_SOURCE
+
+/*
+ * this assumes that KRB_C_BIGENDIAN is used.
+ * if we can find out endianess at compile-time, do so,
+ * otherwise WORDS_BIGENDIAN should already have been defined
+ */
+
+#if ENDIANESS_IN_SYS_PARAM_H
+# include <sys/types.h>
+# include <sys/param.h>
+# if BYTE_ORDER == BIG_ENDIAN
+# define WORDS_BIGENDIAN 1
+# endif
+#endif
diff --git a/crypto/heimdal/include/kadm5/Makefile.am b/crypto/heimdal/include/kadm5/Makefile.am
new file mode 100644
index 000000000000..e0647b8474ac
--- /dev/null
+++ b/crypto/heimdal/include/kadm5/Makefile.am
@@ -0,0 +1,5 @@
+# $Id: Makefile.am,v 1.6 1999/03/20 13:58:17 joda Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+CLEANFILES = admin.h kadm5_err.h private.h
diff --git a/crypto/heimdal/include/kadm5/Makefile.in b/crypto/heimdal/include/kadm5/Makefile.in
new file mode 100644
index 000000000000..895c9f52f2c5
--- /dev/null
+++ b/crypto/heimdal/include/kadm5/Makefile.in
@@ -0,0 +1,494 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.6 1999/03/20 13:58:17 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+CLEANFILES = admin.h kadm5_err.h private.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .et .h .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign include/kadm5/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = include/kadm5
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: tags distdir info-am info dvi-am dvi check-local check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-local install-data-am install-data install-am install \
+uninstall-am uninstall all-local all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/include/stamp-h.in b/crypto/heimdal/include/stamp-h.in
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/crypto/heimdal/include/stamp-h.in
diff --git a/crypto/heimdal/install-sh b/crypto/heimdal/install-sh
new file mode 100755
index 000000000000..89fc9b098b8c
--- /dev/null
+++ b/crypto/heimdal/install-sh
@@ -0,0 +1,238 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/crypto/heimdal/kadmin/ChangeLog b/crypto/heimdal/kadmin/ChangeLog
new file mode 100644
index 000000000000..542667ec1f59
--- /dev/null
+++ b/crypto/heimdal/kadmin/ChangeLog
@@ -0,0 +1,212 @@
+2000-01-02 Assar Westerlund <assar@sics.se>
+
+ * server.c: check initial flag in ticket and allow users to change
+ their own password if it's set
+ * ext.c (do_ext_keytab): set timestamp
+
+1999-12-14 Assar Westerlund <assar@sics.se>
+
+ * del_enctype.c (usage): don't use arg_printusage
+
+1999-11-25 Assar Westerlund <assar@sics.se>
+
+ * del_enctype.c (del_enctype): try not to leak memory
+
+ * version4.c (kadm_ser_mod): use kadm5_s_modify_principal (no
+ _with_key)
+
+ * kadmin.c: add `del_enctype'
+
+ * del_enctype.c (del_enctype): new function for deleting enctypes
+ from a principal
+
+ * Makefile.am (kadmin_SOURCES): add del_enctype.c
+
+1999-11-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * server.c: cope with old clients
+
+ * kadmin_locl.h: remove version string
+
+1999-10-17 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (kadmin_LDADD): add LIB_dlopen
+
+1999-10-01 Assar Westerlund <assar@sics.se>
+
+ * ank.c (add_one_principal): `password' can cactually be NULL in
+ the overwrite code, check for it.
+
+1999-09-20 Assar Westerlund <assar@sics.se>
+
+ * mod.c (mod_entry): print the correct principal name in error
+ messages. From Love <lha@e.kth.se>
+
+1999-09-10 Assar Westerlund <assar@sics.se>
+
+ * init.c (init): also create `changepw/kerberos'
+
+ * version4.c: only create you loose packets when we fail decoding
+ and not when an operation is not performed for some reason
+ (decode_packet): read the service key from the hdb
+ (dispatch, decode_packet): return proper error messages
+
+ * version4.c (kadm_ser_cpw): add password quality functions
+
+1999-08-27 Johan Danielsson <joda@pdc.kth.se>
+
+ * server.c (handle_v5): give more informative message if
+ KRB5_KT_NOTFOUND
+
+1999-08-26 Johan Danielsson <joda@pdc.kth.se>
+
+ * kadmind.c: use HDB keytabs
+
+1999-08-25 Assar Westerlund <assar@sics.se>
+
+ * cpw.c (set_password): use correct variable. From Love
+ <lha@e.kth.se>
+
+ * server.c (v5_loop): use correct error code
+
+ * ank.c (add_one_principal): initialize `default_ent'
+
+1999-08-21 Assar Westerlund <assar@sics.se>
+
+ * random_password.c: new file, stolen from krb4
+
+ * kadmin_locl.h: add prototype for random_password
+
+ * cpw.c: add support for --random-password
+
+ * ank.c: add support for --random-password
+
+ * Makefile.am (kadmin_SOURCES): add random_password.c
+
+1999-08-19 Assar Westerlund <assar@sics.se>
+
+ * util.c (edit_timet): break when we manage to parse the time not
+ the inverse.
+
+ * mod.c: add parsing of lots of options. From Love
+ <lha@stacken.kth.se>
+
+ * ank.c: add setting of expiration and password expiration
+
+ * kadmin_locl.h: update util.c prototypes
+
+ * util.c: move-around. clean-up, rename, make consistent (and
+ some other weird stuff). based on patches from Love
+ <lha@stacken.kth.se>
+
+ * version4.c (kadm_ser_cpw): initialize password
+ (handle_v4): remove unused variable `ret'
+
+1999-08-16 Assar Westerlund <assar@sics.se>
+
+ * version4.c (handle_v4): more error checking and more correct
+ error messages
+
+ * server.c (v5_loop, kadmind_loop): more error checking and more
+ correct error messages
+
+1999-07-24 Assar Westerlund <assar@sics.se>
+
+ * util.c (str2timeval, edit_time): functions for parsing and
+ editing times. Based on patches from Love <lha@stacken.kth.se>.
+ (edit_entry): call new functions
+
+ * mod.c (mod_entry): allow modifying expiration times
+
+ * kadmin_locl.h (str2timeval): add prototype
+
+ * ank.c (add_one_principal): allow setting expiration times
+
+1999-07-03 Assar Westerlund <assar@sics.se>
+
+ * server.c (v5_loop): handle data allocation with krb5_data_alloc
+ and check return value
+
+1999-06-23 Assar Westerlund <assar@sics.se>
+
+ * version4.c (kadm_ser_cpw): read the key in the strange order
+ it's sent
+
+ * util.c (edit_entry): look at default
+ (edit_time): always set mask even if value == 0
+
+ * kadmin_locl.h (edit_entry): update
+
+ * ank.c: make ank use the values of the default principal for
+ prompting
+
+ * version4.c (values_to_ent): convert key data correctly
+
+1999-05-23 Assar Westerlund <assar@sics.se>
+
+ * init.c (create_random_entry): more correct setting of mask
+
+1999-05-21 Assar Westerlund <assar@sics.se>
+
+ * server.c (handle_v5): read sendauth version correctly.
+
+1999-05-14 Assar Westerlund <assar@sics.se>
+
+ * version4.c (error_code): try to handle really old krb4
+ distributions
+
+1999-05-11 Assar Westerlund <assar@sics.se>
+
+ * init.c (init): initialize realm_max_life and realm_max_rlife
+
+1999-05-07 Assar Westerlund <assar@sics.se>
+
+ * ank.c (add_new_key): initialize more variables
+
+1999-05-04 Assar Westerlund <assar@sics.se>
+
+ * version4.c (kadm_ser_cpw): always allow a user to change her
+ password
+ (kadm_ser_*): make logging work
+ clean-up and restructure
+
+ * kadmin_locl.h (set_entry): add prototype
+
+ * kadmin.c (usage): update usage string
+
+ * init.c (init): new arguments realm-max-ticket-life and
+ realm-max-renewable-life
+
+ * util.c (edit_time, edit_attributes): don't do anything if it's
+ already set
+ (set_entry): new function
+
+ * ank.c (add_new_key): new options for setting max-ticket-life,
+ max-renewable-life, and attributes
+
+ * server.c (v5_loop): remove unused variable
+
+ * kadmin_locl.h: add prototypes
+
+ * version4.c: re-insert krb_err.h and other miss
+
+ * server.c (kadmind_loop): break-up and restructure
+
+ * version4.c: add ACL checks more error code checks restructure
+
+1999-05-03 Johan Danielsson <joda@pdc.kth.se>
+
+ * load.c: check for (un-)encrypted keys
+
+ * dump.c: use hdb_print_entry
+
+ * version4.c: version 4 support
+
+ * Makefile.am: link with krb4
+
+ * kadmin_locl.h: include <sys/un.h>
+
+ * server.c: move from lib/kadm5, and add basic support for krb4
+ kadmin protocol
+
+ * kadmind.c: move recvauth to kadmind_loop()
diff --git a/crypto/heimdal/kadmin/Makefile.am b/crypto/heimdal/kadmin/Makefile.am
new file mode 100644
index 000000000000..2bafb5505dfd
--- /dev/null
+++ b/crypto/heimdal/kadmin/Makefile.am
@@ -0,0 +1,55 @@
+# $Id: Makefile.am,v 1.25 2000/01/06 08:04:13 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_readline) $(INCLUDE_krb4)
+
+sbin_PROGRAMS = kadmin
+
+libexec_PROGRAMS = kadmind
+
+kadmin_SOURCES = \
+ ank.c \
+ cpw.c \
+ del.c \
+ del_enctype.c \
+ dump.c \
+ ext.c \
+ get.c \
+ init.c \
+ kadmin.c \
+ load.c \
+ mod.c \
+ rename.c \
+ util.c \
+ random_password.c \
+ kadmin_locl.h
+
+if KRB4
+KRB4LIB = $(LIB_krb4)
+version4_c = version4.c
+endif
+
+kadmind_SOURCES = kadmind.c server.c kadmin_locl.h $(version4_c)
+
+EXTRA_kadmind_SOURCES = version4.c
+
+COMMON_LDADD = \
+ $(top_builddir)/lib/hdb/libhdb.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken) \
+ $(DBLIB)
+
+kadmind_LDADD = $(KRB4LIB) $(top_builddir)/lib/kadm5/libkadm5srv.la \
+ $(COMMON_LDADD) \
+ $(LIB_dlopen)
+
+kadmin_LDADD = \
+ $(top_builddir)/lib/kadm5/libkadm5clnt.la \
+ $(top_builddir)/lib/kadm5/libkadm5srv.la \
+ $(top_builddir)/lib/sl/libsl.la \
+ $(LIB_readline) \
+ $(COMMON_LDADD) \
+ $(LIB_dlopen)
diff --git a/crypto/heimdal/kadmin/Makefile.in b/crypto/heimdal/kadmin/Makefile.in
new file mode 100644
index 000000000000..b7fa7759df60
--- /dev/null
+++ b/crypto/heimdal/kadmin/Makefile.in
@@ -0,0 +1,702 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.25 2000/01/06 08:04:13 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_readline) $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+sbin_PROGRAMS = kadmin
+
+libexec_PROGRAMS = kadmind
+
+kadmin_SOURCES = ank.c cpw.c del.c del_enctype.c dump.c ext.c get.c init.c kadmin.c load.c mod.c rename.c util.c random_password.c kadmin_locl.h
+
+
+@KRB4_TRUE@KRB4LIB = $(LIB_krb4)
+@KRB4_TRUE@version4_c = version4.c
+
+kadmind_SOURCES = kadmind.c server.c kadmin_locl.h $(version4_c)
+
+EXTRA_kadmind_SOURCES = version4.c
+
+COMMON_LDADD = $(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken) $(DBLIB)
+
+
+kadmind_LDADD = $(KRB4LIB) $(top_builddir)/lib/kadm5/libkadm5srv.la $(COMMON_LDADD) $(LIB_dlopen)
+
+
+kadmin_LDADD = $(top_builddir)/lib/kadm5/libkadm5clnt.la $(top_builddir)/lib/kadm5/libkadm5srv.la $(top_builddir)/lib/sl/libsl.la $(LIB_readline) $(COMMON_LDADD) $(LIB_dlopen)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/config.h
+CONFIG_CLEAN_FILES =
+libexec_PROGRAMS = kadmind$(EXEEXT)
+sbin_PROGRAMS = kadmin$(EXEEXT)
+PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+@KRB4_TRUE@kadmind_OBJECTS = kadmind.$(OBJEXT) server.$(OBJEXT) \
+@KRB4_TRUE@version4.$(OBJEXT)
+@KRB4_FALSE@kadmind_OBJECTS = kadmind.$(OBJEXT) server.$(OBJEXT)
+@KRB4_TRUE@kadmind_DEPENDENCIES = \
+@KRB4_TRUE@$(top_builddir)/lib/kadm5/libkadm5srv.la \
+@KRB4_TRUE@$(top_builddir)/lib/hdb/libhdb.la \
+@KRB4_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@kadmind_DEPENDENCIES = \
+@KRB4_FALSE@$(top_builddir)/lib/kadm5/libkadm5srv.la \
+@KRB4_FALSE@$(top_builddir)/lib/hdb/libhdb.la \
+@KRB4_FALSE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+kadmind_LDFLAGS =
+kadmin_OBJECTS = ank.$(OBJEXT) cpw.$(OBJEXT) del.$(OBJEXT) \
+del_enctype.$(OBJEXT) dump.$(OBJEXT) ext.$(OBJEXT) get.$(OBJEXT) \
+init.$(OBJEXT) kadmin.$(OBJEXT) load.$(OBJEXT) mod.$(OBJEXT) \
+rename.$(OBJEXT) util.$(OBJEXT) random_password.$(OBJEXT)
+kadmin_DEPENDENCIES = $(top_builddir)/lib/kadm5/libkadm5clnt.la \
+$(top_builddir)/lib/kadm5/libkadm5srv.la \
+$(top_builddir)/lib/sl/libsl.la $(top_builddir)/lib/hdb/libhdb.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+kadmin_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(kadmind_SOURCES) $(EXTRA_kadmind_SOURCES) $(kadmin_SOURCES)
+OBJECTS = $(kadmind_OBJECTS) $(kadmin_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign kadmin/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libexecPROGRAMS:
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+
+distclean-libexecPROGRAMS:
+
+maintainer-clean-libexecPROGRAMS:
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-sbinPROGRAMS:
+
+clean-sbinPROGRAMS:
+ -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
+
+distclean-sbinPROGRAMS:
+
+maintainer-clean-sbinPROGRAMS:
+
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(sbindir)
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+kadmind$(EXEEXT): $(kadmind_OBJECTS) $(kadmind_DEPENDENCIES)
+ @rm -f kadmind$(EXEEXT)
+ $(LINK) $(kadmind_LDFLAGS) $(kadmind_OBJECTS) $(kadmind_LDADD) $(LIBS)
+
+kadmin$(EXEEXT): $(kadmin_OBJECTS) $(kadmin_DEPENDENCIES)
+ @rm -f kadmin$(EXEEXT)
+ $(LINK) $(kadmin_LDFLAGS) $(kadmin_OBJECTS) $(kadmin_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = kadmin
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libexecPROGRAMS install-sbinPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libexecPROGRAMS uninstall-sbinPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir) $(DESTDIR)$(sbindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libexecPROGRAMS mostlyclean-sbinPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libexecPROGRAMS clean-sbinPROGRAMS clean-compile \
+ clean-libtool clean-tags clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libexecPROGRAMS distclean-sbinPROGRAMS \
+ distclean-compile distclean-libtool distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libexecPROGRAMS \
+ maintainer-clean-sbinPROGRAMS maintainer-clean-compile \
+ maintainer-clean-libtool maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libexecPROGRAMS distclean-libexecPROGRAMS \
+clean-libexecPROGRAMS maintainer-clean-libexecPROGRAMS \
+uninstall-libexecPROGRAMS install-libexecPROGRAMS \
+mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS clean-sbinPROGRAMS \
+maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \
+install-sbinPROGRAMS mostlyclean-compile distclean-compile \
+clean-compile maintainer-clean-compile mostlyclean-libtool \
+distclean-libtool clean-libtool maintainer-clean-libtool tags \
+mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \
+distdir info-am info dvi-am dvi check-local check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-local install-data-am install-data install-am install \
+uninstall-am uninstall all-local all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/kadmin/ank.c b/crypto/heimdal/kadmin/ank.c
new file mode 100644
index 000000000000..7068912564cc
--- /dev/null
+++ b/crypto/heimdal/kadmin/ank.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: ank.c,v 1.19 1999/12/02 17:04:57 joda Exp $");
+
+/*
+ * fetch the default principal corresponding to `princ'
+ */
+
+static krb5_error_code
+get_default (kadm5_server_context *context,
+ krb5_principal princ,
+ kadm5_principal_ent_t default_ent)
+{
+ krb5_error_code ret;
+ krb5_principal def_principal;
+ krb5_realm *realm = krb5_princ_realm(context->context, princ);
+
+ ret = krb5_make_principal (context->context, &def_principal,
+ *realm, "default", NULL);
+ if (ret)
+ return ret;
+ ret = kadm5_get_principal (context, def_principal, default_ent,
+ KADM5_PRINCIPAL_NORMAL_MASK);
+ krb5_free_principal (context->context, def_principal);
+ return ret;
+}
+
+/*
+ * Add the principal `name' to the database.
+ * Prompt for all data not given by the input parameters.
+ */
+
+static krb5_error_code
+add_one_principal (const char *name,
+ int rand_key,
+ int rand_password,
+ char *password,
+ const char *max_ticket_life,
+ const char *max_renewable_life,
+ const char *attributes,
+ const char *expiration,
+ const char *pw_expiration)
+{
+ krb5_error_code ret;
+ kadm5_principal_ent_rec princ, defrec;
+ kadm5_principal_ent_rec *default_ent = NULL;
+ krb5_principal princ_ent = NULL;
+ int mask = 0;
+ int default_mask = 0;
+ char pwbuf[1024];
+
+ memset(&princ, 0, sizeof(princ));
+ ret = krb5_parse_name(context, name, &princ_ent);
+ if (ret) {
+ krb5_warn(context, ret, "krb5_parse_name");
+ return ret;
+ }
+ princ.principal = princ_ent;
+ mask |= KADM5_PRINCIPAL;
+
+ ret = set_entry(context, &princ, &mask,
+ max_ticket_life, max_renewable_life,
+ expiration, pw_expiration, attributes);
+ if (ret)
+ goto out;
+
+ default_ent = &defrec;
+ ret = get_default (kadm_handle, princ_ent, default_ent);
+ if (ret) {
+ default_ent = NULL;
+ default_mask = 0;
+ } else {
+ default_mask = KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
+ KADM5_PRINC_EXPIRE_TIME | KADM5_PW_EXPIRATION;
+ }
+
+ edit_entry(&princ, &mask, default_ent, default_mask);
+ if(rand_key) {
+ princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
+ mask |= KADM5_ATTRIBUTES;
+ strlcpy (pwbuf, "hemlig", sizeof(pwbuf));
+ password = pwbuf;
+ } else if (rand_password) {
+ random_password (pwbuf, sizeof(pwbuf));
+ password = pwbuf;
+ } else if(password == NULL) {
+ char *princ_name;
+ char *prompt;
+
+ krb5_unparse_name(context, princ_ent, &princ_name);
+ asprintf (&prompt, "%s's Password: ", princ_name);
+ free (princ_name);
+ ret = des_read_pw_string (pwbuf, sizeof(pwbuf), prompt, 1);
+ free (prompt);
+ if (ret)
+ goto out;
+ password = pwbuf;
+ }
+
+ ret = kadm5_create_principal(kadm_handle, &princ, mask, password);
+ if(ret)
+ krb5_warn(context, ret, "kadm5_create_principal");
+ if(rand_key) {
+ krb5_keyblock *new_keys;
+ int n_keys, i;
+ ret = kadm5_randkey_principal(kadm_handle, princ_ent,
+ &new_keys, &n_keys);
+ if(ret){
+ krb5_warn(context, ret, "kadm5_randkey_principal");
+ n_keys = 0;
+ }
+ for(i = 0; i < n_keys; i++)
+ krb5_free_keyblock_contents(context, &new_keys[i]);
+ free(new_keys);
+ kadm5_get_principal(kadm_handle, princ_ent, &princ,
+ KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES);
+ princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
+ princ.kvno = 1;
+ kadm5_modify_principal(kadm_handle, &princ,
+ KADM5_ATTRIBUTES | KADM5_KVNO);
+ kadm5_free_principal_ent(kadm_handle, &princ);
+ } else if (rand_password) {
+ char *princ_name;
+
+ krb5_unparse_name(context, princ_ent, &princ_name);
+ printf ("added %s with password `%s'\n", princ_name, password);
+ free (princ_name);
+ }
+out:
+ if (princ_ent)
+ krb5_free_principal (context, princ_ent);
+ if(default_ent)
+ kadm5_free_principal_ent (context, default_ent);
+ if (password != NULL)
+ memset (password, 0, strlen(password));
+ return ret;
+}
+
+/*
+ * the ank command
+ */
+
+static struct getargs args[] = {
+ { "random-key", 'r', arg_flag, NULL, "set random key" },
+ { "random-password", 0, arg_flag, NULL, "set random password" },
+ { "password", 'p', arg_string, NULL, "princial's password" },
+ { "max-ticket-life", 0, arg_string, NULL, "max ticket lifetime",
+ "lifetime"},
+ { "max-renewable-life", 0, arg_string, NULL,
+ "max renewable lifetime", "lifetime" },
+ { "attributes", 0, arg_string, NULL, "principal attributes",
+ "attributes"},
+ { "expiration-time",0, arg_string, NULL, "Expiration time",
+ "time"},
+ { "pw-expiration-time", 0, arg_string, NULL,
+ "Password expiration time", "time"}
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(void)
+{
+ arg_printusage (args, num_args, "ank", "principal");
+}
+
+/*
+ * Parse arguments and add all the principals.
+ */
+
+int
+add_new_key(int argc, char **argv)
+{
+ char *password = NULL;
+ int random_key = 0;
+ int random_password = 0;
+ int optind = 0;
+ krb5_error_code ret;
+ char *max_ticket_life = NULL;
+ char *max_renewable_life = NULL;
+ char *attributes = NULL;
+ char *expiration = NULL;
+ char *pw_expiration = NULL;
+ int i;
+ int num;
+
+ args[0].value = &random_key;
+ args[1].value = &random_password;
+ args[2].value = &password;
+ args[3].value = &max_ticket_life;
+ args[4].value = &max_renewable_life;
+ args[5].value = &attributes;
+ args[6].value = &expiration;
+ args[7].value = &pw_expiration;
+
+ if(getarg(args, num_args, argc, argv, &optind)) {
+ usage ();
+ return 0;
+ }
+ if(optind == argc) {
+ usage ();
+ return 0;
+ }
+
+ num = 0;
+ if (random_key)
+ ++num;
+ if (random_password)
+ ++num;
+ if (password)
+ ++num;
+
+ if (num > 1) {
+ printf ("give only one of "
+ "--random-key, --random-password, --password\n");
+ return 0;
+ }
+
+ for (i = optind; i < argc; ++i) {
+ ret = add_one_principal (argv[i], random_key, random_password,
+ password,
+ max_ticket_life,
+ max_renewable_life,
+ attributes,
+ expiration,
+ pw_expiration);
+ if (ret) {
+ krb5_warn (context, ret, "adding %s", argv[i]);
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/cpw.c b/crypto/heimdal/kadmin/cpw.c
new file mode 100644
index 000000000000..2bd71a7f02b3
--- /dev/null
+++ b/crypto/heimdal/kadmin/cpw.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: cpw.c,v 1.9 1999/12/02 17:04:57 joda Exp $");
+
+struct cpw_entry_data {
+ int random_key;
+ int random_password;
+ char *password;
+};
+
+static struct getargs args[] = {
+ { "random-key", 'r', arg_flag, NULL, "set random key" },
+ { "random-password", 0, arg_flag, NULL, "set random password" },
+ { "password", 'p', arg_string, NULL, "princial's password" },
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(void)
+{
+ arg_printusage(args, num_args, "cpw", "principal...");
+}
+
+static int
+set_random_key (krb5_principal principal)
+{
+ krb5_error_code ret;
+ int i;
+ krb5_keyblock *keys;
+ int num_keys;
+
+ ret = kadm5_randkey_principal(kadm_handle, principal, &keys, &num_keys);
+ if(ret)
+ return ret;
+ for(i = 0; i < num_keys; i++)
+ krb5_free_keyblock_contents(context, &keys[i]);
+ free(keys);
+ return 0;
+}
+
+static int
+set_random_password (krb5_principal principal)
+{
+ krb5_error_code ret;
+ char pw[128];
+
+ random_password (pw, sizeof(pw));
+ ret = kadm5_chpass_principal(kadm_handle, principal, pw);
+ if (ret == 0) {
+ char *princ_name;
+
+ krb5_unparse_name(context, principal, &princ_name);
+
+ printf ("%s's password set to `%s'\n", princ_name, pw);
+ free (princ_name);
+ }
+ memset (pw, 0, sizeof(pw));
+ return ret;
+}
+
+static int
+set_password (krb5_principal principal, char *password)
+{
+ krb5_error_code ret = 0;
+ char pwbuf[128];
+
+ if(password == NULL) {
+ char *princ_name;
+ char *prompt;
+
+ krb5_unparse_name(context, principal, &princ_name);
+ asprintf(&prompt, "%s's Password: ", princ_name);
+ free (princ_name);
+ ret = des_read_pw_string(pwbuf, sizeof(pwbuf), prompt, 1);
+ free (prompt);
+ if(ret){
+ return 0; /* XXX error code? */
+ }
+ password = pwbuf;
+ }
+ if(ret == 0)
+ ret = kadm5_chpass_principal(kadm_handle, principal, password);
+ memset(pwbuf, 0, sizeof(pwbuf));
+ return ret;
+}
+
+static int
+do_cpw_entry(krb5_principal principal, void *data)
+{
+ struct cpw_entry_data *e = data;
+
+ if (e->random_key)
+ return set_random_key (principal);
+ else if (e->random_password)
+ return set_random_password (principal);
+ else
+ return set_password (principal, e->password);
+}
+
+int
+cpw_entry(int argc, char **argv)
+{
+ krb5_error_code ret;
+ int i;
+ int optind = 0;
+ struct cpw_entry_data data;
+ int num;
+
+ data.random_key = 0;
+ data.random_password = 0;
+ data.password = NULL;
+
+ args[0].value = &data.random_key;
+ args[1].value = &data.random_password;
+ args[2].value = &data.password;
+ if(getarg(args, num_args, argc, argv, &optind)){
+ usage();
+ return 0;
+ }
+
+ num = 0;
+ if (data.random_key)
+ ++num;
+ if (data.random_password)
+ ++num;
+ if (data.password)
+ ++num;
+
+ if (num > 1) {
+ printf ("give only one of "
+ "--random-key, --random-password, --password\n");
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ for(i = 0; i < argc; i++)
+ ret = foreach_principal(argv[i], do_cpw_entry, &data);
+
+ return 0;
+}
+
diff --git a/crypto/heimdal/kadmin/del.c b/crypto/heimdal/kadmin/del.c
new file mode 100644
index 000000000000..39ee24e3b556
--- /dev/null
+++ b/crypto/heimdal/kadmin/del.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: del.c,v 1.4 1999/12/02 17:04:58 joda Exp $");
+
+static int
+do_del_entry(krb5_principal principal, void *data)
+{
+ return kadm5_delete_principal(kadm_handle, principal);
+}
+
+int
+del_entry(int argc, char **argv)
+{
+ int i;
+ krb5_error_code ret;
+
+ for(i = 1; i < argc; i++)
+ ret = foreach_principal(argv[i], do_del_entry, NULL);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/del_enctype.c b/crypto/heimdal/kadmin/del_enctype.c
new file mode 100644
index 000000000000..d772b65211f7
--- /dev/null
+++ b/crypto/heimdal/kadmin/del_enctype.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: del_enctype.c,v 1.4 1999/12/14 02:37:49 assar Exp $");
+
+static void
+usage(void)
+{
+ fprintf (stderr, "Usage: del_enctype principal enctypes...\n");
+}
+
+/*
+ * del_enctype principal enctypes...
+ */
+
+int
+del_enctype(int argc, char **argv)
+{
+ kadm5_principal_ent_rec princ;
+ krb5_principal princ_ent = NULL;
+ krb5_error_code ret;
+ const char *princ_name;
+ int i, j, k;
+ krb5_key_data *new_key_data;
+ int n_etypes;
+ krb5_enctype *etypes;
+
+ if (argc < 3) {
+ usage ();
+ return 0;
+ }
+
+ memset (&princ, 0, sizeof(princ));
+ princ_name = argv[1];
+ n_etypes = argc - 2;
+ etypes = malloc (n_etypes * sizeof(*etypes));
+ if (etypes == NULL) {
+ krb5_warnx (context, "out of memory");
+ return 0;
+ }
+ for (i = 0; i < n_etypes; ++i) {
+ ret = krb5_string_to_enctype (context, argv[i + 2], &etypes[i]);
+ if (ret) {
+ krb5_warnx (context, "bad enctype `%s'", argv[i + 2]);
+ goto out2;
+ }
+ }
+
+ ret = krb5_parse_name(context, princ_name, &princ_ent);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_parse_name %s", princ_name);
+ goto out2;
+ }
+
+ ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
+ KADM5_PRINCIPAL | KADM5_KEY_DATA);
+ if (ret) {
+ krb5_free_principal (context, princ_ent);
+ krb5_warnx (context, "no such principal: %s", princ_name);
+ goto out2;
+ }
+
+ new_key_data = malloc(princ.n_key_data * sizeof(*new_key_data));
+ if (new_key_data == NULL) {
+ krb5_warnx (context, "out of memory");
+ goto out;
+ }
+
+ for (i = 0, j = 0; i < princ.n_key_data; ++i) {
+ krb5_key_data *key = &princ.key_data[i];
+ int docopy = 1;
+
+ for (k = 0; k < n_etypes; ++k)
+ if (etypes[k] == key->key_data_type[0]) {
+ docopy = 0;
+ break;
+ }
+ if (docopy) {
+ new_key_data[j++] = *key;
+ } else {
+ int16_t ignore;
+
+ kadm5_free_key_data (kadm_handle, &ignore, key);
+ }
+ }
+
+ free (princ.key_data);
+ princ.n_key_data = j;
+ princ.key_data = new_key_data;
+
+ ret = kadm5_modify_principal (kadm_handle, &princ, KADM5_KEY_DATA);
+ if (ret)
+ krb5_warn(context, ret, "kadm5_modify_principal");
+out:
+ krb5_free_principal (context, princ_ent);
+ kadm5_free_principal_ent(kadm_handle, &princ);
+out2:
+ free (etypes);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/dump.c b/crypto/heimdal/kadmin/dump.c
new file mode 100644
index 000000000000..a57309c593c3
--- /dev/null
+++ b/crypto/heimdal/kadmin/dump.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+#include <kadm5/private.h>
+
+RCSID("$Id: dump.c,v 1.26 1999/12/02 17:04:58 joda Exp $");
+
+int
+dump(int argc, char **argv)
+{
+ krb5_error_code ret;
+ FILE *f;
+ HDB *db = _kadm5_s_get_db(kadm_handle);
+ int decrypt = 0;
+ int optind = 0;
+
+ struct getargs args[] = {
+ { "decrypt", 'd', arg_flag, NULL, "decrypt keys" }
+ };
+ args[0].value = &decrypt;
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) {
+ arg_printusage(args, sizeof(args) / sizeof(args[0]), "kadmin dump",
+ "[dump-file]");
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+ if(argc < 1)
+ f = stdout;
+ else
+ f = fopen(argv[0], "w");
+
+ ret = db->open(context, db, O_RDONLY, 0600);
+ if(ret){
+ krb5_warn(context, ret, "hdb_open");
+ if(f != stdout)
+ fclose(f);
+ return 0;
+ }
+
+ hdb_foreach(context, db, decrypt ? HDB_F_DECRYPT : 0, hdb_print_entry, f);
+
+ if(f != stdout)
+ fclose(f);
+ db->close(context, db);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/ext.c b/crypto/heimdal/kadmin/ext.c
new file mode 100644
index 000000000000..9d2be170e99e
--- /dev/null
+++ b/crypto/heimdal/kadmin/ext.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: ext.c,v 1.5 2000/01/02 03:58:02 assar Exp $");
+
+struct ext_keytab_data {
+ krb5_keytab keytab;
+};
+
+static struct getargs args[] = {
+ { "keytab", 'k', arg_string, NULL, "keytab to use" },
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(void)
+{
+ arg_printusage(args, num_args, "ext", "principal...");
+}
+
+static int
+do_ext_keytab(krb5_principal principal, void *data)
+{
+ krb5_error_code ret;
+ int i;
+ kadm5_principal_ent_rec princ;
+ struct ext_keytab_data *e = data;
+
+ ret = kadm5_get_principal(kadm_handle, principal, &princ,
+ KADM5_PRINCIPAL|KADM5_KVNO|KADM5_KEY_DATA);
+ if(ret)
+ return ret;
+ for(i = 0; i < princ.n_key_data; i++){
+ krb5_keytab_entry key;
+ krb5_key_data *k = &princ.key_data[i];
+ key.principal = princ.principal;
+ key.vno = k->key_data_kvno;
+ key.keyblock.keytype = k->key_data_type[0];
+ key.keyblock.keyvalue.length = k->key_data_length[0];
+ key.keyblock.keyvalue.data = k->key_data_contents[0];
+ key.timestamp = time(NULL);
+ ret = krb5_kt_add_entry(context, e->keytab, &key);
+ if(ret)
+ krb5_warn(context, ret, "krb5_kt_add_entry");
+ }
+ kadm5_free_principal_ent(kadm_handle, &princ);
+ return 0;
+}
+
+int
+ext_keytab(int argc, char **argv)
+{
+ krb5_error_code ret;
+ int i;
+ int optind = 0;
+ char *keytab = NULL;
+ struct ext_keytab_data data;
+
+ args[0].value = &keytab;
+ if(getarg(args, num_args, argc, argv, &optind)){
+ usage();
+ return 0;
+ }
+ if(keytab)
+ ret = krb5_kt_resolve(context, keytab, &data.keytab);
+ else
+ ret = krb5_kt_default(context, &data.keytab);
+ if(ret){
+ krb5_warn(context, ret, "krb5_kt_resolve");
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ for(i = 0; i < argc; i++)
+ foreach_principal(argv[i], do_ext_keytab, &data);
+
+ krb5_kt_close(context, data.keytab);
+
+ return 0;
+}
+
diff --git a/crypto/heimdal/kadmin/get.c b/crypto/heimdal/kadmin/get.c
new file mode 100644
index 000000000000..1492ca959b0a
--- /dev/null
+++ b/crypto/heimdal/kadmin/get.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+#include <parse_units.h>
+
+RCSID("$Id: get.c,v 1.8 1999/12/02 17:04:58 joda Exp $");
+
+struct get_entry_data {
+ void (*header)(void);
+ void (*format)(kadm5_principal_ent_t);
+};
+
+static void
+print_entry_terse(kadm5_principal_ent_t princ)
+{
+ char *p;
+ krb5_unparse_name(context, princ->principal, &p);
+ printf(" %s\n", p);
+ free(p);
+}
+
+static void
+print_header_short(void)
+{
+ printf("%-20s ", "Principal");
+
+ printf("%-10s ", "Expires");
+
+ printf("%-10s ", "PW-exp");
+
+ printf("%-10s ", "PW-change");
+
+ printf("%-9s ", "Max life");
+
+ printf("%-9s ", "Max renew");
+
+ printf("\n");
+}
+
+static void
+print_entry_short(kadm5_principal_ent_t princ)
+{
+ char buf[1024];
+
+ krb5_unparse_name_fixed_short(context, princ->principal, buf, sizeof(buf));
+ printf("%-20s ", buf);
+
+ time_t2str(princ->princ_expire_time, buf, sizeof(buf), 0);
+ printf("%-10s ", buf);
+
+ time_t2str(princ->pw_expiration, buf, sizeof(buf), 0);
+ printf("%-10s ", buf);
+
+ time_t2str(princ->last_pwd_change, buf, sizeof(buf), 0);
+ printf("%-10s ", buf);
+
+ deltat2str(princ->max_life, buf, sizeof(buf));
+ printf("%-9s ", buf);
+
+ deltat2str(princ->max_renewable_life, buf, sizeof(buf));
+ printf("%-9s ", buf);
+
+#if 0
+ time_t2str(princ->mod_date, buf, sizeof(buf), 0);
+ printf("%-10s ", buf);
+
+ krb5_unparse_name_fixed(context, princ->mod_name, buf, sizeof(buf));
+ printf("%-24s", buf);
+#endif
+
+ printf("\n");
+}
+
+static void
+print_entry_long(kadm5_principal_ent_t princ)
+{
+ char buf[1024];
+ int i;
+
+ krb5_unparse_name_fixed(context, princ->principal, buf, sizeof(buf));
+ printf("%24s: %s\n", "Principal", buf);
+ time_t2str(princ->princ_expire_time, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Principal expires", buf);
+
+ time_t2str(princ->pw_expiration, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Password expires", buf);
+
+ time_t2str(princ->last_pwd_change, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Last password change", buf);
+
+ deltat2str(princ->max_life, buf, sizeof(buf));
+ printf("%24s: %s\n", "Max ticket life", buf);
+
+ deltat2str(princ->max_renewable_life, buf, sizeof(buf));
+ printf("%24s: %s\n", "Max renewable life", buf);
+ printf("%24s: %d\n", "Kvno", princ->kvno);
+ printf("%24s: %d\n", "Mkvno", princ->mkvno);
+ printf("%24s: %s\n", "Policy", princ->policy ? princ->policy : "none");
+ time_t2str(princ->last_success, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Last successful login", buf);
+ time_t2str(princ->last_failed, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Last failed login", buf);
+ printf("%24s: %d\n", "Failed login count", princ->fail_auth_count);
+ time_t2str(princ->mod_date, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Last modified", buf);
+ krb5_unparse_name_fixed(context, princ->mod_name, buf, sizeof(buf));
+ printf("%24s: %s\n", "Modifier", buf);
+ attributes2str (princ->attributes, buf, sizeof(buf));
+ printf("%24s: %s\n", "Attributes", buf);
+
+ printf("%24s: ", "Keytypes(salts)");
+
+ for (i = 0; i < princ->n_key_data; ++i) {
+ krb5_key_data *k = &princ->key_data[i];
+ krb5_error_code ret;
+ char *e_string, *s_string;
+
+ ret = krb5_enctype_to_string (context,
+ k->key_data_type[0],
+ &e_string);
+ if (ret)
+ asprintf (&e_string, "unknown(%d)", k->key_data_type[0]);
+
+ ret = krb5_salttype_to_string (context,
+ k->key_data_type[0],
+ k->key_data_type[1],
+ &s_string);
+ if (ret)
+ asprintf (&s_string, "unknown(%d)", k->key_data_type[1]);
+
+ printf ("%s%s(%s)", (i != 0) ? ", " : "", e_string, s_string);
+ free (e_string);
+ free (s_string);
+ }
+ printf("\n\n");
+}
+
+static int
+do_get_entry(krb5_principal principal, void *data)
+{
+ kadm5_principal_ent_rec princ;
+ krb5_error_code ret;
+ struct get_entry_data *e = data;
+
+ memset(&princ, 0, sizeof(princ));
+ ret = kadm5_get_principal(kadm_handle, principal,
+ &princ,
+ KADM5_PRINCIPAL_NORMAL_MASK|KADM5_KEY_DATA);
+ if(ret)
+ return ret;
+ else {
+ if(e->header) {
+ (*e->header)();
+ e->header = NULL; /* XXX only once */
+ }
+ (e->format)(&princ);
+ kadm5_free_principal_ent(kadm_handle, &princ);
+ }
+ return 0;
+}
+
+int
+get_entry(int argc, char **argv)
+{
+ int i;
+ krb5_error_code ret;
+ struct get_entry_data data;
+ struct getargs args[] = {
+ { "long", 'l', arg_flag, NULL, "long format" },
+ { "terse", 't', arg_flag, NULL, "terse format" },
+ };
+ int num_args = sizeof(args) / sizeof(args[0]);
+ int optind = 0;
+ int long_flag = 0;
+ int terse_flag = 0;
+
+ args[0].value = &long_flag;
+ args[1].value = &terse_flag;
+ if(getarg(args, num_args, argc, argv, &optind))
+ goto usage;
+ if(optind == argc)
+ goto usage;
+
+ if(long_flag) {
+ data.format = print_entry_long;
+ data.header = NULL;
+ } else if(terse_flag) {
+ data.format = print_entry_terse;
+ data.header = NULL;
+ } else {
+ data.format = print_entry_short;
+ data.header = print_header_short;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ for(i = 0; i < argc; i++)
+ ret = foreach_principal(argv[i], do_get_entry, &data);
+ return 0;
+usage:
+ arg_printusage (args, num_args, "get", "principal...");
+ return 0;
+}
+
+int
+list_princs(int argc, char **argv)
+{
+ int i;
+ krb5_error_code ret;
+ struct get_entry_data data;
+
+ data.format = print_entry_terse;
+ data.header = NULL;
+
+ for(i = 1; i < argc; i++)
+ ret = foreach_principal(argv[i], do_get_entry, &data);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/init.c b/crypto/heimdal/kadmin/init.c
new file mode 100644
index 000000000000..b88913121c24
--- /dev/null
+++ b/crypto/heimdal/kadmin/init.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+#include <kadm5/private.h>
+
+RCSID("$Id: init.c,v 1.23 1999/12/02 17:04:58 joda Exp $");
+
+static kadm5_ret_t
+create_random_entry(krb5_principal princ,
+ unsigned max_life,
+ unsigned max_rlife,
+ u_int32_t attributes)
+{
+ kadm5_principal_ent_rec ent;
+ kadm5_ret_t ret;
+ int mask = 0;
+ krb5_keyblock *keys;
+ int n_keys, i;
+
+ memset(&ent, 0, sizeof(ent));
+ ent.principal = princ;
+ mask |= KADM5_PRINCIPAL;
+ if (max_life) {
+ ent.max_life = max_life;
+ mask |= KADM5_MAX_LIFE;
+ }
+ if (max_rlife) {
+ ent.max_renewable_life = max_rlife;
+ mask |= KADM5_MAX_RLIFE;
+ }
+ ent.attributes |= attributes | KRB5_KDB_DISALLOW_ALL_TIX;
+ mask |= KADM5_ATTRIBUTES;
+
+ ret = kadm5_create_principal(kadm_handle, &ent, mask, "hemlig");
+ if(ret)
+ return ret;
+ ret = kadm5_randkey_principal(kadm_handle, princ, &keys, &n_keys);
+ if(ret)
+ return ret;
+ for(i = 0; i < n_keys; i++)
+ krb5_free_keyblock_contents(context, &keys[i]);
+ free(keys);
+ ret = kadm5_get_principal(kadm_handle, princ, &ent,
+ KADM5_PRINCIPAL | KADM5_ATTRIBUTES);
+ if(ret)
+ return ret;
+ ent.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
+ ent.kvno = 1;
+ ret = kadm5_modify_principal(kadm_handle, &ent,
+ KADM5_ATTRIBUTES|KADM5_KVNO);
+ kadm5_free_principal_ent (kadm_handle, &ent);
+ if(ret)
+ return ret;
+ return 0;
+}
+
+static struct getargs args[] = {
+ { "realm-max-ticket-life", 0, arg_string, NULL,
+ "realm max ticket lifetime" },
+ { "realm-max-renewable-life", 0, arg_string, NULL,
+ "realm max renewable lifetime" },
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(void)
+{
+ arg_printusage (args, num_args, "ank", "principal");
+}
+
+int
+init(int argc, char **argv)
+{
+ kadm5_ret_t ret;
+ int i;
+ char *realm_max_life = NULL;
+ char *realm_max_rlife = NULL;
+ HDB *db;
+ int optind = 0;
+ krb5_deltat max_life, max_rlife;
+
+ args[0].value = &realm_max_life;
+ args[1].value = &realm_max_rlife;
+
+ if(getarg(args, num_args, argc, argv, &optind)) {
+ usage();
+ return 0;
+ }
+
+ if (realm_max_life) {
+ if (str2deltat (realm_max_life, &max_life) != 0) {
+ krb5_warnx (context, "unable to parse `%s'", realm_max_life);
+ return 0;
+ }
+ }
+ if (realm_max_rlife) {
+ if (str2deltat (realm_max_rlife, &max_rlife) != 0) {
+ krb5_warnx (context, "unable to parse `%s'", realm_max_rlife);
+ return 0;
+ }
+ }
+
+ db = _kadm5_s_get_db(kadm_handle);
+
+ ret = db->open(context, db, O_RDWR | O_CREAT, 0600);
+ if(ret){
+ krb5_warn(context, ret, "hdb_open");
+ return 0;
+ }
+ db->close(context, db);
+ for(i = optind; i < argc; i++){
+ krb5_principal princ;
+ const char *realm = argv[i];
+
+ /* Create `krbtgt/REALM' */
+ krb5_make_principal(context, &princ, realm, "krbtgt", realm, NULL);
+ if (realm_max_life == NULL) {
+ max_life = 0;
+ edit_deltat ("Realm max ticket life", &max_life, NULL, 0);
+ }
+ if (realm_max_rlife == NULL) {
+ max_rlife = 0;
+ edit_deltat("Realm max renewable ticket life", &max_rlife,
+ NULL, 0);
+ }
+ create_random_entry(princ, max_life, max_rlife, 0);
+ krb5_free_principal(context, princ);
+
+ /* Create `kadmin/changepw' */
+ krb5_make_principal(context, &princ, realm,
+ "kadmin", "changepw", NULL);
+ create_random_entry(princ, 5*60, 5*60,
+ KRB5_KDB_DISALLOW_TGT_BASED|
+ KRB5_KDB_PWCHANGE_SERVICE|
+ KRB5_KDB_DISALLOW_POSTDATED|
+ KRB5_KDB_DISALLOW_FORWARDABLE|
+ KRB5_KDB_DISALLOW_RENEWABLE|
+ KRB5_KDB_DISALLOW_PROXIABLE|
+ KRB5_KDB_REQUIRES_PRE_AUTH);
+ krb5_free_principal(context, princ);
+
+ /* Create `kadmin/admin' */
+ krb5_make_principal(context, &princ, realm,
+ "kadmin", "admin", NULL);
+ create_random_entry(princ, 60*60, 60*60, KRB5_KDB_REQUIRES_PRE_AUTH);
+ krb5_free_principal(context, princ);
+
+ /* Create `changepw/kerberos' (for v4 compat) */
+ krb5_make_principal(context, &princ, realm,
+ "changepw", "kerberos", NULL);
+ create_random_entry(princ, 60*60, 60*60, 0);
+ krb5_free_principal(context, princ);
+
+ /* Create `default' */
+ {
+ kadm5_principal_ent_rec ent;
+ int mask = 0;
+
+ memset (&ent, 0, sizeof(ent));
+ mask |= KADM5_PRINCIPAL;
+ krb5_make_principal(context, &ent.principal, realm,
+ "default", NULL);
+ mask |= KADM5_MAX_LIFE;
+ ent.max_life = 24 * 60 * 60;
+ mask |= KADM5_MAX_RLIFE;
+ ent.max_renewable_life = 7 * ent.max_life;
+ ent.attributes = KRB5_KDB_DISALLOW_ALL_TIX;
+ mask |= KADM5_ATTRIBUTES;
+
+ ret = kadm5_create_principal(kadm_handle, &ent, mask, "");
+ if (ret)
+ krb5_err (context, 1, ret, "kadm5_create_principal");
+
+ krb5_free_principal(context, ent.principal);
+ }
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/kadmin.c b/crypto/heimdal/kadmin/kadmin.c
new file mode 100644
index 000000000000..9172d6e48544
--- /dev/null
+++ b/crypto/heimdal/kadmin/kadmin.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+#include <sl.h>
+
+RCSID("$Id: kadmin.c,v 1.26 1999/12/02 17:04:58 joda Exp $");
+
+static char *config_file;
+static char *keyfile;
+static int local_flag;
+static int help_flag;
+static int version_flag;
+static char *realm;
+static char *admin_server;
+static int server_port = 0;
+static char *client_name;
+
+static struct getargs args[] = {
+ { "principal", 'p', arg_string, &client_name,
+ "principal to authenticate as" },
+ {
+ "config-file", 'c', arg_string, &config_file,
+ "location of config file", "file"
+ },
+ {
+ "key-file", 'k', arg_string, &keyfile,
+ "location of master key file", "file"
+ },
+ {
+ "realm", 'r', arg_string, &realm,
+ "realm to use", "realm"
+ },
+ {
+ "admin-server", 'a', arg_string, &admin_server,
+ "server to contact", "host"
+ },
+ {
+ "server-port", 's', arg_integer, &server_port,
+ "server to contact", "port number"
+ },
+ { "local", 'l', arg_flag, &local_flag, "local admin mode" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 'v', arg_flag, &version_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static SL_cmd commands[] = {
+ /* commands that are only available with `-l' */
+ {
+ "dump", dump, "dump [file]",
+ "Dumps the database in a human readable format to the\n"
+ "specified file, or the standard out."
+ },
+ {
+ "load", load, "load file",
+ "Loads a previously dumped file."
+ },
+ {
+ "merge", merge, "merge file" ,
+ "Merges the contents of a dump file into the database."
+ },
+ {
+ "init", init, "init realm...",
+ "Initializes the default principals for a realm.\n"
+ "Creates the database if necessary."
+ },
+ /* common commands */
+ {
+ "add", add_new_key, "add principal" ,
+ "Adds a principal to the database."
+ },
+ { "add_new_key"},
+ { "ank"},
+ {
+ "passwd", cpw_entry, "passwd expression..." ,
+ "Changes the password of one or more principals\n"
+ "matching the expressions."
+ },
+ { "change_password"},
+ { "cpw"},
+ {
+ "delete", del_entry, "delete expression...",
+ "Deletes all principals matching the expressions."
+ },
+ { "del_entry" },
+ {
+ "del_enctype", del_enctype, "del_enctype principal enctype...",
+ "Delete all the mentioned enctypes for principal."
+ },
+ {
+ "ext_keytab", ext_keytab, "ext_keytab expression...",
+ "Extracts the keys of all principals matching the expressions,\n"
+ "and stores them in a keytab."
+ },
+ {
+ "get", get_entry, "get expression...",
+ "Shows information about principals matching the expressions."
+ },
+ { "get_entry" },
+ {
+ "rename", rename_entry, "rename source target",
+ "Renames `source' to `target'."
+ },
+ {
+ "modify", mod_entry, "modify principal",
+ "Modifies some attributes of the specified principal."
+ },
+ {
+ "privileges", get_privs, "privileges",
+ "Shows which kinds of operations you are allowed to perform."
+ },
+ {
+ "list", list_princs, "list expression...",
+ "Lists principals in a terse format. The same as `get -t'."
+ },
+ { "help", help, "help"},
+ { "?"},
+ { "exit", exit_kadmin, "exit"},
+ { NULL}
+};
+
+krb5_context context;
+void *kadm_handle;
+
+int
+help(int argc, char **argv)
+{
+ sl_help(commands, argc, argv);
+ return 0;
+}
+
+int
+exit_kadmin (int argc, char **argv)
+{
+ return 1;
+}
+
+static void
+usage(int ret)
+{
+ arg_printusage (args, num_args, NULL, "[command]");
+ exit (ret);
+}
+
+int
+get_privs(int argc, char **argv)
+{
+ u_int32_t privs;
+ char str[128];
+ kadm5_ret_t ret;
+
+ ret = kadm5_get_privs(kadm_handle, &privs);
+ if(ret)
+ krb5_warn(context, ret, "kadm5_get_privs");
+ else{
+ ret =_kadm5_privs_to_string(privs, str, sizeof(str));
+ printf("%s\n", str);
+ }
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_config_section *cf = NULL;
+ kadm5_config_params conf;
+ int optind = 0;
+ int e;
+ SL_cmd *cmd;
+
+ set_progname(argv[0]);
+
+ krb5_init_context(&context);
+
+ while((e = getarg(args, num_args, argc, argv, &optind)))
+ warnx("error at argument `%s'", argv[optind]);
+
+ if (help_flag)
+ usage (0);
+
+ if (version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (config_file == NULL)
+ config_file = HDB_DB_DIR "/kdc.conf";
+
+ if(krb5_config_parse_file(config_file, &cf) == 0) {
+ const char *p = krb5_config_get_string (context, cf,
+ "kdc", "key-file", NULL);
+ if (p)
+ keyfile = strdup(p);
+ }
+
+ memset(&conf, 0, sizeof(conf));
+ if(realm) {
+ krb5_set_default_realm(context, realm); /* XXX should be fixed
+ some other way */
+ conf.realm = realm;
+ conf.mask |= KADM5_CONFIG_REALM;
+ }
+
+ if (admin_server) {
+ conf.admin_server = admin_server;
+ conf.mask |= KADM5_CONFIG_ADMIN_SERVER;
+ }
+
+ if (server_port) {
+ conf.kadmind_port = htons(server_port);
+ conf.mask |= KADM5_CONFIG_KADMIND_PORT;
+ }
+
+ if(local_flag){
+ ret = kadm5_s_init_with_password_ctx(context,
+ KADM5_ADMIN_SERVICE,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm_handle);
+ cmd = commands;
+ } else {
+ ret = kadm5_c_init_with_password_ctx(context,
+ client_name,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm_handle);
+ cmd = commands + 4; /* XXX */
+ }
+
+ if(ret)
+ krb5_err(context, 1, ret, "kadm5_init_with_password");
+ if (argc != 0) {
+ ret = sl_command (cmd, argc, argv);
+ if(ret == -1)
+ krb5_warnx (context, "unrecognized command: %s", argv[0]);
+ } else
+ ret = sl_loop (cmd, "kadmin> ") != 0;
+
+ kadm5_destroy(kadm_handle);
+ krb5_config_file_free (context, cf);
+ krb5_free_context(context);
+ return ret;
+}
diff --git a/crypto/heimdal/kadmin/kadmin_locl.h b/crypto/heimdal/kadmin/kadmin_locl.h
new file mode 100644
index 000000000000..240ca2c44947
--- /dev/null
+++ b/crypto/heimdal/kadmin/kadmin_locl.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*
+ * $Id: kadmin_locl.h,v 1.24 1999/12/02 17:04:58 joda Exp $
+ */
+
+#ifndef __ADMIN_LOCL_H__
+#define __ADMIN_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#include <err.h>
+#include <roken.h>
+#include <krb5.h>
+#include <hdb.h>
+#include <hdb_err.h>
+#include <kadm5/admin.h>
+#include <kadm5/private.h>
+#include <kadm5/kadm5_err.h>
+#include <parse_time.h>
+#include <getarg.h>
+
+
+extern krb5_context context;
+extern void * kadm_handle;
+
+#define DECL(X) int X(int, char **)
+
+DECL(add_new_key);
+DECL(cpw_entry);
+DECL(del_entry);
+DECL(del_enctype);
+DECL(exit_kadmin);
+DECL(ext_keytab);
+DECL(get_entry);
+DECL(get_privs);
+DECL(help);
+DECL(list_princs);
+DECL(mod_entry);
+DECL(rename_entry);
+DECL(init);
+DECL(dump);
+DECL(load);
+DECL(merge);
+
+#define ALLOC(X) ((X) = malloc(sizeof(*(X))))
+
+/* util.c */
+
+void attributes2str(krb5_flags attributes, char *str, size_t len);
+int str2attributes(const char *str, krb5_flags *flags);
+int parse_attributes (const char *resp, krb5_flags *attr, int *mask, int bit);
+int edit_attributes (const char *prompt, krb5_flags *attr, int *mask,
+ int bit);
+
+void time_t2str(time_t t, char *str, size_t len, int include_time);
+int str2time_t (const char *str, time_t *time);
+int parse_timet (const char *resp, krb5_timestamp *value, int *mask, int bit);
+int edit_timet (const char *prompt, krb5_timestamp *value, int *mask,
+ int bit);
+
+void deltat2str(unsigned t, char *str, size_t len);
+int str2deltat(const char *str, krb5_deltat *delta);
+int parse_deltat (const char *resp, krb5_deltat *value, int *mask, int bit);
+int edit_deltat (const char *prompt, krb5_deltat *value, int *mask, int bit);
+
+int edit_entry(kadm5_principal_ent_t ent, int *mask,
+ kadm5_principal_ent_t default_ent, int default_mask);
+int set_entry(krb5_context context,
+ kadm5_principal_ent_t ent,
+ int *mask,
+ const char *max_ticket_life,
+ const char *max_renewable_life,
+ const char *expiration,
+ const char *pw_expiration,
+ const char *attributes);
+int
+foreach_principal(const char *exp,
+ int (*func)(krb5_principal, void*),
+ void *data);
+
+void get_response(const char *prompt, const char *def, char *buf, size_t len);
+
+/* server.c */
+
+krb5_error_code
+kadmind_loop (krb5_context, krb5_auth_context, krb5_keytab, int);
+
+/* version4.c */
+
+void
+handle_v4(krb5_context context, int len, int fd);
+
+/* random_password.c */
+
+void
+random_password(char *pw, size_t len);
+
+#endif /* __ADMIN_LOCL_H__ */
diff --git a/crypto/heimdal/kadmin/kadmind.c b/crypto/heimdal/kadmin/kadmind.c
new file mode 100644
index 000000000000..4b4fb0dd4c82
--- /dev/null
+++ b/crypto/heimdal/kadmin/kadmind.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: kadmind.c,v 1.16 1999/12/02 17:04:58 joda Exp $");
+
+static char *config_file;
+static char *keyfile;
+static char *keytab_str = "HDB:";
+static int help_flag;
+static int version_flag;
+static int debug_flag;
+static int debug_port;
+char *realm;
+
+static struct getargs args[] = {
+ {
+ "config-file", 'c', arg_string, &config_file,
+ "location of config file", "file"
+ },
+ {
+ "key-file", 'k', arg_string, &keyfile,
+ "location of master key file", "file"
+ },
+ {
+ "keytab", 0, arg_string, &keytab_str,
+ "what keytab to use", "keytab"
+ },
+ { "realm", 'r', arg_string, &realm,
+ "realm to use", "realm"
+ },
+ { "debug", 'd', arg_flag, &debug_flag,
+ "enable debugging"
+ },
+ { "debug-port", 'p', arg_integer,&debug_port,
+ "port to use with debug", "port" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 'v', arg_flag, &version_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+krb5_context context;
+
+static void
+usage(int ret)
+{
+ arg_printusage (args, num_args, NULL, "");
+ exit (ret);
+}
+
+krb5_error_code
+kadmind_loop (krb5_context, krb5_auth_context, krb5_keytab, int);
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_config_section *cf;
+ int optind = 0;
+ int e;
+ krb5_log_facility *logf;
+ krb5_keytab keytab;
+
+ set_progname(argv[0]);
+
+ krb5_init_context(&context);
+
+ ret = krb5_openlog(context, "kadmind", &logf);
+ ret = krb5_set_warn_dest(context, logf);
+
+ while((e = getarg(args, num_args, argc, argv, &optind)))
+ warnx("error at argument `%s'", argv[optind]);
+
+ if (help_flag)
+ usage (0);
+
+ if (version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ ret = krb5_kt_register(context, &hdb_kt_ops);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_kt_register");
+
+ if (config_file == NULL)
+ config_file = HDB_DB_DIR "/kdc.conf";
+
+ if(krb5_config_parse_file(config_file, &cf) == 0) {
+ const char *p = krb5_config_get_string (context, cf,
+ "kdc", "key-file", NULL);
+ if (p)
+ keyfile = strdup(p);
+ }
+
+ ret = krb5_kt_resolve(context, keytab_str, &keytab);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_kt_resolve");
+
+ {
+ int fd = 0;
+ krb5_auth_context ac = NULL;
+ if(debug_flag){
+ if(debug_port == 0)
+ debug_port = krb5_getportbyname (context, "kerberos-adm",
+ "tcp", 749);
+ else
+ debug_port = htons(debug_port);
+ mini_inetd(debug_port);
+ }
+ if(realm)
+ krb5_set_default_realm(context, realm); /* XXX */
+ kadmind_loop(context, ac, keytab, fd);
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/load.c b/crypto/heimdal/kadmin/load.c
new file mode 100644
index 000000000000..5f9f2b7612ce
--- /dev/null
+++ b/crypto/heimdal/kadmin/load.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+#include <kadm5/private.h>
+
+RCSID("$Id: load.c,v 1.34 1999/12/02 17:04:58 joda Exp $");
+
+struct entry{
+ char *principal;
+ char *key;
+ char *max_life;
+ char *max_renew;
+ char *created;
+ char *modified;
+ char *valid_start;
+ char *valid_end;
+ char *pw_end;
+ char *flags;
+ char *etypes;
+};
+
+static char *
+skip_next(char *p)
+{
+ while(*p && !isspace((unsigned char)*p))
+ p++;
+ *p++ = 0;
+ while(*p && isspace((unsigned char)*p)) p++;
+ return p;
+}
+
+static time_t*
+parse_time_string(time_t *t, char *s)
+{
+ int year, month, date, hour, minute, second;
+ struct tm tm;
+ if(strcmp(s, "-") == 0)
+ return NULL;
+ if(t == NULL)
+ t = malloc(sizeof(*t));
+ sscanf(s, "%04d%02d%02d%02d%02d%02d",
+ &year, &month, &date, &hour, &minute, &second);
+ tm.tm_year = year - 1900;
+ tm.tm_mon = month - 1;
+ tm.tm_mday = date;
+ tm.tm_hour = hour;
+ tm.tm_min = minute;
+ tm.tm_sec = second;
+ tm.tm_isdst = 0;
+ *t = timegm(&tm);
+ return t;
+}
+
+static unsigned*
+parse_integer(unsigned *u, char *s)
+{
+ if(strcmp(s, "-") == 0)
+ return NULL;
+ if(u == NULL)
+ u = malloc(sizeof(*u));
+ sscanf(s, "%u", u);
+ return u;
+}
+
+static void
+parse_keys(hdb_entry *ent, char *str)
+{
+ int tmp;
+ char *p;
+ int i;
+
+ p = strsep(&str, ":");
+ sscanf(p, "%d", &tmp);
+ ent->kvno = tmp;
+ p = strsep(&str, ":");
+ while(p){
+ Key *key;
+ key = realloc(ent->keys.val,
+ (ent->keys.len + 1) * sizeof(*ent->keys.val));
+ if(key == NULL)
+ abort();
+ ent->keys.val = key;
+ key = ent->keys.val + ent->keys.len;
+ ent->keys.len++;
+ memset(key, 0, sizeof(*key));
+ if(sscanf(p, "%d", &tmp) == 1) {
+ key->mkvno = malloc(sizeof(*key->mkvno));
+ *key->mkvno = tmp;
+ } else
+ key->mkvno = NULL;
+ p = strsep(&str, ":");
+ sscanf(p, "%d", &tmp);
+ key->key.keytype = tmp;
+ p = strsep(&str, ":");
+ krb5_data_alloc(&key->key.keyvalue, (strlen(p) - 1) / 2 + 1);
+ for(i = 0; i < strlen(p); i += 2){
+ sscanf(p + i, "%02x", &tmp);
+ ((u_char*)key->key.keyvalue.data)[i / 2] = tmp;
+ }
+ p = strsep(&str, ":");
+ if(strcmp(p, "-") != 0){
+ unsigned type;
+ size_t p_len;
+ if(sscanf(p, "%u/", &type) != 1){
+ abort ();
+ }
+ p = strchr(p, '/');
+ if(p == NULL)
+ abort ();
+ p++;
+ p_len = strlen(p);
+
+ key->salt = malloc(sizeof(*key->salt));
+ key->salt->type = type;
+
+ if (p_len) {
+ if(*p == '\"'){
+ krb5_data_copy(&key->salt->salt, p + 1, p_len - 2);
+ }else{
+ krb5_data_alloc(&key->salt->salt, (p_len - 1) / 2 + 1);
+ for(i = 0; i < p_len; i += 2){
+ sscanf(p + i, "%02x", &tmp);
+ ((u_char*)key->salt->salt.data)[i / 2] = tmp;
+ }
+ }
+ } else
+ krb5_data_zero (&key->salt->salt);
+ }
+ p = strsep(&str, ":");
+ }
+}
+
+static Event*
+parse_event(Event *ev, char *str)
+{
+ char *p;
+ if(strcmp(str, "-") == 0)
+ return NULL;
+ if(ev == NULL)
+ ev = malloc(sizeof(*ev));
+ memset(ev, 0, sizeof(*ev));
+ p = strsep(&str, ":");
+ parse_time_string(&ev->time, p);
+ p = strsep(&str, ":");
+ krb5_parse_name(context, p, &ev->principal);
+ return ev;
+}
+
+static HDBFlags
+parse_hdbflags2int(char *str)
+{
+ unsigned i;
+ parse_integer(&i, str);
+
+ return int2HDBFlags(i);
+}
+
+#if 0
+static void
+parse_etypes(char *str, unsigned **val, unsigned *len)
+{
+ unsigned v;
+
+ *val = NULL;
+ *len = 0;
+ while(sscanf(str, "%u", &v) == 1) {
+ *val = realloc(*val, (*len+1) * sizeof(**val));
+ (*val)[(*len)++] = v;
+ str = strchr(str, ':');
+ if(str == NULL)
+ break;
+ str++;
+ }
+}
+#endif
+
+static void
+doit(char *filename, int merge)
+{
+ krb5_error_code ret;
+ FILE *f;
+ char s[1024];
+ char *p;
+ int line;
+ int flags = O_RDWR;
+ struct entry e;
+ hdb_entry ent;
+ HDB *db = _kadm5_s_get_db(kadm_handle);
+
+ f = fopen(filename, "r");
+ if(f == NULL){
+ krb5_warn(context, errno, "fopen(%s)", filename);
+ return;
+ }
+ if(!merge)
+ flags |= O_CREAT | O_TRUNC;
+ ret = db->open(context, db, flags, 0600);
+ if(ret){
+ krb5_warn(context, ret, "hdb_open");
+ fclose(f);
+ return;
+ }
+ line = 0;
+ while(fgets(s, sizeof(s), f)){
+ line++;
+ e.principal = s;
+ for(p = s; *p; p++){
+ if(*p == '\\')
+ p++;
+ else if(isspace((unsigned char)*p)) {
+ *p = 0;
+ break;
+ }
+ }
+ p = skip_next(p);
+
+ e.key = p;
+ p = skip_next(p);
+
+ e.created = p;
+ p = skip_next(p);
+
+ e.modified = p;
+ p = skip_next(p);
+
+ e.valid_start = p;
+ p = skip_next(p);
+
+ e.valid_end = p;
+ p = skip_next(p);
+
+ e.pw_end = p;
+ p = skip_next(p);
+
+ e.max_life = p;
+ p = skip_next(p);
+
+ e.max_renew = p;
+ p = skip_next(p);
+
+ e.flags = p;
+ p = skip_next(p);
+
+ e.etypes = p;
+ p = skip_next(p);
+
+ memset(&ent, 0, sizeof(ent));
+ ret = krb5_parse_name(context, e.principal, &ent.principal);
+ if(ret){
+ fprintf(stderr, "%s:%d:%s (%s)\n",
+ filename,
+ line,
+ krb5_get_err_text(context, ret),
+ e.principal);
+ continue;
+ }
+
+ parse_keys(&ent, e.key);
+
+ parse_event(&ent.created_by, e.created);
+ ent.modified_by = parse_event(NULL, e.modified);
+ ent.valid_start = parse_time_string(NULL, e.valid_start);
+ ent.valid_end = parse_time_string(NULL, e.valid_end);
+ ent.pw_end = parse_time_string(NULL, e.pw_end);
+ ent.max_life = parse_integer(NULL, e.max_life);
+ ent.max_renew = parse_integer(NULL, e.max_renew);
+ ent.flags = parse_hdbflags2int(e.flags);
+#if 0
+ ALLOC(ent.etypes);
+ parse_etypes(e.etypes, &ent.etypes->val, &ent.etypes->len);
+ if(ent.etypes->len == 0) {
+ free(ent.etypes);
+ ent.etypes = NULL;
+ }
+#endif
+
+ db->store(context, db, HDB_F_REPLACE, &ent);
+ hdb_free_entry (context, &ent);
+ }
+ db->close(context, db);
+ fclose(f);
+}
+
+int
+load(int argc, char **argv)
+{
+ if(argc < 2){
+ krb5_warnx(context, "Usage: load filename");
+ return 0;
+ }
+ doit(argv[1], 0);
+ return 0;
+}
+
+int
+merge(int argc, char **argv)
+{
+ if(argc < 2){
+ krb5_warnx(context, "Usage: merge filename");
+ return 0;
+ }
+ doit(argv[1], 1);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/mod.c b/crypto/heimdal/kadmin/mod.c
new file mode 100644
index 000000000000..48d00a62e41a
--- /dev/null
+++ b/crypto/heimdal/kadmin/mod.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: mod.c,v 1.7 1999/12/02 17:04:58 joda Exp $");
+
+static int parse_args (krb5_context context, kadm5_principal_ent_t ent,
+ int argc, char **argv, int *optind, char *name,
+ int *mask);
+
+static int
+parse_args(krb5_context context, kadm5_principal_ent_t ent,
+ int argc, char **argv, int *optind, char *name,
+ int *mask)
+{
+ char *attr_str = NULL;
+ char *max_life_str = NULL;
+ char *max_rlife_str = NULL;
+ char *expiration_str = NULL;
+ char *pw_expiration_str = NULL;
+ int ret, i;
+
+ struct getargs args[] = {
+ {"attributes", 'a', arg_string, NULL, "Attributies",
+ "attributes"},
+ {"max-ticket-life", 0, arg_string, NULL, "max ticket lifetime",
+ "lifetime"},
+ {"max-renewable-life", 0, arg_string, NULL,
+ "max renewable lifetime", "lifetime" },
+ {"expiration-time", 0, arg_string,
+ NULL, "Expiration time", "time"},
+ {"pw-expiration-time", 0, arg_string,
+ NULL, "Password expiration time", "time"},
+ };
+
+ i = 0;
+ args[i++].value = &attr_str;
+ args[i++].value = &max_life_str;
+ args[i++].value = &max_rlife_str;
+ args[i++].value = &expiration_str;
+ args[i++].value = &pw_expiration_str;
+
+ *optind = 0; /* XXX */
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]),
+ argc, argv, optind)){
+ arg_printusage(args,
+ sizeof(args) / sizeof(args[0]),
+ name ? name : "",
+ "principal");
+ return -1;
+ }
+
+ ret = set_entry(context, ent, mask, max_life_str, max_rlife_str,
+ expiration_str, pw_expiration_str, attr_str);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+int
+mod_entry(int argc, char **argv)
+{
+ kadm5_principal_ent_rec princ;
+ int mask = 0;
+ krb5_error_code ret;
+ krb5_principal princ_ent = NULL;
+ int optind;
+
+ memset (&princ, 0, sizeof(princ));
+
+ ret = parse_args (context, &princ, argc, argv,
+ &optind, "mod", &mask);
+ if (ret)
+ return 0;
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ printf ("Usage: mod [options] principal\n");
+ return 0;
+ }
+
+ krb5_parse_name(context, argv[0], &princ_ent);
+
+ if (mask == 0) {
+ memset(&princ, 0, sizeof(princ));
+ ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
+ KADM5_PRINCIPAL | KADM5_ATTRIBUTES |
+ KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
+ KADM5_PRINC_EXPIRE_TIME |
+ KADM5_PW_EXPIRATION);
+ if (ret) {
+ printf ("no such principal: %s\n", argv[0]);
+ krb5_free_principal (context, princ_ent);
+ return 0;
+ }
+ edit_entry(&princ, &mask, NULL, 0);
+
+ } else {
+ princ.principal = princ_ent;
+ }
+
+ ret = kadm5_modify_principal(kadm_handle, &princ, mask);
+ if(ret)
+ krb5_warn(context, ret, "kadm5_modify_principal");
+ if(princ_ent)
+ krb5_free_principal(context, princ_ent);
+ kadm5_free_principal_ent(kadm_handle, &princ);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/random_password.c b/crypto/heimdal/kadmin/random_password.c
new file mode 100644
index 000000000000..aabe08c2776b
--- /dev/null
+++ b/crypto/heimdal/kadmin/random_password.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: random_password.c,v 1.3 1999/12/02 17:04:58 joda Exp $");
+
+/* 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)
+{
+#ifdef OTP_STYLE
+ {
+ des_cblock newkey;
+
+ des_new_random_key(&newkey);
+ otp_print_stddict (newkey, pw, len);
+ strlwr(pw);
+ }
+#else
+ char *pass;
+ generate_password(&pass, 3,
+ "abcdefghijklmnopqrstuvwxyz", 7,
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 2,
+ "@$%&*()-+=:,/<>1234567890", 1);
+ strlcpy(pw, pass, len);
+ memset(pass, 0, strlen(pass));
+ free(pass);
+#endif
+}
+
+/* some helper functions */
+
+#ifndef OTP_STYLE
+/* return a random value in range 0-127 */
+static int
+RND(des_cblock *key, int *left)
+{
+ if(*left == 0){
+ des_new_random_key(key);
+ *left = 8;
+ }
+ (*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;
+ des_cblock rbuf; /* random buffer */
+ int rleft = 0;
+
+ classes = malloc(num_classes * sizeof(*classes));
+ 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)
+ return;
+ for(i = 0; i < len; i++) {
+ int j;
+ int x = RND(&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, &rleft) % classes[j].len];
+ classes[j].freq--;
+ break;
+ }
+ t += classes[j].freq;
+ }
+ }
+ (*pw)[len] = '\0';
+ memset(rbuf, 0, sizeof(rbuf));
+ free(classes);
+}
+#endif
diff --git a/crypto/heimdal/kadmin/rename.c b/crypto/heimdal/kadmin/rename.c
new file mode 100644
index 000000000000..4d8a48e33df2
--- /dev/null
+++ b/crypto/heimdal/kadmin/rename.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: rename.c,v 1.2 1999/12/02 17:04:58 joda Exp $");
+
+int
+rename_entry(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_principal princ1, princ2;
+
+ if(argc != 3){
+ krb5_warnx(context, "rename source target");
+ return 0;
+ }
+ ret = krb5_parse_name(context, argv[1], &princ1);
+ if(ret){
+ krb5_warn(context, ret, "krb5_parse_name(%s)", argv[1]);
+ return 0;
+ }
+ ret = krb5_parse_name(context, argv[2], &princ2);
+ if(ret){
+ krb5_free_principal(context, princ2);
+ krb5_warn(context, ret, "krb5_parse_name(%s)", argv[2]);
+ return 0;
+ }
+ ret = kadm5_rename_principal(kadm_handle, princ1, princ2);
+ if(ret)
+ krb5_warn(context, ret, "rename");
+ krb5_free_principal(context, princ1);
+ krb5_free_principal(context, princ2);
+ return 0;
+}
+
diff --git a/crypto/heimdal/kadmin/server.c b/crypto/heimdal/kadmin/server.c
new file mode 100644
index 000000000000..d491e464f8be
--- /dev/null
+++ b/crypto/heimdal/kadmin/server.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+#include <krb5-private.h>
+
+RCSID("$Id: server.c,v 1.24 2000/01/02 03:58:45 assar Exp $");
+
+static kadm5_ret_t
+kadmind_dispatch(void *kadm_handle, krb5_boolean initial,
+ krb5_data *in, krb5_data *out)
+{
+ kadm5_ret_t ret;
+ int32_t cmd, mask, tmp;
+ kadm5_server_context *context = kadm_handle;
+ char client[128], name[128], name2[128];
+ char *op = "";
+ krb5_principal princ, princ2;
+ kadm5_principal_ent_rec ent;
+ char *password, *exp;
+ krb5_keyblock *new_keys;
+ int n_keys;
+ char **princs;
+ int n_princs;
+ krb5_storage *sp;
+
+ krb5_unparse_name_fixed(context->context, context->caller,
+ client, sizeof(client));
+
+ sp = krb5_storage_from_data(in);
+
+ krb5_ret_int32(sp, &cmd);
+ switch(cmd){
+ case kadm_get:{
+ op = "GET";
+ ret = krb5_ret_principal(sp, &princ);
+ if(ret)
+ goto fail;
+ ret = krb5_ret_int32(sp, &mask);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_GET);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ ret = kadm5_get_principal(kadm_handle, princ, &ent, mask);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ if(ret == 0){
+ kadm5_store_principal_ent(sp, &ent);
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ }
+ krb5_free_principal(context->context, princ);
+ break;
+ }
+ case kadm_delete:{
+ op = "DELETE";
+ ret = krb5_ret_principal(sp, &princ);
+ if(ret)
+ goto fail;
+ krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_DELETE);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ ret = kadm5_delete_principal(kadm_handle, princ);
+ krb5_free_principal(context->context, princ);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ break;
+ }
+ case kadm_create:{
+ op = "CREATE";
+ ret = kadm5_ret_principal_ent(sp, &ent);
+ if(ret)
+ goto fail;
+ ret = krb5_ret_int32(sp, &mask);
+ if(ret){
+ kadm5_free_principal_ent(context->context, &ent);
+ goto fail;
+ }
+ ret = krb5_ret_string(sp, &password);
+ if(ret){
+ kadm5_free_principal_ent(context->context, &ent);
+ goto fail;
+ }
+ krb5_unparse_name_fixed(context->context, ent.principal,
+ name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_ADD);
+ if(ret){
+ kadm5_free_principal_ent(context->context, &ent);
+ memset(password, 0, strlen(password));
+ free(password);
+ goto fail;
+ }
+ ret = kadm5_create_principal(kadm_handle, &ent,
+ mask, password);
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ memset(password, 0, strlen(password));
+ free(password);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ break;
+ }
+ case kadm_modify:{
+ op = "MODIFY";
+ ret = kadm5_ret_principal_ent(sp, &ent);
+ if(ret)
+ goto fail;
+ ret = krb5_ret_int32(sp, &mask);
+ if(ret){
+ kadm5_free_principal_ent(context, &ent);
+ goto fail;
+ }
+ krb5_unparse_name_fixed(context->context, ent.principal,
+ name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_MODIFY);
+ if(ret){
+ kadm5_free_principal_ent(context, &ent);
+ goto fail;
+ }
+ ret = kadm5_modify_principal(kadm_handle, &ent, mask);
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ break;
+ }
+ case kadm_rename:{
+ op = "RENAME";
+ ret = krb5_ret_principal(sp, &princ);
+ if(ret)
+ goto fail;
+ ret = krb5_ret_principal(sp, &princ2);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
+ krb5_unparse_name_fixed(context->context, princ2, name2, sizeof(name2));
+ krb5_warnx(context->context, "%s: %s %s -> %s",
+ client, op, name, name2);
+ ret = _kadm5_acl_check_permission(context,
+ KADM5_PRIV_ADD|KADM5_PRIV_DELETE);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ ret = kadm5_rename_principal(kadm_handle, princ, princ2);
+ krb5_free_principal(context->context, princ);
+ krb5_free_principal(context->context, princ2);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ break;
+ }
+ case kadm_chpass:{
+ op = "CHPASS";
+ ret = krb5_ret_principal(sp, &princ);
+ if(ret)
+ goto fail;
+ ret = krb5_ret_string(sp, &password);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+
+ /*
+ * The change is allowed if at least one of:
+ * a) it's for the principal him/herself and this was an initial ticket
+ * b) the user is on the CPW ACL.
+ */
+
+ if (initial
+ && krb5_principal_compare (context->context, context->caller,
+ princ))
+ ret = 0;
+ else
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW);
+
+ if(ret) {
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ ret = kadm5_chpass_principal(kadm_handle, princ, password);
+ krb5_free_principal(context->context, princ);
+ memset(password, 0, strlen(password));
+ free(password);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ break;
+ }
+ case kadm_randkey:{
+ op = "RANDKEY";
+ ret = krb5_ret_principal(sp, &princ);
+ if(ret)
+ goto fail;
+ krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+ /*
+ * The change is allowed if at least one of:
+ * a) it's for the principal him/herself and this was an initial ticket
+ * b) the user is on the CPW ACL.
+ */
+
+ if (initial
+ && krb5_principal_compare (context->context, context->caller,
+ princ))
+ ret = 0;
+ else
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW);
+
+ if(ret) {
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ ret = kadm5_randkey_principal(kadm_handle, princ,
+ &new_keys, &n_keys);
+ krb5_free_principal(context->context, princ);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ if(ret == 0){
+ int i;
+ krb5_store_int32(sp, n_keys);
+ for(i = 0; i < n_keys; i++){
+ krb5_store_keyblock(sp, new_keys[i]);
+ krb5_free_keyblock_contents(context->context, &new_keys[i]);
+ }
+ }
+ break;
+ }
+ case kadm_get_privs:{
+ ret = kadm5_get_privs(kadm_handle, &mask);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ if(ret == 0)
+ krb5_store_int32(sp, mask);
+ break;
+ }
+ case kadm_get_princs:{
+ op = "LIST";
+ ret = krb5_ret_int32(sp, &tmp);
+ if(ret)
+ goto fail;
+ if(tmp){
+ ret = krb5_ret_string(sp, &exp);
+ if(ret)
+ goto fail;
+ }else
+ exp = NULL;
+ krb5_warnx(context->context, "%s: %s %s", client, op, exp ? exp : "*");
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_LIST);
+ if(ret){
+ free(exp);
+ goto fail;
+ }
+ ret = kadm5_get_principals(kadm_handle, exp, &princs, &n_princs);
+ free(exp);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ if(ret == 0){
+ int i;
+ krb5_store_int32(sp, n_princs);
+ for(i = 0; i < n_princs; i++)
+ krb5_store_string(sp, princs[i]);
+ kadm5_free_name_list(kadm_handle, princs, &n_princs);
+ }
+ break;
+ }
+ default:
+ krb5_warnx(context->context, "%s: UNKNOWN OP %d", client, cmd);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, KADM5_FAILURE);
+ break;
+ }
+ krb5_storage_to_data(sp, out);
+ krb5_storage_free(sp);
+ return 0;
+fail:
+ krb5_warn(context->context, ret, "%s", op);
+ sp->seek(sp, 0, SEEK_SET);
+ krb5_store_int32(sp, ret);
+ krb5_storage_to_data(sp, out);
+ krb5_storage_free(sp);
+ return 0;
+}
+
+static void
+v5_loop (krb5_context context,
+ krb5_auth_context ac,
+ krb5_boolean initial,
+ void *kadm_handle,
+ int fd)
+{
+ krb5_error_code ret;
+ ssize_t n;
+ unsigned long len;
+ u_char tmp[4];
+ struct iovec iov[2];
+ krb5_data in, out, msg, reply;
+
+ for (;;) {
+ n = krb5_net_read(context, &fd, tmp, 4);
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+ if (n == 0)
+ exit (0);
+ _krb5_get_int (tmp, &len, 4);
+
+ ret = krb5_data_alloc(&in, len);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_data_alloc");
+
+ n = krb5_net_read(context, &fd, in.data, in.length);
+ if (n == 0)
+ exit (0);
+ if(n < 0)
+ krb5_errx(context, 1, "read error: %d", errno);
+ ret = krb5_rd_priv(context, ac, &in, &out, NULL);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_rd_priv");
+ krb5_data_free(&in);
+ kadmind_dispatch(kadm_handle, initial, &out, &msg);
+ krb5_data_free(&out);
+ ret = krb5_mk_priv(context, ac, &msg, &reply, NULL);
+ krb5_data_free(&msg);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_mk_priv");
+
+ _krb5_put_int(tmp, reply.length, 4);
+
+ iov[0].iov_base = tmp;
+ iov[0].iov_len = 4;
+ iov[1].iov_base = reply.data;
+ iov[1].iov_len = reply.length;
+ n = writev(fd, iov, 2);
+ krb5_data_free(&reply);
+ if(n < 0)
+ krb5_err(context, 1, errno, "writev");
+ if(n < iov[0].iov_len + iov[1].iov_len)
+ krb5_errx(context, 1, "short write");
+ }
+}
+
+static krb5_boolean
+match_appl_version(void *data, const char *appl_version)
+{
+ unsigned minor;
+ if(sscanf(appl_version, "KADM0.%u", &minor) != 1)
+ return 0;
+ *(unsigned*)data = minor;
+ return 1;
+}
+
+static void
+handle_v5(krb5_context context,
+ krb5_auth_context ac,
+ krb5_keytab keytab,
+ int len,
+ int fd)
+{
+ krb5_error_code ret;
+ u_char version[sizeof(KRB5_SENDAUTH_VERSION)];
+ krb5_ticket *ticket;
+ krb5_principal server;
+ char *client;
+ void *kadm_handle;
+ ssize_t n;
+ krb5_boolean initial;
+
+ unsigned kadm_version;
+ kadm5_config_params realm_params;
+
+ if (len != sizeof(KRB5_SENDAUTH_VERSION))
+ krb5_errx(context, 1, "bad sendauth len %d", len);
+ n = krb5_net_read(context, &fd, version, len);
+ if (n < 0)
+ krb5_err (context, 1, errno, "reading sendauth version");
+ if (n == 0)
+ krb5_errx (context, 1, "EOF reading sendauth version");
+ if(memcmp(version, KRB5_SENDAUTH_VERSION, len) != 0)
+ krb5_errx(context, 1, "bad sendauth version %.8s", version);
+
+ ret = krb5_parse_name(context, KADM5_ADMIN_SERVICE, &server);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name %s", KADM5_ADMIN_SERVICE);
+ ret = krb5_recvauth_match_version(context, &ac, &fd,
+ match_appl_version, &kadm_version,
+ server, KRB5_RECVAUTH_IGNORE_VERSION,
+ keytab, &ticket);
+ if(ret == KRB5_KT_NOTFOUND) {
+ char *name;
+ krb5_unparse_name(context, server, &name);
+ krb5_errx(context, 1, "krb5_recvauth: %s (%s)",
+ krb5_get_err_text(context, ret),
+ name);
+ }
+ krb5_free_principal(context, server);
+
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_recvauth");
+
+ memset(&realm_params, 0, sizeof(realm_params));
+
+ if(kadm_version == 1) {
+ krb5_data enc_data, params;
+ ret = krb5_read_message(context, &fd, &enc_data);
+ ret = krb5_rd_priv(context, ac, &enc_data, &params, NULL);
+ krb5_data_free(&enc_data);
+ _kadm5_unmarshal_params(context, &params, &realm_params);
+ }
+
+ initial = ticket->ticket.flags.initial;
+ ret = krb5_unparse_name(context, ticket->client, &client);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_unparse_name");
+ krb5_free_ticket (context, ticket);
+ ret = kadm5_init_with_password_ctx(context,
+ client,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &realm_params,
+ 0, 0,
+ &kadm_handle);
+ if(ret)
+ krb5_err (context, 1, ret, "kadm5_init_with_password_ctx");
+ v5_loop (context, ac, initial, kadm_handle, fd);
+}
+
+krb5_error_code
+kadmind_loop(krb5_context context,
+ krb5_auth_context ac,
+ krb5_keytab keytab,
+ int fd)
+{
+ unsigned char tmp[4];
+ ssize_t n;
+ unsigned long len;
+
+ n = krb5_net_read(context, &fd, tmp, 4);
+ if(n == 0)
+ exit(0);
+ if(n < 0)
+ krb5_errx(context, 1, "read error: %d", errno);
+ _krb5_get_int(tmp, &len, 4);
+ if(len > 0xffff && (len & 0xffff) == ('K' << 8) + 'A') {
+ len >>= 16;
+#ifdef KRB4
+ handle_v4(context, len, fd);
+#else
+ krb5_errx(context, 1, "packet appears to be version 4");
+#endif
+ } else {
+ handle_v5(context, ac, keytab, len, fd);
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/util.c b/crypto/heimdal/kadmin/util.c
new file mode 100644
index 000000000000..f30c8c5a79df
--- /dev/null
+++ b/crypto/heimdal/kadmin/util.c
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+#include <parse_units.h>
+
+RCSID("$Id: util.c,v 1.23 1999/12/02 17:04:58 joda Exp $");
+
+/*
+ * util.c - functions for parsing, unparsing, and editing different
+ * types of data used in kadmin.
+ */
+
+/*
+ * attributes
+ */
+
+struct units kdb_attrs[] = {
+ { "new-princ", KRB5_KDB_NEW_PRINC },
+ { "support-desmd5", KRB5_KDB_SUPPORT_DESMD5 },
+ { "pwchange-service", KRB5_KDB_PWCHANGE_SERVICE },
+ { "disallow-svr", KRB5_KDB_DISALLOW_SVR },
+ { "requires-pw-change", KRB5_KDB_REQUIRES_PWCHANGE },
+ { "requires-hw-auth", KRB5_KDB_REQUIRES_HW_AUTH },
+ { "requires-pre-auth", KRB5_KDB_REQUIRES_PRE_AUTH },
+ { "disallow-all-tix", KRB5_KDB_DISALLOW_ALL_TIX },
+ { "disallow-dup-skey", KRB5_KDB_DISALLOW_DUP_SKEY },
+ { "disallow-proxiable", KRB5_KDB_DISALLOW_PROXIABLE },
+ { "disallow-renewable", KRB5_KDB_DISALLOW_RENEWABLE },
+ { "disallow-tgt-based", KRB5_KDB_DISALLOW_TGT_BASED },
+ { "disallow-forwardable", KRB5_KDB_DISALLOW_FORWARDABLE },
+ { "disallow-postdated", KRB5_KDB_DISALLOW_POSTDATED },
+ { NULL }
+};
+
+/*
+ * convert the attributes in `attributes' into a printable string
+ * in `str, len'
+ */
+
+void
+attributes2str(krb5_flags attributes, char *str, size_t len)
+{
+ unparse_flags (attributes, kdb_attrs, str, len);
+}
+
+/*
+ * convert the string in `str' into attributes in `flags'
+ * return 0 if parsed ok, else -1.
+ */
+
+int
+str2attributes(const char *str, krb5_flags *flags)
+{
+ int res;
+
+ res = parse_flags (str, kdb_attrs, *flags);
+ if (res < 0)
+ return res;
+ else {
+ *flags = res;
+ return 0;
+ }
+}
+
+/*
+ * try to parse the string `resp' into attributes in `attr', also
+ * setting the `bit' in `mask' if attributes are given and valid.
+ */
+
+int
+parse_attributes (const char *resp, krb5_flags *attr, int *mask, int bit)
+{
+ krb5_flags tmp = *attr;
+
+ if (resp[0] == '\0')
+ return 0;
+ else if (str2attributes(resp, &tmp) == 0) {
+ *attr = tmp;
+ if (mask)
+ *mask |= bit;
+ return 0;
+ } else if(*resp == '?') {
+ print_flags_table (kdb_attrs, stderr);
+ } else {
+ fprintf (stderr, "Unable to parse '%s'\n", resp);
+ }
+ return -1;
+}
+
+/*
+ * allow the user to edit the attributes in `attr', prompting with `prompt'
+ */
+
+int
+edit_attributes (const char *prompt, krb5_flags *attr, int *mask, int bit)
+{
+ char buf[1024], resp[1024];
+
+ if (mask && (*mask & bit))
+ return 0;
+
+ attributes2str(*attr, buf, sizeof(buf));
+ for (;;) {
+ get_response("Attributes", buf, resp, sizeof(resp));
+ if (parse_attributes (resp, attr, mask, bit) == 0)
+ break;
+ }
+ return 0;
+}
+
+/*
+ * time_t
+ * the special value 0 means ``never''
+ */
+
+/*
+ * Convert the time `t' to a string representation in `str' (of max
+ * size `len'). If include_time also include time, otherwise just
+ * date.
+ */
+
+void
+time_t2str(time_t t, char *str, size_t len, int include_time)
+{
+ if(t) {
+ if(include_time)
+ strftime(str, len, "%Y-%m-%d %H:%M:%S UTC", gmtime(&t));
+ else
+ strftime(str, len, "%Y-%m-%d", gmtime(&t));
+ } else
+ snprintf(str, len, "never");
+}
+
+/*
+ * Convert the time representation in `str' to a time in `time'.
+ * Return 0 if succesful, else -1.
+ */
+
+int
+str2time_t (const char *str, time_t *time)
+{
+ const char *p;
+ struct tm tm;
+
+ memset (&tm, 0, sizeof (tm));
+
+ if(strcasecmp(str, "never") == 0) {
+ *time = 0;
+ return 0;
+ }
+
+ p = strptime (str, "%Y-%m-%d", &tm);
+
+ if (p == NULL)
+ return -1;
+
+ /* Do it on the end of the day */
+ tm.tm_hour = 23;
+ tm.tm_min = 59;
+ tm.tm_sec = 59;
+
+ strptime (p, "%H:%M:%S", &tm);
+
+ *time = tm2time (tm, 0);
+ return 0;
+}
+
+/*
+ * try to parse the time in `resp' storing it in `value'
+ */
+
+int
+parse_timet (const char *resp, krb5_timestamp *value, int *mask, int bit)
+{
+ time_t tmp;
+
+ if (str2time_t(resp, &tmp) == 0) {
+ *value = tmp;
+ if(mask)
+ *mask |= bit;
+ return 0;
+ } else if(*resp == '?') {
+ printf ("Print date on format YYYY-mm-dd [hh:mm:ss]\n");
+ } else {
+ fprintf (stderr, "Unable to parse time '%s'\n", resp);
+ }
+ return -1;
+}
+
+/*
+ * allow the user to edit the time in `value'
+ */
+
+int
+edit_timet (const char *prompt, krb5_timestamp *value, int *mask, int bit)
+{
+ char buf[1024], resp[1024];
+
+ if (mask && (*mask & bit))
+ return 0;
+
+ time_t2str (*value, buf, sizeof (buf), 0);
+
+ for (;;) {
+ get_response(prompt, buf, resp, sizeof(resp));
+ if (parse_timet (resp, value, mask, bit) == 0)
+ break;
+ }
+ return 0;
+}
+
+/*
+ * deltat
+ * the special value 0 means ``unlimited''
+ */
+
+/*
+ * convert the delta_t value in `t' into a printable form in `str, len'
+ */
+
+void
+deltat2str(unsigned t, char *str, size_t len)
+{
+ if(t)
+ unparse_time(t, str, len);
+ else
+ snprintf(str, len, "unlimited");
+}
+
+/*
+ * parse the delta value in `str', storing result in `*delta'
+ * return 0 if ok, else -1
+ */
+
+int
+str2deltat(const char *str, krb5_deltat *delta)
+{
+ int res;
+
+ if(strcasecmp(str, "unlimited") == 0) {
+ *delta = 0;
+ return 0;
+ }
+ res = parse_time(str, "day");
+ if (res < 0)
+ return res;
+ else {
+ *delta = res;
+ return 0;
+ }
+}
+
+/*
+ * try to parse the string in `resp' into a deltad in `value'
+ * `mask' will get the bit `bit' set if a value was given.
+ */
+
+int
+parse_deltat (const char *resp, krb5_deltat *value, int *mask, int bit)
+{
+ krb5_deltat tmp;
+
+ if (str2deltat(resp, &tmp) == 0) {
+ *value = tmp;
+ if (mask)
+ *mask |= bit;
+ return 0;
+ } else if(*resp == '?') {
+ print_time_table (stderr);
+ } else {
+ fprintf (stderr, "Unable to parse time '%s'\n", resp);
+ }
+ return -1;
+}
+
+/*
+ * allow the user to edit the deltat in `value'
+ */
+
+int
+edit_deltat (const char *prompt, krb5_deltat *value, int *mask, int bit)
+{
+ char buf[1024], resp[1024];
+
+ if (mask && (*mask & bit))
+ return 0;
+
+ deltat2str(*value, buf, sizeof(buf));
+ for (;;) {
+ get_response(prompt, buf, resp, sizeof(resp));
+ if (parse_deltat (resp, value, mask, bit) == 0)
+ break;
+ }
+ return 0;
+}
+
+/*
+ * allow the user to edit `ent'
+ */
+
+int
+edit_entry(kadm5_principal_ent_t ent, int *mask,
+ kadm5_principal_ent_t default_ent, int default_mask)
+{
+ if (default_ent && (default_mask & KADM5_MAX_LIFE))
+ ent->max_life = default_ent->max_life;
+ edit_deltat ("Max ticket life", &ent->max_life, mask,
+ KADM5_MAX_LIFE);
+
+ if (default_ent && (default_mask & KADM5_MAX_RLIFE))
+ ent->max_renewable_life = default_ent->max_renewable_life;
+ edit_deltat ("Max renewable life", &ent->max_renewable_life, mask,
+ KADM5_MAX_RLIFE);
+
+ if (default_ent && (default_mask & KADM5_PRINC_EXPIRE_TIME))
+ ent->princ_expire_time = default_ent->princ_expire_time;
+ edit_timet ("Principal expiration time", &ent->princ_expire_time, mask,
+ KADM5_PRINC_EXPIRE_TIME);
+
+ if (default_ent && (default_mask & KADM5_PW_EXPIRATION))
+ ent->pw_expiration = default_ent->pw_expiration;
+ edit_timet ("Password expiration time", &ent->pw_expiration, mask,
+ KADM5_PW_EXPIRATION);
+
+ if (default_ent && (default_mask & KADM5_ATTRIBUTES))
+ ent->attributes = default_ent->attributes & ~KRB5_KDB_DISALLOW_ALL_TIX;
+ edit_attributes ("Attributes", &ent->attributes, mask,
+ KADM5_ATTRIBUTES);
+ return 0;
+}
+
+/*
+ * Parse the arguments, set the fields in `ent' and the `mask' for the
+ * entries having been set.
+ * Return 1 on failure and 0 on success.
+ */
+
+int
+set_entry(krb5_context context,
+ kadm5_principal_ent_t ent,
+ int *mask,
+ const char *max_ticket_life,
+ const char *max_renewable_life,
+ const char *expiration,
+ const char *pw_expiration,
+ const char *attributes)
+{
+ if (max_ticket_life != NULL) {
+ if (parse_deltat (max_ticket_life, &ent->max_life,
+ mask, KADM5_MAX_LIFE)) {
+ krb5_warnx (context, "unable to parse `%s'", max_ticket_life);
+ return 1;
+ }
+ }
+ if (max_renewable_life != NULL) {
+ if (parse_deltat (max_renewable_life, &ent->max_renewable_life,
+ mask, KADM5_MAX_RLIFE)) {
+ krb5_warnx (context, "unable to parse `%s'", max_renewable_life);
+ return 1;
+ }
+ }
+
+ if (expiration) {
+ if (parse_timet (expiration, &ent->princ_expire_time,
+ mask, KADM5_PRINC_EXPIRE_TIME)) {
+ krb5_warnx (context, "unable to parse `%s'", expiration);
+ return 1;
+ }
+ }
+ if (pw_expiration) {
+ if (parse_timet (pw_expiration, &ent->pw_expiration,
+ mask, KADM5_PW_EXPIRATION)) {
+ krb5_warnx (context, "unable to parse `%s'", pw_expiration);
+ return 1;
+ }
+ }
+ if (attributes != NULL) {
+ if (parse_attributes (attributes, &ent->attributes,
+ mask, KADM5_ATTRIBUTES)) {
+ krb5_warnx (context, "unable to parse `%s'", attributes);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Does `string' contain any globing characters?
+ */
+
+static int
+is_expression(const char *string)
+{
+ const char *p;
+ int quote = 0;
+
+ for(p = string; *p; p++) {
+ if(quote) {
+ quote = 0;
+ continue;
+ }
+ if(*p == '\\')
+ quote++;
+ else if(strchr("[]*?", *p) != NULL)
+ return 1;
+ }
+ return 0;
+}
+
+/* loop over all principals matching exp */
+int
+foreach_principal(const char *exp,
+ int (*func)(krb5_principal, void*),
+ void *data)
+{
+ char **princs;
+ int num_princs;
+ int i;
+ krb5_error_code ret;
+ krb5_principal princ_ent;
+ int is_expr;
+
+ /* if this isn't an expression, there is no point in wading
+ through the whole database looking for matches */
+ is_expr = is_expression(exp);
+ if(is_expr)
+ ret = kadm5_get_principals(kadm_handle, exp, &princs, &num_princs);
+ if(!is_expr || ret == KADM5_AUTH_LIST) {
+ /* we might be able to perform the requested opreration even
+ if we're not allowed to list principals */
+ num_princs = 1;
+ princs = malloc(sizeof(*princs));
+ if(princs == NULL)
+ return ENOMEM;
+ princs[0] = strdup(exp);
+ if(princs[0] == NULL){
+ free(princs);
+ return ENOMEM;
+ }
+ } else if(ret) {
+ krb5_warn(context, ret, "kadm5_get_principals");
+ return ret;
+ }
+ for(i = 0; i < num_princs; i++) {
+ ret = krb5_parse_name(context, princs[i], &princ_ent);
+ if(ret){
+ krb5_warn(context, ret, "krb5_parse_name(%s)", princs[i]);
+ continue;
+ }
+ ret = (*func)(princ_ent, data);
+ if(ret) {
+ char *tmp;
+ krb5_error_code ret2;
+
+ ret2 = krb5_unparse_name(context, princ_ent, &tmp);
+ if(ret2) {
+ krb5_warn(context, ret2, "krb5_unparse_name");
+ krb5_warn(context, ret, "<unknown principal>");
+ } else {
+ krb5_warn(context, ret, "%s", tmp);
+ free(tmp);
+ }
+ }
+ krb5_free_principal(context, princ_ent);
+ }
+ kadm5_free_name_list(kadm_handle, princs, &num_princs);
+ return 0;
+}
+
+/*
+ * prompt with `prompt' and default value `def', and store the reply
+ * in `buf, len'
+ */
+
+void
+get_response(const char *prompt, const char *def, char *buf, size_t len)
+{
+ char *p;
+
+ printf("%s [%s]:", prompt, def);
+ if(fgets(buf, len, stdin) == NULL)
+ *buf = '\0';
+ p = strchr(buf, '\n');
+ if(p)
+ *p = '\0';
+ if(strcmp(buf, "") == 0)
+ strncpy(buf, def, len);
+ buf[len-1] = 0;
+}
diff --git a/crypto/heimdal/kadmin/version4.c b/crypto/heimdal/kadmin/version4.c
new file mode 100644
index 000000000000..77ac02908aa3
--- /dev/null
+++ b/crypto/heimdal/kadmin/version4.c
@@ -0,0 +1,985 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "kadmin_locl.h"
+#include <krb5-private.h>
+
+#define Principal krb4_Principal
+#define kadm_get krb4_kadm_get
+#undef ALLOC
+#include <krb.h>
+#include <kadm.h>
+#include <krb_err.h>
+#include <kadm_err.h>
+
+RCSID("$Id: version4.c,v 1.16 1999/11/25 22:32:47 assar Exp $");
+
+#define KADM_NO_OPCODE -1
+#define KADM_NO_ENCRYPT -2
+
+/*
+ * make an error packet if we fail encrypting
+ */
+
+static void
+make_you_loose_packet(int code, krb5_data *reply)
+{
+ krb5_data_alloc(reply, KADM_VERSIZE + 4);
+ memcpy(reply->data, KADM_ULOSE, KADM_VERSIZE);
+ _krb5_put_int((char*)reply->data + KADM_VERSIZE, code, 4);
+}
+
+static int
+ret_fields(krb5_storage *sp, char *fields)
+{
+ return sp->fetch(sp, fields, FLDSZ);
+}
+
+static int
+store_fields(krb5_storage *sp, char *fields)
+{
+ return sp->store(sp, fields, FLDSZ);
+}
+
+static void
+ret_vals(krb5_storage *sp, Kadm_vals *vals)
+{
+ int field;
+ char *tmp_string;
+
+ memset(vals, 0, sizeof(*vals));
+
+ ret_fields(sp, vals->fields);
+
+ for(field = 31; field >= 0; field--) {
+ if(IS_FIELD(field, vals->fields)) {
+ switch(field) {
+ case KADM_NAME:
+ krb5_ret_stringz(sp, &tmp_string);
+ strlcpy(vals->name, tmp_string, sizeof(vals->name));
+ free(tmp_string);
+ break;
+ case KADM_INST:
+ krb5_ret_stringz(sp, &tmp_string);
+ strlcpy(vals->instance, tmp_string,
+ sizeof(vals->instance));
+ free(tmp_string);
+ break;
+ case KADM_EXPDATE:
+ krb5_ret_int32(sp, &vals->exp_date);
+ break;
+ case KADM_ATTR:
+ krb5_ret_int16(sp, &vals->attributes);
+ break;
+ case KADM_MAXLIFE:
+ krb5_ret_int8(sp, &vals->max_life);
+ break;
+ case KADM_DESKEY:
+ krb5_ret_int32(sp, &vals->key_high);
+ krb5_ret_int32(sp, &vals->key_low);
+ break;
+#ifdef EXTENDED_KADM
+ case KADM_MODDATE:
+ krb5_ret_int32(sp, &vals->mod_date);
+ break;
+ case KADM_MODNAME:
+ krb5_ret_stringz(sp, &tmp_string);
+ strlcpy(vals->mod_name, tmp_string,
+ sizeof(vals->mod_name));
+ free(tmp_string);
+ break;
+ case KADM_MODINST:
+ krb5_ret_stringz(sp, &tmp_string);
+ strlcpy(vals->mod_instance, tmp_string,
+ sizeof(vals->mod_instance));
+ free(tmp_string);
+ break;
+ case KADM_KVNO:
+ krb5_ret_int8(sp, &vals->key_version);
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ }
+}
+
+static void
+store_vals(krb5_storage *sp, Kadm_vals *vals)
+{
+ int field;
+
+ store_fields(sp, vals->fields);
+
+ for(field = 31; field >= 0; field--) {
+ if(IS_FIELD(field, vals->fields)) {
+ switch(field) {
+ case KADM_NAME:
+ krb5_store_stringz(sp, vals->name);
+ break;
+ case KADM_INST:
+ krb5_store_stringz(sp, vals->instance);
+ break;
+ case KADM_EXPDATE:
+ krb5_store_int32(sp, vals->exp_date);
+ break;
+ case KADM_ATTR:
+ krb5_store_int16(sp, vals->attributes);
+ break;
+ case KADM_MAXLIFE:
+ krb5_store_int8(sp, vals->max_life);
+ break;
+ case KADM_DESKEY:
+ krb5_store_int32(sp, vals->key_high);
+ krb5_store_int32(sp, vals->key_low);
+ break;
+#ifdef EXTENDED_KADM
+ case KADM_MODDATE:
+ krb5_store_int32(sp, vals->mod_date);
+ break;
+ case KADM_MODNAME:
+ krb5_store_stringz(sp, vals->mod_name);
+ break;
+ case KADM_MODINST:
+ krb5_store_stringz(sp, vals->mod_instance);
+ break;
+ case KADM_KVNO:
+ krb5_store_int8(sp, vals->key_version);
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ }
+}
+
+static int
+flags_4_to_5(char *flags)
+{
+ int i;
+ int32_t mask = 0;
+ for(i = 31; i >= 0; i--) {
+ if(IS_FIELD(i, flags))
+ switch(i) {
+ case KADM_NAME:
+ case KADM_INST:
+ mask |= KADM5_PRINCIPAL;
+ case KADM_EXPDATE:
+ mask |= KADM5_PW_EXPIRATION;
+ case KADM_MAXLIFE:
+ mask |= KADM5_MAX_LIFE;
+#ifdef EXTENDED_KADM
+ case KADM_KVNO:
+ mask |= KADM5_KEY_DATA;
+ case KADM_MODDATE:
+ mask |= KADM5_MOD_TIME;
+ case KADM_MODNAME:
+ case KADM_MODINST:
+ mask |= KADM5_MOD_NAME;
+#endif
+ }
+ }
+ return mask;
+}
+
+static void
+ent_to_values(krb5_context context,
+ kadm5_principal_ent_t ent,
+ int32_t mask,
+ Kadm_vals *vals)
+{
+ krb5_error_code ret;
+ char realm[REALM_SZ];
+
+ memset(vals, 0, sizeof(*vals));
+ if(mask & KADM5_PRINCIPAL) {
+ ret = krb5_524_conv_principal(context, ent->principal,
+ vals->name, vals->instance, realm);
+ SET_FIELD(KADM_NAME, vals->fields);
+ SET_FIELD(KADM_INST, vals->fields);
+ }
+ if(mask & KADM5_PW_EXPIRATION) {
+ time_t exp = 0;
+ if(ent->princ_expire_time != 0)
+ exp = ent->princ_expire_time;
+ if(ent->pw_expiration != 0 && (exp == 0 || exp > ent->pw_expiration))
+ exp = ent->pw_expiration;
+ if(exp) {
+ vals->exp_date = exp;
+ SET_FIELD(KADM_EXPDATE, vals->fields);
+ }
+ }
+ if(mask & KADM5_MAX_LIFE) {
+ if(ent->max_life == 0)
+ vals->max_life = 255;
+ else
+ vals->max_life = krb_time_to_life(0, ent->max_life);
+ SET_FIELD(KADM_MAXLIFE, vals->fields);
+ }
+ if(mask & KADM5_KEY_DATA) {
+ if(ent->n_key_data > 0) {
+#ifdef EXTENDED_KADM
+ vals->key_version = ent->key_data[0].key_data_kvno;
+ SET_FIELD(KADM_KVNO, vals->fields);
+#endif
+ }
+ /* XXX the key itself? */
+ }
+#ifdef EXTENDED_KADM
+ if(mask & KADM5_MOD_TIME) {
+ vals->mod_date = ent->mod_date;
+ SET_FIELD(KADM_MODDATE, vals->fields);
+ }
+ if(mask & KADM5_MOD_NAME) {
+ krb5_524_conv_principal(context, ent->mod_name,
+ vals->mod_name, vals->mod_instance, realm);
+ SET_FIELD(KADM_MODNAME, vals->fields);
+ SET_FIELD(KADM_MODINST, vals->fields);
+ }
+#endif
+}
+
+/*
+ * convert the kadm4 values in `vals' to `ent' (and `mask')
+ */
+
+static krb5_error_code
+values_to_ent(krb5_context context,
+ Kadm_vals *vals,
+ kadm5_principal_ent_t ent,
+ int32_t *mask)
+{
+ krb5_error_code ret;
+ *mask = 0;
+ memset(ent, 0, sizeof(*ent));
+
+ if(IS_FIELD(KADM_NAME, vals->fields)) {
+ char *inst = NULL;
+ if(IS_FIELD(KADM_INST, vals->fields))
+ inst = vals->instance;
+ ret = krb5_425_conv_principal(context,
+ vals->name,
+ inst,
+ NULL,
+ &ent->principal);
+ if(ret)
+ return ret;
+ *mask |= KADM5_PRINCIPAL;
+ }
+ if(IS_FIELD(KADM_EXPDATE, vals->fields)) {
+ ent->pw_expiration = vals->exp_date;
+ *mask |= KADM5_PW_EXPIRATION;
+ }
+ if(IS_FIELD(KADM_MAXLIFE, vals->fields)) {
+ ent->max_life = krb_life_to_time(0, vals->max_life);
+ *mask |= KADM5_MAX_LIFE;
+ }
+
+ if(IS_FIELD(KADM_DESKEY, vals->fields)) {
+ int i;
+ ent->key_data = calloc(3, sizeof(*ent->key_data));
+ if(ent->key_data == NULL)
+ return ENOMEM;
+ for(i = 0; i < 3; i++) {
+ u_int32_t key_low, key_high;
+
+ ent->key_data[i].key_data_ver = 2;
+#ifdef EXTENDED_KADM
+ if(IS_FIELD(KADM_KVNO, vals->fields))
+ ent->key_data[i].key_data_kvno = vals->key_version;
+#endif
+ ent->key_data[i].key_data_type[0] = ETYPE_DES_CBC_MD5;
+ ent->key_data[i].key_data_length[0] = 8;
+ if((ent->key_data[i].key_data_contents[0] = malloc(8)) == NULL)
+ return ENOMEM;
+
+ key_low = ntohl(vals->key_low);
+ key_high = ntohl(vals->key_high);
+ memcpy(ent->key_data[i].key_data_contents[0],
+ &key_low, 4);
+ memcpy((char*)ent->key_data[i].key_data_contents[0] + 4,
+ &key_high, 4);
+ ent->key_data[i].key_data_type[1] = KRB5_PW_SALT;
+ ent->key_data[i].key_data_length[1] = 0;
+ ent->key_data[i].key_data_contents[1] = NULL;
+ }
+ ent->key_data[1].key_data_type[0] = ETYPE_DES_CBC_MD4;
+ ent->key_data[2].key_data_type[0] = ETYPE_DES_CBC_CRC;
+ ent->n_key_data = 3;
+ *mask |= KADM5_KEY_DATA;
+ }
+
+#ifdef EXTENDED_KADM
+ if(IS_FIELD(KADM_MODDATE, vals->fields)) {
+ ent->mod_date = vals->mod_date;
+ *mask |= KADM5_MOD_TIME;
+ }
+ if(IS_FIELD(KADM_MODNAME, vals->fields)) {
+ char *inst = NULL;
+ if(IS_FIELD(KADM_MODINST, vals->fields))
+ inst = vals->mod_instance;
+ ret = krb5_425_conv_principal(context,
+ vals->mod_name,
+ inst,
+ NULL,
+ &ent->mod_name);
+ if(ret)
+ return ret;
+ *mask |= KADM5_MOD_NAME;
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Try to translate a KADM5 error code into a v4 kadmin one.
+ */
+
+static int
+error_code(int ret)
+{
+ switch (ret) {
+ case 0:
+ return 0;
+ case KADM5_FAILURE :
+ case KADM5_AUTH_GET :
+ case KADM5_AUTH_ADD :
+ case KADM5_AUTH_MODIFY :
+ case KADM5_AUTH_DELETE :
+ case KADM5_AUTH_INSUFFICIENT :
+ return KADM_UNAUTH;
+ case KADM5_BAD_DB :
+ return KADM_UK_RERROR;
+ case KADM5_DUP :
+ return KADM_INUSE;
+ case KADM5_RPC_ERROR :
+ case KADM5_NO_SRV :
+ return KADM_NO_SERV;
+ case KADM5_NOT_INIT :
+ return KADM_NO_CONN;
+ case KADM5_UNK_PRINC :
+ return KADM_NOENTRY;
+ case KADM5_PASS_Q_TOOSHORT :
+#ifdef KADM_PASS_Q_TOOSHORT
+ return KADM_PASS_Q_TOOSHORT;
+#else
+ return KADM_INSECURE_PW;
+#endif
+ case KADM5_PASS_Q_CLASS :
+#ifdef KADM_PASS_Q_CLASS
+ return KADM_PASS_Q_CLASS;
+#else
+ return KADM_INSECURE_PW;
+#endif
+ case KADM5_PASS_Q_DICT :
+#ifdef KADM_PASS_Q_DICT
+ return KADM_PASS_Q_DICT;
+#else
+ return KADM_INSECURE_PW;
+#endif
+ case KADM5_PASS_REUSE :
+ case KADM5_PASS_TOOSOON :
+ case KADM5_BAD_PASSWORD :
+ return KADM_INSECURE_PW;
+ case KADM5_PROTECT_PRINCIPAL :
+ return KADM_IMMUTABLE;
+ case KADM5_POLICY_REF :
+ case KADM5_INIT :
+ case KADM5_BAD_HIST_KEY :
+ case KADM5_UNK_POLICY :
+ case KADM5_BAD_MASK :
+ case KADM5_BAD_CLASS :
+ case KADM5_BAD_LENGTH :
+ case KADM5_BAD_POLICY :
+ case KADM5_BAD_PRINCIPAL :
+ case KADM5_BAD_AUX_ATTR :
+ case KADM5_BAD_HISTORY :
+ case KADM5_BAD_MIN_PASS_LIFE :
+ case KADM5_BAD_SERVER_HANDLE :
+ case KADM5_BAD_STRUCT_VERSION :
+ case KADM5_OLD_STRUCT_VERSION :
+ case KADM5_NEW_STRUCT_VERSION :
+ case KADM5_BAD_API_VERSION :
+ case KADM5_OLD_LIB_API_VERSION :
+ case KADM5_OLD_SERVER_API_VERSION :
+ case KADM5_NEW_LIB_API_VERSION :
+ case KADM5_NEW_SERVER_API_VERSION :
+ case KADM5_SECURE_PRINC_MISSING :
+ case KADM5_NO_RENAME_SALT :
+ case KADM5_BAD_CLIENT_PARAMS :
+ case KADM5_BAD_SERVER_PARAMS :
+ case KADM5_AUTH_LIST :
+ case KADM5_AUTH_CHANGEPW :
+ case KADM5_BAD_TL_TYPE :
+ case KADM5_MISSING_CONF_PARAMS :
+ case KADM5_BAD_SERVER_NAME :
+ default :
+ return KADM_UNAUTH; /* XXX */
+ }
+}
+
+/*
+ * server functions
+ */
+
+static int
+kadm_ser_cpw(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_storage *message,
+ krb5_storage *reply)
+{
+ char key[8];
+ char *password = NULL;
+ krb5_error_code ret;
+
+ krb5_warnx(context, "v4-compat %s: cpw %s",
+ principal_string, principal_string);
+
+ ret = message->fetch(message, key + 4, 4);
+ ret = message->fetch(message, key, 4);
+ ret = krb5_ret_stringz(message, &password);
+
+ if(password) {
+ krb5_data pwd_data;
+ const char *tmp;
+
+ pwd_data.data = password;
+ pwd_data.length = strlen(password);
+
+ tmp = kadm5_check_password_quality (context, principal, &pwd_data);
+
+ if (tmp != NULL) {
+ krb5_store_stringz (reply, (char *)tmp);
+ ret = KADM5_PASS_Q_DICT;
+ goto fail;
+ }
+ ret = kadm5_chpass_principal(kadm_handle, principal, password);
+ } else {
+ krb5_key_data key_data[3];
+ int i;
+ for(i = 0; i < 3; i++) {
+ key_data[i].key_data_ver = 2;
+ key_data[i].key_data_kvno = 0;
+ /* key */
+ key_data[i].key_data_type[0] = ETYPE_DES_CBC_CRC;
+ key_data[i].key_data_length[0] = 8;
+ key_data[i].key_data_contents[0] = malloc(8);
+ memcpy(key_data[i].key_data_contents[0], &key, 8);
+ /* salt */
+ key_data[i].key_data_type[1] = KRB5_PW_SALT;
+ key_data[i].key_data_length[1] = 0;
+ key_data[i].key_data_contents[1] = NULL;
+ }
+ key_data[0].key_data_type[0] = ETYPE_DES_CBC_MD5;
+ key_data[1].key_data_type[0] = ETYPE_DES_CBC_MD4;
+ ret = kadm5_s_chpass_principal_with_key(kadm_handle,
+ principal, 3, key_data);
+ }
+
+ if(ret != 0) {
+ krb5_store_stringz(reply, (char*)krb5_get_err_text(context, ret));
+ goto fail;
+ }
+ return 0;
+fail:
+ krb5_warn(context, ret, "v4-compat cpw");
+ return error_code(ret);
+}
+
+static int
+kadm_ser_add(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_storage *message,
+ krb5_storage *reply)
+{
+ int32_t mask;
+ kadm5_principal_ent_rec ent, out;
+ Kadm_vals values;
+ krb5_error_code ret;
+ char name[128];
+
+ ret_vals(message, &values);
+
+ ret = values_to_ent(context, &values, &ent, &mask);
+ if(ret)
+ goto fail;
+
+ krb5_unparse_name_fixed(context, ent.principal, name, sizeof(name));
+ krb5_warnx(context, "v4-compat %s: add %s",
+ principal_string, name);
+
+ ret = _kadm5_acl_check_permission (kadm_handle, KADM5_PRIV_ADD);
+ if (ret)
+ goto fail;
+
+ ret = kadm5_s_create_principal_with_key(kadm_handle, &ent, mask);
+ if(ret) {
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ goto fail;
+ }
+
+ mask = KADM5_PRINCIPAL | KADM5_PW_EXPIRATION | KADM5_MAX_LIFE |
+ KADM5_KEY_DATA | KADM5_MOD_TIME | KADM5_MOD_NAME;
+
+ kadm5_get_principal(kadm_handle, ent.principal, &out, mask);
+ ent_to_values(context, &out, mask, &values);
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ kadm5_free_principal_ent(kadm_handle, &out);
+ store_vals(reply, &values);
+ return 0;
+fail:
+ krb5_warn(context, ret, "v4-compat add");
+ return error_code(ret);
+}
+
+static int
+kadm_ser_get(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_storage *message,
+ krb5_storage *reply)
+{
+ krb5_error_code ret;
+ Kadm_vals values;
+ kadm5_principal_ent_rec ent, out;
+ int32_t mask;
+ char flags[FLDSZ];
+ char name[128];
+
+ ret_vals(message, &values);
+ /* XXX BRAIN DAMAGE! these flags are not stored in the same order
+ as in the header */
+ krb5_ret_int8(message, &flags[3]);
+ krb5_ret_int8(message, &flags[2]);
+ krb5_ret_int8(message, &flags[1]);
+ krb5_ret_int8(message, &flags[0]);
+ ret = values_to_ent(context, &values, &ent, &mask);
+ if(ret)
+ goto fail;
+
+ krb5_unparse_name_fixed(context, ent.principal, name, sizeof(name));
+ krb5_warnx(context, "v4-compat %s: get %s",
+ principal_string, name);
+
+ ret = _kadm5_acl_check_permission (kadm_handle, KADM5_PRIV_GET);
+ if (ret)
+ goto fail;
+
+ mask = flags_4_to_5(flags);
+
+ ret = kadm5_get_principal(kadm_handle, ent.principal, &out, mask);
+ kadm5_free_principal_ent(kadm_handle, &ent);
+
+ if (ret)
+ goto fail;
+
+ ent_to_values(context, &out, mask, &values);
+
+ kadm5_free_principal_ent(kadm_handle, &out);
+
+ store_vals(reply, &values);
+ return 0;
+fail:
+ krb5_warn(context, ret, "v4-compat get");
+ return error_code(ret);
+}
+
+static int
+kadm_ser_mod(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_storage *message,
+ krb5_storage *reply)
+{
+ Kadm_vals values1, values2;
+ kadm5_principal_ent_rec ent, out;
+ int32_t mask;
+ krb5_error_code ret;
+ char name[128];
+
+ ret_vals(message, &values1);
+ /* why are the old values sent? is the mask the same in the old and
+ the new entry? */
+ ret_vals(message, &values2);
+
+ ret = values_to_ent(context, &values2, &ent, &mask);
+ if(ret)
+ goto fail;
+
+ krb5_unparse_name_fixed(context, ent.principal, name, sizeof(name));
+ krb5_warnx(context, "v4-compat %s: mod %s",
+ principal_string, name);
+
+ ret = _kadm5_acl_check_permission (kadm_handle, KADM5_PRIV_MODIFY);
+ if (ret)
+ goto fail;
+
+ ret = kadm5_s_modify_principal(kadm_handle, &ent, mask);
+ if(ret) {
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ krb5_warn(context, ret, "kadm5_s_modify_principal");
+ goto fail;
+ }
+
+ ret = kadm5_get_principal(kadm_handle, ent.principal, &out, mask);
+ if(ret) {
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ krb5_warn(context, ret, "kadm5_s_modify_principal");
+ goto fail;
+ }
+
+ ent_to_values(context, &out, mask, &values1);
+
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ kadm5_free_principal_ent(kadm_handle, &out);
+
+ store_vals(reply, &values1);
+ return 0;
+fail:
+ krb5_warn(context, ret, "v4-compat mod");
+ return error_code(ret);
+}
+
+static int
+kadm_ser_del(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_storage *message,
+ krb5_storage *reply)
+{
+ Kadm_vals values;
+ kadm5_principal_ent_rec ent;
+ int32_t mask;
+ krb5_error_code ret;
+ char name[128];
+
+ ret_vals(message, &values);
+
+ ret = values_to_ent(context, &values, &ent, &mask);
+ if(ret)
+ goto fail;
+
+ krb5_unparse_name_fixed(context, ent.principal, name, sizeof(name));
+ krb5_warnx(context, "v4-compat %s: del %s",
+ principal_string, name);
+
+ ret = _kadm5_acl_check_permission (kadm_handle, KADM5_PRIV_DELETE);
+ if (ret)
+ goto fail;
+
+ ret = kadm5_delete_principal(kadm_handle, ent.principal);
+
+ kadm5_free_principal_ent(kadm_handle, &ent);
+
+ if (ret)
+ goto fail;
+
+ return 0;
+fail:
+ krb5_warn(context, ret, "v4-compat add");
+ return error_code(ret);
+}
+
+static int
+dispatch(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_data msg,
+ krb5_data *reply)
+{
+ int retval;
+ int8_t command;
+ krb5_storage *sp_in, *sp_out;
+
+ sp_in = krb5_storage_from_data(&msg);
+ krb5_ret_int8(sp_in, &command);
+
+ sp_out = krb5_storage_emem();
+ sp_out->store(sp_out, KADM_VERSTR, KADM_VERSIZE);
+ krb5_store_int32(sp_out, 0);
+
+ switch(command) {
+ case CHANGE_PW:
+ retval = kadm_ser_cpw(context, kadm_handle, principal,
+ principal_string,
+ sp_in, sp_out);
+ break;
+ case ADD_ENT:
+ retval = kadm_ser_add(context, kadm_handle, principal,
+ principal_string,
+ sp_in, sp_out);
+ break;
+ case GET_ENT:
+ retval = kadm_ser_get(context, kadm_handle, principal,
+ principal_string,
+ sp_in, sp_out);
+ break;
+ case MOD_ENT:
+ retval = kadm_ser_mod(context, kadm_handle, principal,
+ principal_string,
+ sp_in, sp_out);
+ break;
+ case DEL_ENT:
+ retval = kadm_ser_del(context, kadm_handle, principal,
+ principal_string,
+ sp_in, sp_out);
+ break;
+ default:
+ krb5_warnx(context, "v4-compat %s: unknown opcode: %d",
+ principal_string, command);
+ retval = KADM_NO_OPCODE;
+ break;
+ }
+ krb5_storage_free(sp_in);
+ if(retval) {
+ sp_out->seek(sp_out, KADM_VERSIZE, SEEK_SET);
+ krb5_store_int32(sp_out, retval);
+ }
+ krb5_storage_to_data(sp_out, reply);
+ krb5_storage_free(sp_out);
+ return retval;
+}
+
+/*
+ * Decode a v4 kadmin packet in `message' and create a reply in `reply'
+ */
+
+static void
+decode_packet(krb5_context context,
+ struct sockaddr_in *admin_addr,
+ struct sockaddr_in *client_addr,
+ krb5_data message,
+ krb5_data *reply)
+{
+ int ret;
+ KTEXT_ST authent;
+ AUTH_DAT ad;
+ MSG_DAT msg_dat;
+ off_t off = 0;
+ unsigned long rlen;
+ char sname[] = "changepw", sinst[] = "kerberos";
+ unsigned long checksum;
+ des_key_schedule schedule;
+ char *msg = message.data;
+ void *kadm_handle;
+ krb5_principal client;
+ char *client_str;
+
+ if(message.length < KADM_VERSIZE
+ || strncmp(msg, KADM_VERSTR, KADM_VERSIZE) != 0) {
+ make_you_loose_packet (KADM_BAD_VER, reply);
+ return;
+ }
+
+ off = KADM_VERSIZE;
+ off += _krb5_get_int(msg + off, &rlen, 4);
+ memset(&authent, 0, sizeof(authent));
+ authent.length = message.length - rlen - KADM_VERSIZE - 4;
+ memcpy(authent.dat, (char*)msg + off, authent.length);
+ off += authent.length;
+
+ {
+ krb5_principal principal;
+ krb5_keyblock *key;
+
+ ret = krb5_make_principal(context, &principal, NULL,
+ "changepw", "kerberos", NULL);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_make_principal");
+ make_you_loose_packet (KADM_NOMEM, reply);
+ return;
+ }
+ ret = krb5_kt_read_service_key(context,
+ "HDB:",
+ principal,
+ 0,
+/* ETYPE_DES_CBC_CRC,*/
+ ETYPE_DES_CBC_MD5,
+ &key);
+ krb5_free_principal(context, principal);
+ if(ret) {
+ if(ret == KRB5_KT_NOTFOUND)
+ make_you_loose_packet(KADM_NO_AUTH, reply);
+ else
+ /* XXX */
+ make_you_loose_packet(KADM_NO_AUTH, reply);
+ krb5_warn(context, ret, "krb5_kt_read_service_key");
+ return;
+ }
+
+ if(key->keyvalue.length != 8)
+ krb5_abortx(context, "key has wrong length (%lu)",
+ (unsigned long)key->keyvalue.length);
+ krb_set_key(key->keyvalue.data, 0);
+ krb5_free_keyblock(context, key);
+ }
+
+ ret = krb_rd_req(&authent, sname, sinst,
+ client_addr->sin_addr.s_addr, &ad, NULL);
+
+ if(ret) {
+ make_you_loose_packet(krb_err_base + ret, reply);
+ krb5_warnx(context, "krb_rd_req: %d", ret);
+ return;
+ }
+
+ krb5_425_conv_principal(context, ad.pname, ad.pinst, ad.prealm,
+ &client);
+ krb5_unparse_name(context, client, &client_str);
+
+ ret = kadm5_init_with_password_ctx(context,
+ client_str,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ NULL, 0, 0,
+ &kadm_handle);
+ if (ret) {
+ krb5_warn (context, ret, "kadm5_init_with_password_ctx");
+ make_you_loose_packet (KADM_NOMEM, reply);
+ goto out;
+ }
+
+ checksum = des_quad_cksum((des_cblock*)(msg + off), NULL, rlen,
+ 0, &ad.session);
+ if(checksum != ad.checksum) {
+ krb5_warnx(context, "decode_packet: bad checksum");
+ make_you_loose_packet (KADM_BAD_CHK, reply);
+ goto out;
+ }
+ des_set_key(&ad.session, schedule);
+ ret = krb_rd_priv(msg + off, rlen, schedule, &ad.session,
+ client_addr, admin_addr, &msg_dat);
+ if (ret) {
+ make_you_loose_packet (krb_err_base + ret, reply);
+ krb5_warnx(context, "krb_rd_priv: %d", ret);
+ goto out;
+ }
+
+ {
+ krb5_data d, r;
+ int retval;
+
+ d.data = msg_dat.app_data;
+ d.length = msg_dat.app_length;
+
+ retval = dispatch(context, kadm_handle,
+ client, client_str, d, &r);
+ krb5_data_alloc(reply, r.length + 26);
+ reply->length = krb_mk_priv(r.data, reply->data, r.length,
+ schedule, &ad.session,
+ admin_addr, client_addr);
+ if((ssize_t)reply->length < 0) {
+ make_you_loose_packet(KADM_NO_ENCRYPT, reply);
+ goto out;
+ }
+ }
+out:
+ krb5_free_principal(context, client);
+ free(client_str);
+}
+
+void
+handle_v4(krb5_context context,
+ int len,
+ int fd)
+{
+ int first = 1;
+ struct sockaddr_in admin_addr, client_addr;
+ int addr_len;
+ krb5_data message, reply;
+ ssize_t n;
+
+ addr_len = sizeof(client_addr);
+ if (getsockname(fd, (struct sockaddr*)&admin_addr, &addr_len) < 0)
+ krb5_errx (context, 1, "getsockname");
+ addr_len = sizeof(client_addr);
+ if (getpeername(fd, (struct sockaddr*)&client_addr, &addr_len) < 0)
+ krb5_errx (context, 1, "getpeername");
+
+ while(1) {
+ if(first) {
+ /* first time around, we have already read len, and two
+ bytes of the version string */
+ krb5_data_alloc(&message, len);
+ memcpy(message.data, "KA", 2);
+ n = krb5_net_read(context, &fd, (char*)message.data + 2,
+ len - 2);
+ if (n == 0)
+ exit (0);
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+ first = 0;
+ } else {
+ char buf[2];
+ unsigned long tmp;
+ ssize_t n;
+
+ n = krb5_net_read(context, &fd, buf, sizeof(2));
+ if (n == 0)
+ exit (0);
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+ _krb5_get_int(buf, &tmp, 2);
+ krb5_data_alloc(&message, tmp);
+ n = krb5_net_read(context, &fd, message.data, message.length);
+ if (n == 0)
+ krb5_errx (context, 1, "EOF in krb5_net_read");
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+ }
+ decode_packet(context, &admin_addr, &client_addr,
+ message, &reply);
+ krb5_data_free(&message);
+ {
+ char buf[2];
+
+ _krb5_put_int(buf, reply.length, sizeof(buf));
+ n = krb5_net_write(context, &fd, buf, sizeof(buf));
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_write");
+ n = krb5_net_write(context, &fd, reply.data, reply.length);
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_write");
+ krb5_data_free(&reply);
+ }
+ }
+}
diff --git a/crypto/heimdal/kdc/524.c b/crypto/heimdal/kdc/524.c
new file mode 100644
index 000000000000..fb188de24def
--- /dev/null
+++ b/crypto/heimdal/kdc/524.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kdc_locl.h"
+
+RCSID("$Id: 524.c,v 1.10 1999/12/02 17:04:58 joda Exp $");
+
+#ifdef KRB4
+
+krb5_error_code
+do_524(Ticket *t, krb5_data *reply, const char *from, struct sockaddr *addr)
+{
+ krb5_error_code ret = 0;
+ krb5_principal sprinc = NULL;
+ krb5_crypto crypto;
+ hdb_entry *server;
+ Key *skey;
+ krb5_data et_data;
+ EncTicketPart et;
+ EncryptedData ticket;
+ krb5_storage *sp;
+ char *spn = NULL;
+ unsigned char buf[MAX_KTXT_LEN + 4 * 4];
+ size_t len;
+
+ principalname2krb5_principal(&sprinc, t->sname, t->realm);
+ krb5_unparse_name(context, sprinc, &spn);
+ server = db_fetch(sprinc);
+ if(server == NULL){
+ kdc_log(0, "Request to convert ticket from %s for unknown principal %s",
+ from, spn);
+ goto out;
+ }
+ ret = hdb_enctype2key(context, server, t->enc_part.etype, &skey);
+ if(ret){
+ kdc_log(0, "No suitable key found for server (%s) "
+ "when converting ticket from ", spn, from);
+ goto out;
+ }
+ krb5_crypto_init(context, &skey->key, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_TICKET,
+ &t->enc_part,
+ &et_data);
+ krb5_crypto_destroy(context, crypto);
+ if(ret){
+ kdc_log(0, "Failed to decrypt ticket from %s for %s", from, spn);
+ goto out;
+ }
+ ret = krb5_decode_EncTicketPart(context, et_data.data, et_data.length,
+ &et, &len);
+ krb5_data_free(&et_data);
+ if(ret){
+ kdc_log(0, "Failed to decode ticket from %s for %s", from, spn);
+ goto out;
+ }
+ {
+ krb5_principal client;
+ char *cpn;
+ principalname2krb5_principal(&client, et.cname, et.crealm);
+ krb5_unparse_name(context, client, &cpn);
+ kdc_log(1, "524-REQ %s from %s for %s", cpn, from, spn);
+ free(cpn);
+ krb5_free_principal(context, client);
+ }
+
+ if(et.endtime < kdc_time){
+ kdc_log(0, "Ticket expired (%s)", spn);
+ free_EncTicketPart(&et);
+ ret = KRB5KRB_AP_ERR_TKT_EXPIRED;
+ goto out;
+ }
+ if(et.flags.invalid){
+ kdc_log(0, "Ticket not valid (%s)", spn);
+ free_EncTicketPart(&et);
+ ret = KRB5KRB_AP_ERR_TKT_NYV;
+ goto out;
+ }
+ {
+ krb5_addresses *save_caddr, new_addr;
+ krb5_address v4_addr;
+
+ ret = krb5_sockaddr2address(addr, &v4_addr);
+ if(ret) {
+ kdc_log(0, "Failed to convert address (%s)", spn);
+ free_EncTicketPart(&et);
+ goto out;
+ }
+
+ if (et.caddr && !krb5_address_search (context, &v4_addr, et.caddr)) {
+ kdc_log(0, "Incorrect network address (%s)", spn);
+ free_EncTicketPart(&et);
+ krb5_free_address(context, &v4_addr);
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto out;
+ }
+ if(v4_addr.addr_type == KRB5_ADDRESS_INET) {
+ /* we need to collapse the addresses in the ticket to a
+ single address; best guess is to use the address the
+ connection came from */
+ save_caddr = et.caddr;
+ new_addr.len = 1;
+ new_addr.val = &v4_addr;
+ et.caddr = &new_addr;
+ }
+ ret = encode_v4_ticket(buf + sizeof(buf) - 1, sizeof(buf),
+ &et, &t->sname, &len);
+ if(v4_addr.addr_type == KRB5_ADDRESS_INET)
+ et.caddr = save_caddr;
+ }
+ free_EncTicketPart(&et);
+ if(ret){
+ kdc_log(0, "Failed to encode v4 ticket (%s)", spn);
+ goto out;
+ }
+ ret = get_des_key(server, &skey);
+ if(ret){
+ kdc_log(0, "No DES key for server (%s)", spn);
+ goto out;
+ }
+ ret = encrypt_v4_ticket(buf + sizeof(buf) - len, len,
+ skey->key.keyvalue.data, &ticket);
+ if(ret){
+ kdc_log(0, "Failed to encrypt v4 ticket (%s)", spn);
+ goto out;
+ }
+out:
+ /* make reply */
+ memset(buf, 0, sizeof(buf));
+ sp = krb5_storage_from_mem(buf, sizeof(buf));
+ krb5_store_int32(sp, ret);
+ if(ret == 0){
+ krb5_store_int32(sp, server->kvno); /* is this right? */
+ krb5_store_data(sp, ticket.cipher);
+ /* Aargh! This is coded as a KTEXT_ST. */
+ sp->seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR);
+ krb5_store_int32(sp, 0); /* mbz */
+ free_EncryptedData(&ticket);
+ }
+ ret = krb5_storage_to_data(sp, reply);
+ krb5_storage_free(sp);
+
+ if(spn)
+ free(spn);
+ if(sprinc)
+ krb5_free_principal(context, sprinc);
+ hdb_free_entry(context, server);
+ free(server);
+ return ret;
+}
+
+#endif
diff --git a/crypto/heimdal/kdc/Makefile.am b/crypto/heimdal/kdc/Makefile.am
new file mode 100644
index 000000000000..3e3df20504ba
--- /dev/null
+++ b/crypto/heimdal/kdc/Makefile.am
@@ -0,0 +1,62 @@
+# $Id: Makefile.am,v 1.33 1999/05/13 23:32:35 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+bin_PROGRAMS = string2key
+
+sbin_PROGRAMS = kstash
+
+libexec_PROGRAMS = hprop hpropd kdc
+
+man_MANS = kdc.8 kstash.8 hprop.8 hpropd.8
+
+hprop_SOURCES = hprop.c hprop-common.c hprop.h kadb.h
+hpropd_SOURCES = hpropd.c hprop-common.c hprop.h
+
+kstash_SOURCES = kstash.c headers.h
+
+string2key_SOURCES = string2key.c headers.h
+
+kdc_SOURCES = \
+ 524.c \
+ config.c \
+ connect.c \
+ kaserver.c \
+ kdc_locl.h \
+ kerberos4.c \
+ kerberos4.h \
+ kerberos5.c \
+ log.c \
+ main.c \
+ misc.c \
+ rx.h
+
+
+hprop_LDADD = \
+ $(top_builddir)/lib/hdb/libhdb.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_kdb) $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken) \
+ $(DBLIB)
+
+hpropd_LDADD = \
+ $(top_builddir)/lib/hdb/libhdb.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_kdb) $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken) \
+ $(DBLIB)
+
+LDADD = $(top_builddir)/lib/hdb/libhdb.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken) \
+ $(DBLIB)
+
diff --git a/crypto/heimdal/kdc/Makefile.in b/crypto/heimdal/kdc/Makefile.in
new file mode 100644
index 000000000000..6ba90e1355cb
--- /dev/null
+++ b/crypto/heimdal/kdc/Makefile.in
@@ -0,0 +1,799 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.33 1999/05/13 23:32:35 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+bin_PROGRAMS = string2key
+
+sbin_PROGRAMS = kstash
+
+libexec_PROGRAMS = hprop hpropd kdc
+
+man_MANS = kdc.8 kstash.8 hprop.8 hpropd.8
+
+hprop_SOURCES = hprop.c hprop-common.c hprop.h kadb.h
+hpropd_SOURCES = hpropd.c hprop-common.c hprop.h
+
+kstash_SOURCES = kstash.c headers.h
+
+string2key_SOURCES = string2key.c headers.h
+
+kdc_SOURCES = 524.c config.c connect.c kaserver.c kdc_locl.h kerberos4.c kerberos4.h kerberos5.c log.c main.c misc.c rx.h
+
+
+hprop_LDADD = $(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la $(LIB_kdb) $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken) $(DBLIB)
+
+
+hpropd_LDADD = $(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la $(LIB_kdb) $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken) $(DBLIB)
+
+
+LDADD = $(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken) $(DBLIB)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = string2key$(EXEEXT)
+libexec_PROGRAMS = hprop$(EXEEXT) hpropd$(EXEEXT) kdc$(EXEEXT)
+sbin_PROGRAMS = kstash$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) $(sbin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+string2key_OBJECTS = string2key.$(OBJEXT)
+string2key_LDADD = $(LDADD)
+string2key_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+string2key_LDFLAGS =
+hprop_OBJECTS = hprop.$(OBJEXT) hprop-common.$(OBJEXT)
+hprop_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+hprop_LDFLAGS =
+hpropd_OBJECTS = hpropd.$(OBJEXT) hprop-common.$(OBJEXT)
+hpropd_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+hpropd_LDFLAGS =
+kdc_OBJECTS = 524.$(OBJEXT) config.$(OBJEXT) connect.$(OBJEXT) \
+kaserver.$(OBJEXT) kerberos4.$(OBJEXT) kerberos5.$(OBJEXT) \
+log.$(OBJEXT) main.$(OBJEXT) misc.$(OBJEXT)
+kdc_LDADD = $(LDADD)
+kdc_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+kdc_LDFLAGS =
+kstash_OBJECTS = kstash.$(OBJEXT)
+kstash_LDADD = $(LDADD)
+kstash_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+kstash_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man8dir = $(mandir)/man8
+MANS = $(man_MANS)
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(string2key_SOURCES) $(hprop_SOURCES) $(hpropd_SOURCES) $(kdc_SOURCES) $(kstash_SOURCES)
+OBJECTS = $(string2key_OBJECTS) $(hprop_OBJECTS) $(hpropd_OBJECTS) $(kdc_OBJECTS) $(kstash_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign kdc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-libexecPROGRAMS:
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+
+distclean-libexecPROGRAMS:
+
+maintainer-clean-libexecPROGRAMS:
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-sbinPROGRAMS:
+
+clean-sbinPROGRAMS:
+ -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
+
+distclean-sbinPROGRAMS:
+
+maintainer-clean-sbinPROGRAMS:
+
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(sbindir)
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+string2key$(EXEEXT): $(string2key_OBJECTS) $(string2key_DEPENDENCIES)
+ @rm -f string2key$(EXEEXT)
+ $(LINK) $(string2key_LDFLAGS) $(string2key_OBJECTS) $(string2key_LDADD) $(LIBS)
+
+hprop$(EXEEXT): $(hprop_OBJECTS) $(hprop_DEPENDENCIES)
+ @rm -f hprop$(EXEEXT)
+ $(LINK) $(hprop_LDFLAGS) $(hprop_OBJECTS) $(hprop_LDADD) $(LIBS)
+
+hpropd$(EXEEXT): $(hpropd_OBJECTS) $(hpropd_DEPENDENCIES)
+ @rm -f hpropd$(EXEEXT)
+ $(LINK) $(hpropd_LDFLAGS) $(hpropd_OBJECTS) $(hpropd_LDADD) $(LIBS)
+
+kdc$(EXEEXT): $(kdc_OBJECTS) $(kdc_DEPENDENCIES)
+ @rm -f kdc$(EXEEXT)
+ $(LINK) $(kdc_LDFLAGS) $(kdc_OBJECTS) $(kdc_LDADD) $(LIBS)
+
+kstash$(EXEEXT): $(kstash_OBJECTS) $(kstash_DEPENDENCIES)
+ @rm -f kstash$(EXEEXT)
+ $(LINK) $(kstash_LDFLAGS) $(kstash_OBJECTS) $(kstash_LDADD) $(LIBS)
+
+install-man8:
+ $(mkinstalldirs) $(DESTDIR)$(man8dir)
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
+ done
+
+uninstall-man8:
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man8dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man8
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man8
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = kdc
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS install-libexecPROGRAMS \
+ install-sbinPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-man install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS uninstall-libexecPROGRAMS \
+ uninstall-sbinPROGRAMS uninstall-man
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(MANS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(libexecdir) \
+ $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-libexecPROGRAMS \
+ mostlyclean-sbinPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-libexecPROGRAMS clean-sbinPROGRAMS \
+ clean-compile clean-libtool clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-libexecPROGRAMS \
+ distclean-sbinPROGRAMS distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-libexecPROGRAMS \
+ maintainer-clean-sbinPROGRAMS maintainer-clean-compile \
+ maintainer-clean-libtool maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-libexecPROGRAMS distclean-libexecPROGRAMS \
+clean-libexecPROGRAMS maintainer-clean-libexecPROGRAMS \
+uninstall-libexecPROGRAMS install-libexecPROGRAMS \
+mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS clean-sbinPROGRAMS \
+maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \
+install-sbinPROGRAMS mostlyclean-compile distclean-compile \
+clean-compile maintainer-clean-compile mostlyclean-libtool \
+distclean-libtool clean-libtool maintainer-clean-libtool install-man8 \
+uninstall-man8 install-man uninstall-man tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/kdc/config.c b/crypto/heimdal/kdc/config.c
new file mode 100644
index 000000000000..ba76432c2331
--- /dev/null
+++ b/crypto/heimdal/kdc/config.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kdc_locl.h"
+#include <getarg.h>
+#include <parse_bytes.h>
+
+RCSID("$Id: config.c,v 1.28 1999/12/02 17:04:58 joda Exp $");
+
+static char *config_file;
+int require_preauth = -1;
+char *keyfile;
+static char *max_request_str;
+size_t max_request;
+time_t kdc_warn_pwexpire;
+struct dbinfo *databases;
+HDB **db;
+int num_db;
+char *port_str;
+int enable_http = -1;
+krb5_boolean encode_as_rep_as_tgs_rep; /* bug compatibility */
+
+krb5_boolean check_ticket_addresses;
+krb5_boolean allow_null_ticket_addresses;
+
+#ifdef KRB4
+char *v4_realm;
+#endif
+#ifdef KASERVER
+krb5_boolean enable_kaserver = -1;
+#endif
+
+static int help_flag;
+static int version_flag;
+
+static struct getargs args[] = {
+ {
+ "config-file", 'c', arg_string, &config_file,
+ "location of config file", "file"
+ },
+ {
+ "require-preauth", 'p', arg_negative_flag, &require_preauth,
+ "don't require pa-data in as-reqs"
+ },
+ {
+ "key-file", 'k', arg_string, &keyfile,
+ "location of master key file", "file"
+ },
+ {
+ "max-request", 0, arg_string, &max_request,
+ "max size for a kdc-request", "size"
+ },
+#if 0
+ {
+ "database", 'd', arg_string, &databases,
+ "location of database", "database"
+ },
+#endif
+ { "enable-http", 'H', arg_flag, &enable_http, "turn on HTTP support" },
+#ifdef KRB4
+ {
+ "v4-realm", 'r', arg_string, &v4_realm,
+ "realm to serve v4-requests for"
+ },
+#endif
+#ifdef KASERVER
+ {
+ "kaserver", 'K', arg_negative_flag, &enable_kaserver,
+ "turn off kaserver support"
+ },
+#endif
+ { "ports", 'P', arg_string, &port_str,
+ "ports to listen to"
+ },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 'v', arg_flag, &version_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int ret)
+{
+ arg_printusage (args, num_args, NULL, "");
+ exit (ret);
+}
+
+static void
+get_dbinfo(krb5_config_section *cf)
+{
+ krb5_config_binding *top_binding = NULL;
+ krb5_config_binding *db_binding;
+ krb5_config_binding *default_binding = NULL;
+ struct dbinfo *di, **dt;
+ const char *default_dbname = HDB_DEFAULT_DB;
+ const char *default_mkey = HDB_DB_DIR "/m-key";
+ const char *p;
+
+ databases = NULL;
+ dt = &databases;
+ while((db_binding = (krb5_config_binding *)
+ krb5_config_get_next(context, cf, &top_binding,
+ krb5_config_list,
+ "kdc",
+ "database",
+ NULL))) {
+ p = krb5_config_get_string(context, db_binding, "realm", NULL);
+ if(p == NULL) {
+ if(default_binding) {
+ krb5_warnx(context, "WARNING: more than one realm-less "
+ "database specification");
+ krb5_warnx(context, "WARNING: using the first encountered");
+ } else
+ default_binding = db_binding;
+ continue;
+ }
+ di = calloc(1, sizeof(*di));
+ di->realm = strdup(p);
+ p = krb5_config_get_string(context, db_binding, "dbname", NULL);
+ if(p)
+ di->dbname = strdup(p);
+ p = krb5_config_get_string(context, db_binding, "mkey_file", NULL);
+ if(p)
+ di->mkey_file = strdup(p);
+ *dt = di;
+ dt = &di->next;
+ }
+ if(default_binding) {
+ di = calloc(1, sizeof(*di));
+ p = krb5_config_get_string(context, default_binding, "dbname", NULL);
+ if(p) {
+ di->dbname = strdup(p);
+ default_dbname = p;
+ }
+ p = krb5_config_get_string(context, default_binding, "mkey_file", NULL);
+ if(p) {
+ di->mkey_file = strdup(p);
+ default_mkey = p;
+ }
+ *dt = di;
+ dt = &di->next;
+ } else {
+ di = calloc(1, sizeof(*di));
+ di->dbname = strdup(default_dbname);
+ di->mkey_file = strdup(default_mkey);
+ *dt = di;
+ dt = &di->next;
+ }
+ for(di = databases; di; di = di->next) {
+ if(di->dbname == NULL)
+ di->dbname = strdup(default_dbname);
+ if(di->mkey_file == NULL) {
+ p = strrchr(di->dbname, '.');
+ if(p == NULL || strchr(p, '/') != NULL)
+ asprintf(&di->mkey_file, "%s.mkey", di->dbname);
+ else
+ asprintf(&di->mkey_file, "%.*s.mkey",
+ (int)(p - di->dbname), di->dbname);
+ }
+ }
+}
+
+void
+configure(int argc, char **argv)
+{
+ krb5_config_section *cf = NULL;
+ int optind = 0;
+ int e;
+ const char *p;
+
+ while((e = getarg(args, num_args, argc, argv, &optind)))
+ warnx("error at argument `%s'", argv[optind]);
+
+ if(help_flag)
+ usage (0);
+
+ if (version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage(1);
+
+ if(config_file == NULL)
+ config_file = HDB_DB_DIR "/kdc.conf";
+
+ if(krb5_config_parse_file(config_file, &cf))
+ cf = NULL;
+
+ if(keyfile == NULL){
+ p = krb5_config_get_string (context, cf,
+ "kdc",
+ "key-file",
+ NULL);
+ if(p)
+ keyfile = strdup(p);
+ }
+
+
+ get_dbinfo(cf);
+
+ if(max_request_str){
+ max_request = parse_bytes(max_request_str, NULL);
+ }
+
+ if(max_request == 0){
+ p = krb5_config_get_string (context,
+ cf,
+ "kdc",
+ "max-request",
+ NULL);
+ if(p)
+ max_request = parse_bytes(p, NULL);
+ }
+
+ if(require_preauth == -1)
+ require_preauth = krb5_config_get_bool(context, cf, "kdc",
+ "require-preauth", NULL);
+
+ if(port_str == NULL){
+ p = krb5_config_get_string(context, cf, "kdc", "ports", NULL);
+ if (p != NULL)
+ port_str = strdup(p);
+ }
+ if(enable_http == -1)
+ enable_http = krb5_config_get_bool(context, cf, "kdc",
+ "enable-http", NULL);
+ check_ticket_addresses =
+ krb5_config_get_bool(context, cf, "kdc",
+ "check-ticket-addresses", NULL);
+ allow_null_ticket_addresses =
+ krb5_config_get_bool(context, cf, "kdc",
+ "allow-null-ticket-addresses", NULL);
+#ifdef KRB4
+ if(v4_realm == NULL){
+ p = krb5_config_get_string (context, cf,
+ "kdc",
+ "v4-realm",
+ NULL);
+ if(p)
+ v4_realm = strdup(p);
+ }
+#endif
+#ifdef KASERVER
+ if (enable_kaserver == -1)
+ enable_kaserver = krb5_config_get_bool_default(context, cf, TRUE,
+ "kdc",
+ "enable-kaserver",
+ NULL);
+#endif
+
+ encode_as_rep_as_tgs_rep = krb5_config_get_bool(context, cf, "kdc",
+ "encode_as_rep_as_tgs_rep",
+ NULL);
+
+ kdc_warn_pwexpire = krb5_config_get_time (context, cf,
+ "kdc",
+ "kdc_warn_pwexpire",
+ NULL);
+ kdc_openlog(cf);
+ if(cf)
+ krb5_config_file_free (context, cf);
+ if(max_request == 0)
+ max_request = 64 * 1024;
+ if(require_preauth == -1)
+ require_preauth = 1;
+ if (port_str == NULL)
+ port_str = "+";
+#ifdef KRB4
+ if(v4_realm == NULL){
+ v4_realm = malloc(40); /* REALM_SZ */
+ krb_get_lrealm(v4_realm, 1);
+ }
+#endif
+}
diff --git a/crypto/heimdal/kdc/connect.c b/crypto/heimdal/kdc/connect.c
new file mode 100644
index 000000000000..62b5bea7d874
--- /dev/null
+++ b/crypto/heimdal/kdc/connect.c
@@ -0,0 +1,727 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kdc_locl.h"
+
+RCSID("$Id: connect.c,v 1.68 1999/12/02 17:04:58 joda Exp $");
+
+struct port_desc{
+ int family;
+ int type;
+ int port;
+};
+
+static struct port_desc *ports;
+static int num_ports;
+
+static void
+add_port(int family, int port, const char *protocol)
+{
+ int type;
+ int i;
+
+ if(strcmp(protocol, "udp") == 0)
+ type = SOCK_DGRAM;
+ else if(strcmp(protocol, "tcp") == 0)
+ type = SOCK_STREAM;
+ else
+ return;
+ for(i = 0; i < num_ports; i++){
+ if(ports[i].type == type
+ && ports[i].port == port
+ && ports[i].family == family)
+ return;
+ }
+ ports = realloc(ports, (num_ports + 1) * sizeof(*ports));
+ ports[num_ports].family = family;
+ ports[num_ports].type = type;
+ ports[num_ports].port = port;
+ num_ports++;
+}
+
+static void
+add_port_service(int family, const char *service, int port,
+ const char *protocol)
+{
+ port = krb5_getportbyname (context, service, protocol, port);
+ add_port (family, port, protocol);
+}
+
+static void
+add_port_string (int family, const char *port_str, const char *protocol)
+{
+ struct servent *sp;
+ int port;
+
+ sp = roken_getservbyname (port_str, protocol);
+ if (sp != NULL) {
+ port = sp->s_port;
+ } else {
+ char *end;
+
+ port = htons(strtol(port_str, &end, 0));
+ if (end == port_str)
+ return;
+ }
+ add_port (family, port, protocol);
+}
+
+static void
+add_standard_ports (int family)
+{
+ add_port_service(family, "kerberos", 88, "udp");
+ add_port_service(family, "kerberos", 88, "tcp");
+ add_port_service(family, "kerberos-sec", 88, "udp");
+ add_port_service(family, "kerberos-sec", 88, "tcp");
+ add_port_service(family, "kerberos-iv", 750, "udp");
+ add_port_service(family, "kerberos-iv", 750, "tcp");
+ if(enable_http)
+ add_port_service(family, "http", 80, "tcp");
+#ifdef KASERVER
+ if (enable_kaserver)
+ add_port_service(family, "afs3-kaserver", 7004, "udp");
+#endif
+}
+
+static void
+parse_ports(const char *str)
+{
+ char *pos = NULL;
+ char *p;
+ char *str_copy = strdup (str);
+
+ p = strtok_r(str_copy, " \t", &pos);
+ while(p != NULL) {
+ if(strcmp(p, "+") == 0) {
+#ifdef HAVE_IPV6
+ add_standard_ports(AF_INET6);
+#endif
+ add_standard_ports(AF_INET);
+ } else {
+ char *q = strchr(p, '/');
+ if(q){
+ *q++ = 0;
+#ifdef HAVE_IPV6
+ add_port_string(AF_INET6, p, q);
+#endif
+ add_port_string(AF_INET, p, q);
+ }else {
+#ifdef HAVE_IPV6
+ add_port_string(AF_INET6, p, "udp");
+ add_port_string(AF_INET6, p, "tcp");
+#endif
+ add_port_string(AF_INET, p, "udp");
+ add_port_string(AF_INET, p, "tcp");
+ }
+ }
+
+ p = strtok_r(NULL, " \t", &pos);
+ }
+ free (str_copy);
+}
+
+struct descr {
+ int s;
+ int type;
+ unsigned char *buf;
+ size_t size;
+ size_t len;
+ time_t timeout;
+};
+
+/*
+ * Create the socket (family, type, port) in `d'
+ */
+
+static void
+init_socket(struct descr *d, krb5_address *a, int family, int type, int port)
+{
+ krb5_error_code ret;
+ struct sockaddr_storage __ss;
+ struct sockaddr *sa = (struct sockaddr *)&__ss;
+ int sa_size;
+
+ memset(d, 0, sizeof(*d));
+ d->s = -1;
+
+ ret = krb5_addr2sockaddr (a, sa, &sa_size, port);
+ if (ret) {
+ krb5_warn(context, ret, "krb5_anyaddr");
+ close(d->s);
+ d->s = -1;
+ return;
+ }
+
+ if (sa->sa_family != family)
+ return;
+
+ d->s = socket(family, type, 0);
+ if(d->s < 0){
+ krb5_warn(context, errno, "socket(%d, %d, 0)", family, type);
+ d->s = -1;
+ return;
+ }
+#if defined(HAVE_SETSOCKOPT) && defined(SOL_SOCKET) && defined(SO_REUSEADDR)
+ {
+ int one = 1;
+ setsockopt(d->s, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
+ }
+#endif
+ d->type = type;
+
+ if(bind(d->s, sa, sa_size) < 0){
+ krb5_warn(context, errno, "bind(%d)", ntohs(port));
+ close(d->s);
+ d->s = -1;
+ return;
+ }
+ if(type == SOCK_STREAM && listen(d->s, SOMAXCONN) < 0){
+ krb5_warn(context, errno, "listen");
+ close(d->s);
+ return;
+ }
+}
+
+/*
+ * Allocate descriptors for all the sockets that we should listen on
+ * and return the number of them.
+ */
+
+static int
+init_sockets(struct descr **desc)
+{
+ krb5_error_code ret;
+ int i, j;
+ struct descr *d;
+ int num = 0;
+ krb5_addresses addresses;
+
+ ret = krb5_get_all_server_addrs (context, &addresses);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_all_server_addrs");
+ parse_ports(port_str);
+ d = malloc(addresses.len * num_ports * sizeof(*d));
+ if (d == NULL)
+ krb5_errx(context, 1, "malloc(%u) failed", num_ports * sizeof(*d));
+
+ for (i = 0; i < num_ports; i++){
+ for (j = 0; j < addresses.len; ++j) {
+ init_socket(&d[num], &addresses.val[j],
+ ports[i].family, ports[i].type, ports[i].port);
+ if(d[num].s != -1){
+ char a_str[80];
+ size_t len;
+
+ krb5_print_address (&addresses.val[j], a_str,
+ sizeof(a_str), &len);
+
+ kdc_log(5, "listening on %s port %u/%s",
+ a_str,
+ ntohs(ports[i].port),
+ (ports[i].type == SOCK_STREAM) ? "tcp" : "udp");
+ /* XXX */
+ num++;
+ }
+ }
+ }
+ krb5_free_addresses (context, &addresses);
+ d = realloc(d, num * sizeof(*d));
+ if (d == NULL && num != 0)
+ krb5_errx(context, 1, "realloc(%u) failed", num * sizeof(*d));
+ *desc = d;
+ return num;
+}
+
+
+static int
+process_request(unsigned char *buf,
+ size_t len,
+ krb5_data *reply,
+ int *sendlength,
+ const char *from,
+ struct sockaddr *addr)
+{
+ KDC_REQ req;
+#ifdef KRB4
+ Ticket ticket;
+#endif
+ krb5_error_code ret;
+ size_t i;
+
+ gettimeofday(&now, NULL);
+ if(decode_AS_REQ(buf, len, &req, &i) == 0){
+ ret = as_rep(&req, reply, from, addr);
+ free_AS_REQ(&req);
+ return ret;
+ }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
+ ret = tgs_rep(&req, reply, from, addr);
+ free_TGS_REQ(&req);
+ return ret;
+ }
+#ifdef KRB4
+ else if(maybe_version4(buf, len)){
+ *sendlength = 0; /* elbitapmoc sdrawkcab XXX */
+ do_version4(buf, len, reply, from, (struct sockaddr_in*)addr);
+ return 0;
+ }else if(decode_Ticket(buf, len, &ticket, &i) == 0){
+ ret = do_524(&ticket, reply, from, addr);
+ free_Ticket(&ticket);
+ return ret;
+ }
+#endif
+#ifdef KASERVER
+ else if (enable_kaserver) {
+ ret = do_kaserver (buf, len, reply, from, (struct sockaddr_in*)addr);
+ return ret;
+ }
+#endif
+
+ return -1;
+}
+
+static void
+addr_to_string(struct sockaddr *addr, size_t addr_len, char *str, size_t len)
+{
+ krb5_address a;
+ krb5_sockaddr2address(addr, &a);
+ if(krb5_print_address(&a, str, len, &len) == 0) {
+ krb5_free_address(context, &a);
+ return;
+ }
+ krb5_free_address(context, &a);
+ snprintf(str, len, "<family=%d>", addr->sa_family);
+}
+
+static void
+do_request(void *buf, size_t len, int sendlength,
+ int socket, struct sockaddr *from, size_t from_len)
+{
+ krb5_error_code ret;
+ krb5_data reply;
+ char addr[128];
+
+ addr_to_string(from, from_len, addr, sizeof(addr));
+
+ reply.length = 0;
+ ret = process_request(buf, len, &reply, &sendlength, addr, from);
+ if(reply.length){
+ kdc_log(5, "sending %d bytes to %s", reply.length, addr);
+ if(sendlength){
+ unsigned char len[4];
+ len[0] = (reply.length >> 24) & 0xff;
+ len[1] = (reply.length >> 16) & 0xff;
+ len[2] = (reply.length >> 8) & 0xff;
+ len[3] = reply.length & 0xff;
+ if(sendto(socket, len, sizeof(len), 0, from, from_len) < 0) {
+ kdc_log (0, "sendto(%s): %s", addr, strerror(errno));
+ krb5_data_free(&reply);
+ return;
+ }
+ }
+ if(sendto(socket, reply.data, reply.length, 0, from, from_len) < 0) {
+ kdc_log (0, "sendto(%s): %s", addr, strerror(errno));
+ krb5_data_free(&reply);
+ return;
+ }
+ krb5_data_free(&reply);
+ }
+ if(ret)
+ kdc_log(0, "Failed processing %lu byte request from %s",
+ (unsigned long)len, addr);
+}
+
+static void
+handle_udp(struct descr *d)
+{
+ unsigned char *buf;
+ struct sockaddr_storage __ss;
+ struct sockaddr *sa = (struct sockaddr *)&__ss;
+ int from_len;
+ int n;
+
+ buf = malloc(max_request);
+ if(buf == NULL){
+ kdc_log(0, "Failed to allocate %u bytes", max_request);
+ return;
+ }
+
+ from_len = sizeof(__ss);
+ n = recvfrom(d->s, buf, max_request, 0,
+ sa, &from_len);
+ if(n < 0){
+ krb5_warn(context, errno, "recvfrom");
+ goto out;
+ }
+ if(n == 0) {
+ goto out;
+ }
+ do_request(buf, n, 0, d->s, sa, from_len);
+out:
+ free (buf);
+}
+
+static void
+clear_descr(struct descr *d)
+{
+ if(d->buf)
+ memset(d->buf, 0, d->size);
+ d->len = 0;
+ if(d->s != -1)
+ close(d->s);
+ d->s = -1;
+}
+
+
+/* remove HTTP %-quoting from buf */
+static int
+de_http(char *buf)
+{
+ char *p, *q;
+ for(p = q = buf; *p; p++, q++) {
+ if(*p == '%') {
+ unsigned int x;
+ if(sscanf(p + 1, "%2x", &x) != 1)
+ return -1;
+ *q = x;
+ p += 2;
+ } else
+ *q = *p;
+ }
+ *q = '\0';
+ return 0;
+}
+
+#define TCP_TIMEOUT 4
+
+/*
+ * accept a new TCP connection on `d[index]'
+ */
+
+static void
+add_new_tcp (struct descr *d, int index, int min_free)
+{
+ struct sockaddr_storage __ss;
+ struct sockaddr *sa = (struct sockaddr *)&__ss;
+ int s;
+ int from_len;
+
+ from_len = sizeof(__ss);
+ s = accept(d[index].s, sa, &from_len);
+ if(s < 0){
+ krb5_warn(context, errno, "accept");
+ return;
+ }
+ if(min_free == -1){
+ close(s);
+ return;
+ }
+
+ d[min_free].s = s;
+ d[min_free].timeout = time(NULL) + TCP_TIMEOUT;
+ d[min_free].type = SOCK_STREAM;
+}
+
+/*
+ * Grow `d' to handle at least `n'.
+ * Return != 0 if fails
+ */
+
+static int
+grow_descr (struct descr *d, size_t n)
+{
+ if (d->size - d->len < n) {
+ unsigned char *tmp;
+
+ d->size += max(1024, d->len + n);
+ if (d->size >= max_request) {
+ kdc_log(0, "Request exceeds max request size (%u bytes).",
+ d->size);
+ clear_descr(d);
+ return -1;
+ }
+ tmp = realloc (d->buf, d->size);
+ if (tmp == NULL) {
+ kdc_log(0, "Failed to re-allocate %u bytes.", d->size);
+ clear_descr(d);
+ return -1;
+ }
+ d->buf = tmp;
+ }
+ return 0;
+}
+
+/*
+ * Try to handle the TCP data at `d->buf, d->len'.
+ * Return -1 if failed, 0 if succesful, and 1 if data is complete.
+ */
+
+static int
+handle_vanilla_tcp (struct descr *d)
+{
+ krb5_storage *sp;
+ int32_t len;
+
+ sp = krb5_storage_from_mem(d->buf, d->len);
+ if (sp == NULL) {
+ kdc_log (0, "krb5_storage_from_mem failed");
+ return -1;
+ }
+ krb5_ret_int32(sp, &len);
+ krb5_storage_free(sp);
+ if(d->len - 4 >= len) {
+ memcpy(d->buf, d->buf + 4, d->len - 4);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Try to handle the TCP/HTTP data at `d->buf, d->len'.
+ * Return -1 if failed, 0 if succesful, and 1 if data is complete.
+ */
+
+static int
+handle_http_tcp (struct descr *d, const char *addr)
+{
+ char *s, *p, *t;
+ void *data;
+ char *proto;
+ int len;
+
+ s = (char *)d->buf;
+
+ p = strstr(s, "\r\n");
+ if (p == NULL) {
+ kdc_log(0, "Malformed HTTP request from %s", addr);
+ return -1;
+ }
+ *p = 0;
+
+ p = NULL;
+ t = strtok_r(s, " \t", &p);
+ if (t == NULL) {
+ kdc_log(0, "Malformed HTTP request from %s", addr);
+ return -1;
+ }
+ t = strtok_r(NULL, " \t", &p);
+ if(t == NULL) {
+ kdc_log(0, "Malformed HTTP request from %s", addr);
+ return -1;
+ }
+ data = malloc(strlen(t));
+ if (data == NULL) {
+ kdc_log(0, "Failed to allocate %u bytes", strlen(t));
+ return -1;
+ }
+ if(*t == '/')
+ t++;
+ if(de_http(t) != 0) {
+ kdc_log(0, "Malformed HTTP request from %s", addr);
+ kdc_log(5, "Request: %s", t);
+ free(data);
+ return -1;
+ }
+ proto = strtok_r(NULL, " \t", &p);
+ if (proto == NULL) {
+ kdc_log(0, "Malformed HTTP request from %s", addr);
+ free(data);
+ return -1;
+ }
+ len = base64_decode(t, data);
+ if(len <= 0){
+ const char *msg =
+ " 404 Not found\r\n"
+ "Server: Heimdal/" VERSION "\r\n"
+ "Content-type: text/html\r\n"
+ "Content-transfer-encoding: 8bit\r\n\r\n"
+ "<TITLE>404 Not found</TITLE>\r\n"
+ "<H1>404 Not found</H1>\r\n"
+ "That page doesn't exist, maybe you are looking for "
+ "<A HREF=\"http://www.pdc.kth.se/heimdal\">Heimdal</A>?\r\n";
+ write(d->s, proto, strlen(proto));
+ write(d->s, msg, strlen(msg));
+ kdc_log(0, "HTTP request from %s is non KDC request", addr);
+ kdc_log(5, "Request: %s", t);
+ free(data);
+ return -1;
+ }
+ {
+ const char *msg =
+ " 200 OK\r\n"
+ "Server: Heimdal/" VERSION "\r\n"
+ "Content-type: application/octet-stream\r\n"
+ "Content-transfer-encoding: binary\r\n\r\n";
+ write(d->s, proto, strlen(proto));
+ write(d->s, msg, strlen(msg));
+ }
+ memcpy(d->buf, data, len);
+ d->len = len;
+ free(data);
+ return 1;
+}
+
+/*
+ * Handle incoming data to the TCP socket in `d[index]'
+ */
+
+static void
+handle_tcp(struct descr *d, int index, int min_free)
+{
+ unsigned char buf[1024];
+ char addr[32];
+ struct sockaddr_storage __ss;
+ struct sockaddr *sa = (struct sockaddr *)&__ss;
+ int from_len;
+ int n;
+ int ret = 0;
+
+ if (d[index].timeout == 0) {
+ add_new_tcp (d, index, min_free);
+ return;
+ }
+
+ /*
+ * We can't trust recvfrom to return an address so we always call
+ * getpeername.
+ */
+
+ n = recvfrom(d[index].s, buf, sizeof(buf), 0, NULL, NULL);
+ if(n < 0){
+ krb5_warn(context, errno, "recvfrom");
+ return;
+ }
+ from_len = sizeof(__ss);
+ if (getpeername(d[index].s, sa, &from_len) < 0) {
+ krb5_warn(context, errno, "getpeername");
+ return;
+ }
+ addr_to_string(sa, from_len, addr, sizeof(addr));
+ if (grow_descr (&d[index], n))
+ return;
+ memcpy(d[index].buf + d[index].len, buf, n);
+ d[index].len += n;
+ if(d[index].len > 4 && d[index].buf[0] == 0) {
+ ret = handle_vanilla_tcp (&d[index]);
+ } else if(enable_http &&
+ d[index].len >= 4 &&
+ strncmp((char *)d[index].buf, "GET ", 4) == 0 &&
+ strncmp((char *)d[index].buf + d[index].len - 4,
+ "\r\n\r\n", 4) == 0) {
+ ret = handle_http_tcp (&d[index], addr);
+ if (ret < 0)
+ clear_descr (d + index);
+ } else if (d[index].len > 4) {
+ kdc_log (0, "TCP data of strange type from %s", addr);
+ return;
+ }
+ if (ret < 0)
+ return;
+ else if (ret == 1) {
+ do_request(d[index].buf, d[index].len, 1,
+ d[index].s, sa, from_len);
+ clear_descr(d + index);
+ }
+}
+
+void
+loop(void)
+{
+ struct descr *d;
+ int ndescr;
+
+ ndescr = init_sockets(&d);
+ if(ndescr <= 0)
+ krb5_errx(context, 1, "No sockets!");
+ while(exit_flag == 0){
+ struct timeval tmout;
+ fd_set fds;
+ int min_free = -1;
+ int max_fd = 0;
+ int i;
+ FD_ZERO(&fds);
+ for(i = 0; i < ndescr; i++){
+ if(d[i].s >= 0){
+ if(d[i].type == SOCK_STREAM &&
+ d[i].timeout && d[i].timeout < time(NULL)){
+ struct sockaddr sa;
+ int salen = sizeof(sa);
+ char addr[32];
+
+ getpeername(d[i].s, &sa, &salen);
+ addr_to_string(&sa, salen, addr, sizeof(addr));
+ kdc_log(1, "TCP-connection from %s expired after %u bytes",
+ addr, d[i].len);
+ clear_descr(&d[i]);
+ continue;
+ }
+ if(max_fd < d[i].s)
+ max_fd = d[i].s;
+ FD_SET(d[i].s, &fds);
+ }else if(min_free < 0 || i < min_free)
+ min_free = i;
+ }
+ if(min_free == -1){
+ struct descr *tmp;
+ tmp = realloc(d, (ndescr + 4) * sizeof(*d));
+ if(tmp == NULL)
+ krb5_warnx(context, "No memory");
+ else{
+ d = tmp;
+ memset(d + ndescr, 0, 4 * sizeof(*d));
+ for(i = ndescr; i < ndescr + 4; i++)
+ d[i].s = -1;
+ min_free = ndescr;
+ ndescr += 4;
+ }
+ }
+
+ tmout.tv_sec = TCP_TIMEOUT;
+ tmout.tv_usec = 0;
+ switch(select(max_fd + 1, &fds, 0, 0, &tmout)){
+ case 0:
+ break;
+ case -1:
+ krb5_warn(context, errno, "select");
+ break;
+ default:
+ for(i = 0; i < ndescr; i++)
+ if(d[i].s >= 0 && FD_ISSET(d[i].s, &fds)) {
+ if(d[i].type == SOCK_DGRAM)
+ handle_udp(&d[i]);
+ else if(d[i].type == SOCK_STREAM)
+ handle_tcp(d, i, min_free);
+ }
+ }
+ }
+ free (d);
+}
diff --git a/crypto/heimdal/kdc/headers.h b/crypto/heimdal/kdc/headers.h
new file mode 100644
index 000000000000..f9c3eb806283
--- /dev/null
+++ b/crypto/heimdal/kdc/headers.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*
+ * $Id: headers.h,v 1.5 1999/12/02 17:04:59 joda Exp $
+ */
+
+#ifndef __HEADERS_H__
+#define __HEADERS_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#include <err.h>
+#include <roken.h>
+#include <getarg.h>
+#include <base64.h>
+#include <parse_units.h>
+#include <krb5.h>
+#include <hdb.h>
+#include <hdb_err.h>
+#include <der.h> /* copy_octet_string */
+
+#ifdef KRB4
+#include <krb.h>
+#include <prot.h>
+#define Principal Principal4
+#include <krb_db.h>
+#endif
+
+#define ALLOC(X) ((X) = malloc(sizeof(*(X))))
+
+#endif /* __HEADERS_H__ */
diff --git a/crypto/heimdal/kdc/hprop-common.c b/crypto/heimdal/kdc/hprop-common.c
new file mode 100644
index 000000000000..660725f68883
--- /dev/null
+++ b/crypto/heimdal/kdc/hprop-common.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "hprop.h"
+
+RCSID("$Id: hprop-common.c,v 1.7 1999/12/02 17:04:59 joda Exp $");
+
+krb5_error_code
+send_priv(krb5_context context, krb5_auth_context ac,
+ krb5_data *data, int fd)
+{
+ krb5_data packet;
+ krb5_error_code ret;
+
+ ret = krb5_mk_priv (context,
+ ac,
+ data,
+ &packet,
+ NULL);
+ if (ret)
+ return ret;
+
+ ret = krb5_write_message (context, &fd, &packet);
+ krb5_data_free(&packet);
+ return ret;
+}
+
+krb5_error_code
+recv_priv(krb5_context context, krb5_auth_context ac, int fd, krb5_data *out)
+{
+ krb5_error_code ret;
+ krb5_data data;
+
+ ret = krb5_read_message (context, &fd, &data);
+ if (ret)
+ return ret;
+
+ ret = krb5_rd_priv(context, ac, &data, out, NULL);
+ krb5_data_free (&data);
+ return ret;
+}
+
+krb5_error_code
+send_clear(krb5_context context, int fd, krb5_data data)
+{
+ return krb5_write_message (context, &fd, &data);
+}
+
+krb5_error_code
+recv_clear(krb5_context context, int fd, krb5_data *out)
+{
+ return krb5_read_message (context, &fd, out);
+}
diff --git a/crypto/heimdal/kdc/hprop.8 b/crypto/heimdal/kdc/hprop.8
new file mode 100644
index 000000000000..d7005777fa72
--- /dev/null
+++ b/crypto/heimdal/kdc/hprop.8
@@ -0,0 +1,66 @@
+.\" $Id: hprop.8,v 1.3 1997/09/03 20:33:04 joda Exp $
+.\"
+.Dd September 3, 1997
+.Dt HPROP 8
+.Os HEIMDAL
+.Sh NAME
+.Nm hprop
+.Nd
+propagate the KDC database
+.Sh SYNOPSIS
+.Nm
+.Op Fl 4DEhnv
+.Op Fl d Ar file
+.Op Fl -database= Ns Ar file
+.Op Fl -decrypt
+.Op Fl -encrypt
+.Op Fl -help
+.Op Fl k
+.Op Fl -keytab= Ns Ar file
+.Op Fl m Ar file
+.Op Fl -master-key= Ns Ar file
+.Op Fl -stdout
+.Op Fl -v4-db
+.Op Fl -verbose
+.Op Fl -version
+.Ar host ...
+.Sh DESCRIPTION
+.Nm
+propagates the database from a master KDC to a slave. It connects to
+all
+.Ar hosts
+specified on the command by opening a TCP connection to port 754
+(service hprop) and sends the database in encrypted form.
+.Pp
+Options supported:
+.Bl -tag -width Ds
+.It Fl d Ar file
+.It Fl -database= Ns Ar file
+The database to be propagated.
+.It Fl D
+.It Fl -decrypt
+The encryption keys in the database can either be in clear, or
+encrypted with a master key. This option thansmits the database with
+unencrypted keys.
+.It Fl E
+.It Fl -encrypt
+This option thansmits the database with encrypted keys.
+.It Fl k
+.It Fl -keytab= Ns Ar file
+The keytab to use for fetching the key to be used for authenticating
+to the propagation daemon(s). The key
+.Pa kadmin/hprop
+is used from this keytab.
+.It Fl m Ar file
+.It Fl -master-key= Ns Ar file
+Where to find the master key to encrypt or decrypt keys with.
+.It Fl n
+.It Fl -stdout
+Dump the database on stdout, in a format that can be fed to hpropd.
+.It Fl 4
+.It Fl -v4-db
+Use a version 4 database. This option is only available if the code is
+compiled with Kerberos 4 support.
+.El
+.Sh SEE ALSO
+.Xr hpropd 8
diff --git a/crypto/heimdal/kdc/hprop.c b/crypto/heimdal/kdc/hprop.c
new file mode 100644
index 000000000000..3be6a6f58974
--- /dev/null
+++ b/crypto/heimdal/kdc/hprop.c
@@ -0,0 +1,676 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "hprop.h"
+
+RCSID("$Id: hprop.c,v 1.40 1999/12/04 18:02:18 assar Exp $");
+
+static int version_flag;
+static int help_flag;
+static char *ktname = HPROP_KEYTAB;
+static char *database;
+static char *mkeyfile;
+static int to_stdout;
+static int verbose_flag;
+static int encrypt_flag;
+static int decrypt_flag;
+static EncryptionKey mkey5;
+static krb5_data msched5;
+
+static int v4_db;
+static int ka_db;
+static char *afs_cell;
+
+#ifdef KRB4
+static char *realm;
+
+#ifdef KASERVER_DB
+static int kaspecials_flag;
+#endif
+#endif
+
+static int
+open_socket(krb5_context context, const char *hostname)
+{
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char portstr[NI_MAXSERV];
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ snprintf (portstr, sizeof(portstr),
+ "%u",
+ ntohs(krb5_getportbyname (context, "hprop", "tcp", HPROP_PORT)));
+
+ error = getaddrinfo (hostname, portstr, &hints, &ai);
+ if (error) {
+ warnx ("%s: %s", hostname, gai_strerror(error));
+ return -1;
+ }
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ int s;
+
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0)
+ continue;
+ if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
+ warn ("connect(%s)", hostname);
+ close (s);
+ continue;
+ }
+ freeaddrinfo (ai);
+ return s;
+ }
+ warnx ("failed to contact %s", hostname);
+ freeaddrinfo (ai);
+ return -1;
+}
+
+struct prop_data{
+ krb5_context context;
+ krb5_auth_context auth_context;
+ int sock;
+};
+
+int hdb_entry2value(krb5_context, hdb_entry*, krb5_data*);
+
+static krb5_error_code
+v5_prop(krb5_context context, HDB *db, hdb_entry *entry, void *appdata)
+{
+ krb5_error_code ret;
+ struct prop_data *pd = appdata;
+ krb5_data data;
+
+ if(encrypt_flag)
+ _hdb_seal_keys_int(entry, 0, msched5);
+ if(decrypt_flag)
+ _hdb_unseal_keys_int(entry, 0, msched5);
+
+ ret = hdb_entry2value(context, entry, &data);
+ if(ret) return ret;
+
+ if(to_stdout)
+ ret = send_clear(context, STDOUT_FILENO, data);
+ else
+ ret = send_priv(context, pd->auth_context, &data, pd->sock);
+ krb5_data_free(&data);
+ return ret;
+}
+
+#ifdef KRB4
+static des_cblock mkey4;
+static des_key_schedule msched4;
+static char realm_buf[REALM_SZ];
+
+static int
+v4_prop(void *arg, Principal *p)
+{
+ struct prop_data *pd = arg;
+ hdb_entry ent;
+ krb5_error_code ret;
+
+ memset(&ent, 0, sizeof(ent));
+
+ ret = krb5_425_conv_principal(pd->context, p->name, p->instance, realm,
+ &ent.principal);
+ if(ret){
+ krb5_warn(pd->context, ret,
+ "krb5_425_conv_principal %s.%s@%s",
+ p->name, p->instance, realm);
+ return 0;
+ }
+
+ if(verbose_flag) {
+ char *s;
+ krb5_unparse_name_short(pd->context, ent.principal, &s);
+ krb5_warnx(pd->context, "%s.%s -> %s", p->name, p->instance, s);
+ free(s);
+ }
+
+ ent.kvno = p->key_version;
+ ent.keys.len = 3;
+ ent.keys.val = malloc(ent.keys.len * sizeof(*ent.keys.val));
+ ent.keys.val[0].mkvno = NULL;
+#if 0
+ ent.keys.val[0].mkvno = malloc (sizeof(*ent.keys.val[0].mkvno));
+ *(ent.keys.val[0].mkvno) = p->kdc_key_ver; /* XXX */
+#endif
+ ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt));
+ ent.keys.val[0].salt->type = pa_pw_salt;
+ ent.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5;
+ krb5_data_alloc(&ent.keys.val[0].key.keyvalue, sizeof(des_cblock));
+
+ {
+ unsigned char *key = ent.keys.val[0].key.keyvalue.data;
+ unsigned char null_key[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ memcpy(key, &p->key_low, 4);
+ memcpy(key + 4, &p->key_high, 4);
+ kdb_encrypt_key((des_cblock*)key, (des_cblock*)key,
+ &mkey4, msched4, DES_DECRYPT);
+ if(memcmp(key, null_key, sizeof(null_key)) == 0) {
+ free_Key(&ent.keys.val[0]);
+ ent.keys.val = 0;
+ ent.flags.invalid = 1;
+ }
+ }
+ copy_Key(&ent.keys.val[0], &ent.keys.val[1]);
+ ent.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
+ copy_Key(&ent.keys.val[0], &ent.keys.val[2]);
+ ent.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC;
+
+ ALLOC(ent.max_life);
+ *ent.max_life = krb_life_to_time(0, p->max_life);
+ if(*ent.max_life == NEVERDATE){
+ free(ent.max_life);
+ ent.max_life = NULL;
+ }
+
+ ALLOC(ent.pw_end);
+ *ent.pw_end = p->exp_date;
+ ret = krb5_make_principal(pd->context, &ent.created_by.principal,
+ realm,
+ "kadmin",
+ "hprop",
+ NULL);
+ if(ret){
+ krb5_warn(pd->context, ret, "krb5_make_principal");
+ ret = 0;
+ goto out;
+ }
+ ent.created_by.time = time(NULL);
+ ALLOC(ent.modified_by);
+ ret = krb5_425_conv_principal(pd->context, p->mod_name, p->mod_instance,
+ realm, &ent.modified_by->principal);
+ if(ret){
+ krb5_warn(pd->context, ret, "%s.%s@%s", p->name, p->instance, realm);
+ ent.modified_by->principal = NULL;
+ ret = 0;
+ goto out;
+ }
+ ent.modified_by->time = p->mod_date;
+
+ ent.flags.forwardable = 1;
+ ent.flags.renewable = 1;
+ ent.flags.proxiable = 1;
+ ent.flags.postdate = 1;
+ ent.flags.client = 1;
+ ent.flags.server = 1;
+
+ /* special case password changing service */
+ if(strcmp(p->name, "changepw") == 0 &&
+ strcmp(p->instance, "kerberos") == 0) {
+ ent.flags.forwardable = 0;
+ ent.flags.renewable = 0;
+ ent.flags.proxiable = 0;
+ ent.flags.postdate = 0;
+ ent.flags.initial = 1;
+ ent.flags.change_pw = 1;
+ }
+
+ ret = v5_prop(pd->context, NULL, &ent, pd);
+
+ if (strcmp (p->name, "krbtgt") == 0
+ && strcmp (realm, p->instance) != 0) {
+ krb5_free_principal (pd->context, ent.principal);
+ ret = krb5_425_conv_principal (pd->context, p->name,
+ realm, p->instance,
+ &ent.principal);
+ if (ret == 0)
+ ret = v5_prop (pd->context, NULL, &ent, pd);
+ }
+
+out:
+ hdb_free_entry(pd->context, &ent);
+ return ret;
+}
+
+#ifdef KASERVER_DB
+
+#include "kadb.h"
+
+/* read a `ka_entry' from `fd' at offset `pos' */
+static void
+read_block(krb5_context context, int fd, int32_t pos, void *buf, size_t len)
+{
+ krb5_error_code ret;
+ if(lseek(fd, 64 + pos, SEEK_SET) == (off_t)-1)
+ krb5_err(context, 1, errno, "lseek(%u)", 64 + pos);
+ ret = read(fd, buf, len);
+ if(ret < 0)
+ krb5_err(context, 1, errno, "read(%u)", len);
+ if(ret != len)
+ krb5_errx(context, 1, "read(%u) = %u", len, ret);
+}
+
+static int
+ka_convert(struct prop_data *pd, int fd, struct ka_entry *ent,
+ const char *cell)
+{
+ int32_t flags = ntohl(ent->flags);
+ krb5_error_code ret;
+ hdb_entry hdb;
+
+ if(!kaspecials_flag
+ && (flags & KAFNORMAL) == 0) /* remove special entries */
+ return 0;
+ memset(&hdb, 0, sizeof(hdb));
+ ret = krb5_425_conv_principal(pd->context, ent->name, ent->instance, realm,
+ &hdb.principal);
+ if(ret) {
+ krb5_warn(pd->context, ret,
+ "krb5_425_conv_principal (%s.%s@%s)",
+ ent->name, ent->instance, realm);
+ return 0;
+ }
+ hdb.kvno = ntohl(ent->kvno);
+ hdb.keys.len = 3;
+ hdb.keys.val = malloc(hdb.keys.len * sizeof(*hdb.keys.val));
+ hdb.keys.val[0].mkvno = NULL;
+ hdb.keys.val[0].salt = calloc(1, sizeof(*hdb.keys.val[0].salt));
+ hdb.keys.val[0].salt->type = hdb_afs3_salt;
+ hdb.keys.val[0].salt->salt.data = strdup(cell);
+ hdb.keys.val[0].salt->salt.length = strlen(cell);
+
+ hdb.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5;
+ krb5_data_copy(&hdb.keys.val[0].key.keyvalue, ent->key, sizeof(ent->key));
+ copy_Key(&hdb.keys.val[0], &hdb.keys.val[1]);
+ hdb.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
+ copy_Key(&hdb.keys.val[0], &hdb.keys.val[2]);
+ hdb.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC;
+
+ ALLOC(hdb.max_life);
+ *hdb.max_life = ntohl(ent->max_life);
+
+ if(ntohl(ent->pw_end) != NEVERDATE && ntohl(ent->pw_end) != -1){
+ ALLOC(hdb.pw_end);
+ *hdb.pw_end = ntohl(ent->pw_end);
+ }
+
+ ret = krb5_make_principal(pd->context, &hdb.created_by.principal,
+ realm,
+ "kadmin",
+ "hprop",
+ NULL);
+ hdb.created_by.time = time(NULL);
+
+ if(ent->mod_ptr){
+ struct ka_entry mod;
+ ALLOC(hdb.modified_by);
+ read_block(pd->context, fd, ntohl(ent->mod_ptr), &mod, sizeof(mod));
+
+ krb5_425_conv_principal(pd->context, mod.name, mod.instance, realm,
+ &hdb.modified_by->principal);
+ hdb.modified_by->time = ntohl(ent->mod_time);
+ memset(&mod, 0, sizeof(mod));
+ }
+
+ hdb.flags.forwardable = 1;
+ hdb.flags.renewable = 1;
+ hdb.flags.proxiable = 1;
+ hdb.flags.postdate = 1;
+ /* XXX - AFS 3.4a creates krbtgt.REALMOFCELL as NOTGS+NOSEAL */
+ if (strcmp(ent->name, "krbtgt") == 0 &&
+ (flags & (KAFNOTGS|KAFNOSEAL)) == (KAFNOTGS|KAFNOSEAL))
+ flags &= ~(KAFNOTGS|KAFNOSEAL);
+
+ hdb.flags.client = (flags & KAFNOTGS) == 0;
+ hdb.flags.server = (flags & KAFNOSEAL) == 0;
+
+ ret = v5_prop(pd->context, NULL, &hdb, pd);
+ hdb_free_entry(pd->context, &hdb);
+ return ret;
+}
+
+static int
+ka_dump(struct prop_data *pd, const char *file, const char *cell)
+{
+ struct ka_header header;
+ int i;
+ int fd = open(file, O_RDONLY);
+
+ if(fd < 0)
+ krb5_err(pd->context, 1, errno, "open(%s)", file);
+ read_block(pd->context, fd, 0, &header, sizeof(header));
+ if(header.version1 != header.version2)
+ krb5_errx(pd->context, 1, "Version mismatch in header: %d/%d",
+ ntohl(header.version1), ntohl(header.version2));
+ if(ntohl(header.version1) != 5)
+ krb5_errx(pd->context, 1, "Unknown database version %d (expected 5)",
+ ntohl(header.version1));
+ for(i = 0; i < ntohl(header.hashsize); i++){
+ int32_t pos = ntohl(header.hash[i]);
+ while(pos){
+ struct ka_entry ent;
+ read_block(pd->context, fd, pos, &ent, sizeof(ent));
+ ka_convert(pd, fd, &ent, cell);
+ pos = ntohl(ent.next);
+ }
+ }
+ return 0;
+}
+
+#endif /* KASERVER_DB */
+
+#endif /* KRB4 */
+
+
+struct getargs args[] = {
+ { "master-key", 'm', arg_string, &mkeyfile, "v5 master key file", "file" },
+#ifdef KRB4
+#endif
+ { "database", 'd', arg_string, &database, "database", "file" },
+#ifdef KRB4
+ { "v4-db", '4', arg_flag, &v4_db, "use version 4 database" },
+ { "v4-realm", 'r', arg_string, &realm, "v4 realm to use" },
+#endif
+#ifdef KASERVER_DB
+ { "ka-db", 'K', arg_flag, &ka_db, "use kaserver database" },
+ { "cell", 'c', arg_string, &afs_cell, "name of AFS cell" },
+ { "kaspecials", 'S', arg_flag, &kaspecials_flag, "dump KASPECIAL keys"},
+#endif
+ { "keytab", 'k', arg_string, &ktname, "keytab to use for authentication", "keytab" },
+ { "decrypt", 'D', arg_flag, &decrypt_flag, "decrypt keys" },
+ { "encrypt", 'E', arg_flag, &encrypt_flag, "encrypt keys" },
+ { "stdout", 'n', arg_flag, &to_stdout, "dump to stdout" },
+ { "verbose", 'v', arg_flag, &verbose_flag },
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 'h', arg_flag, &help_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int ret)
+{
+ arg_printusage (args, num_args, NULL, "host ...");
+ exit (ret);
+}
+
+static void
+get_creds(krb5_context context, krb5_ccache *cache)
+{
+ krb5_keytab keytab;
+ krb5_principal client;
+ krb5_error_code ret;
+ krb5_get_init_creds_opt init_opts;
+ krb5_preauthtype preauth = KRB5_PADATA_ENC_TIMESTAMP;
+ krb5_creds creds;
+
+ ret = krb5_kt_resolve(context, ktname, &keytab);
+ if(ret) krb5_err(context, 1, ret, "krb5_kt_resolve");
+
+ ret = krb5_make_principal(context, &client, NULL,
+ "kadmin", HPROP_NAME, NULL);
+ if(ret) krb5_err(context, 1, ret, "krb5_make_principal");
+
+ krb5_get_init_creds_opt_init(&init_opts);
+ krb5_get_init_creds_opt_set_preauth_list(&init_opts, &preauth, 1);
+
+ ret = krb5_get_init_creds_keytab(context, &creds, client, keytab, 0, NULL, &init_opts);
+ if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");
+
+ ret = krb5_kt_close(context, keytab);
+ if(ret) krb5_err(context, 1, ret, "krb5_kt_close");
+
+ ret = krb5_cc_gen_new(context, &krb5_mcc_ops, cache);
+ if(ret) krb5_err(context, 1, ret, "krb5_cc_gen_new");
+
+ ret = krb5_cc_initialize(context, *cache, client);
+ if(ret) krb5_err(context, 1, ret, "krb5_cc_initialize");
+
+ ret = krb5_cc_store_cred(context, *cache, &creds);
+ if(ret) krb5_err(context, 1, ret, "krb5_cc_store_cred");
+}
+
+static void
+iterate (krb5_context context,
+ const char *database,
+ const char *afs_cell,
+ HDB *db,
+ int v4_db, int ka_db,
+ struct prop_data *pd)
+{
+#ifdef KRB4
+ if(v4_db) {
+ int e = kerb_db_iterate ((k_iter_proc_t)v4_prop, pd);
+ if(e)
+ krb5_errx(context, 1, "kerb_db_iterate: %s",
+ krb_get_err_text(e));
+#ifdef KASERVER_DB
+ } else if(ka_db) {
+ int e = ka_dump(pd, database, afs_cell);
+ if(e)
+ krb5_errx(context, 1, "ka_dump: %s", krb_get_err_text(e));
+#endif
+ } else
+#endif
+ {
+ krb5_error_code ret = hdb_foreach(context, db, HDB_F_DECRYPT,
+ v5_prop, pd);
+ if(ret)
+ krb5_err(context, 1, ret, "hdb_foreach");
+ }
+}
+
+static int
+dump_database (krb5_context context, int v4_db, int ka_db,
+ const char *database, const char *afs_cell,
+ HDB *db)
+{
+ struct prop_data pd;
+
+ pd.context = context;
+ pd.auth_context = NULL;
+ pd.sock = STDOUT_FILENO;
+
+ iterate (context, database, afs_cell, db, v4_db, ka_db, &pd);
+ return 0;
+}
+
+static int
+propagate_database (krb5_context context, int v4_db, int ka_db,
+ const char *database, const char *afs_cell,
+ HDB *db, krb5_ccache ccache,
+ int optind, int argc, char **argv)
+{
+ krb5_principal server;
+ krb5_error_code ret;
+ int i;
+
+ for(i = optind; i < argc; i++){
+ krb5_auth_context auth_context;
+ int fd;
+ struct prop_data pd;
+ krb5_data data;
+
+ fd = open_socket(context, argv[i]);
+ if(fd < 0) {
+ krb5_warn (context, errno, "connect %s", argv[i]);
+ continue;
+ }
+
+ ret = krb5_sname_to_principal(context, argv[i],
+ HPROP_NAME, KRB5_NT_SRV_HST, &server);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_sname_to_principal(%s)", argv[i]);
+ close(fd);
+ continue;
+ }
+
+ auth_context = NULL;
+ ret = krb5_sendauth(context,
+ &auth_context,
+ &fd,
+ HPROP_VERSION,
+ NULL,
+ server,
+ AP_OPTS_MUTUAL_REQUIRED,
+ NULL, /* in_data */
+ NULL, /* in_creds */
+ ccache,
+ NULL,
+ NULL,
+ NULL);
+
+ if(ret) {
+ krb5_warn(context, ret, "krb5_sendauth");
+ close(fd);
+ continue;
+ }
+
+ pd.context = context;
+ pd.auth_context = auth_context;
+ pd.sock = fd;
+
+ iterate (context, database, afs_cell, db,
+ v4_db, ka_db, &pd);
+
+ data.data = NULL;
+ data.length = 0;
+ ret = send_priv(context, auth_context, &data, fd);
+ if(ret)
+ krb5_warn(context, ret, "send_priv");
+
+ ret = recv_priv(context, auth_context, fd, &data);
+ if(ret)
+ krb5_warn(context, ret, "recv_priv");
+ else
+ krb5_data_free (&data);
+
+ krb5_auth_con_free(context, auth_context);
+ close(fd);
+ }
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache ccache;
+ HDB *db;
+ int optind = 0;
+
+ set_progname(argv[0]);
+
+ if(getarg(args, num_args, argc, argv, &optind))
+ usage(1);
+
+ if(help_flag)
+ usage(0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ ret = krb5_init_context(&context);
+ if(ret)
+ exit(1);
+
+ if(encrypt_flag && decrypt_flag)
+ krb5_errx(context, 1,
+ "Only one of `--encrypt' and `--decrypt' is meaningful");
+
+ if(!to_stdout)
+ get_creds(context, &ccache);
+
+ ret = hdb_read_master_key(context, mkeyfile, &mkey5);
+ if(ret && ret != ENOENT)
+ krb5_err(context, 1, ret, "hdb_read_master_key");
+ if(ret) {
+ if(encrypt_flag || decrypt_flag)
+ krb5_errx(context, 1, "No master key file found");
+ } else {
+ ret = hdb_process_master_key(context, mkey5, &msched5);
+ if(ret)
+ krb5_err(context, 1, ret, "hdb_process_master_key");
+ }
+
+#ifdef KRB4
+ if (v4_db
+#ifdef KASERVER_DB
+ || ka_db
+#endif
+) {
+ int e;
+
+ if (realm == NULL) {
+ e = krb_get_lrealm(realm_buf, 1);
+ if(e)
+ krb5_errx(context, 1, "krb_get_lrealm: %s",
+ krb_get_err_text(e));
+ realm = realm_buf;
+ }
+ }
+
+ if(v4_db) {
+ int e = kerb_db_set_name (database);
+ if(e)
+ krb5_errx(context, 1, "kerb_db_set_name: %s",
+ krb_get_err_text(e));
+ e = kdb_get_master_key(0, &mkey4, msched4);
+ if(e)
+ krb5_errx(context, 1, "kdb_get_master_key: %s",
+ krb_get_err_text(e));
+ } else
+#ifdef KASERVER_DB
+ if (ka_db) {
+ /* no preparation required */
+ } else
+#endif
+#endif /* KRB4 */
+ {
+ ret = hdb_create (context, &db, database);
+ if(ret)
+ krb5_err(context, 1, ret, "hdb_create: %s", database);
+ ret = db->open(context, db, O_RDONLY, 0);
+ if(ret)
+ krb5_err(context, 1, ret, "db->open");
+ }
+
+ if (to_stdout)
+ dump_database (context, v4_db, ka_db,
+ database, afs_cell, db);
+ else
+ propagate_database (context, v4_db, ka_db,
+ database, afs_cell,
+ db, ccache,
+ optind, argc, argv);
+ return 0;
+}
diff --git a/crypto/heimdal/kdc/hprop.h b/crypto/heimdal/kdc/hprop.h
new file mode 100644
index 000000000000..3802c5dc84f6
--- /dev/null
+++ b/crypto/heimdal/kdc/hprop.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: hprop.h,v 1.7 1999/12/02 17:04:59 joda Exp $ */
+
+#ifndef __HPROP_H__
+#define __HPROP_H__
+
+#include "headers.h"
+
+#define HPROP_VERSION "hprop-0.0"
+#define HPROP_NAME "hprop"
+#define HPROP_KEYTAB "FILE:/etc/hprop.keytab"
+#define HPROP_PORT 754
+
+#ifndef NEVERDATE
+#define NEVERDATE ((1U << 31) - 1)
+#endif
+
+krb5_error_code send_priv(krb5_context, krb5_auth_context, krb5_data*, int);
+krb5_error_code recv_priv(krb5_context, krb5_auth_context, int, krb5_data*);
+krb5_error_code send_clear(krb5_context context, int fd, krb5_data data);
+krb5_error_code recv_clear(krb5_context context, int fd, krb5_data *out);
+
+#endif /* __HPROP_H__ */
diff --git a/crypto/heimdal/kdc/hpropd.8 b/crypto/heimdal/kdc/hpropd.8
new file mode 100644
index 000000000000..de4249a37ecf
--- /dev/null
+++ b/crypto/heimdal/kdc/hpropd.8
@@ -0,0 +1,27 @@
+.\" $Id: hpropd.8,v 1.1 1997/08/27 23:42:34 assar Exp $
+.\"
+.Dd Aug 27, 1997
+.Dt HPROPD 8
+.Os HEIMDAL
+.Sh NAME
+.Nm hpropd
+.Nd
+receive a propagated database
+.Sh SYNOPSIS
+.Nm
+.Op Fl d Ar database
+.Op Fl -database= Ns Ar database
+.Sh DESCRIPTION
+.Nm
+receives databases sent by
+.Nm hprop .
+and writes it as a local database.
+.Pp
+Options supported:
+.Bl -tag -width Ds
+.It Fl d Ar database
+.It Fl -database= Ns Ar database
+the database to create.
+.El
+.Sh SEE ALSO
+.Xr hprop 8
diff --git a/crypto/heimdal/kdc/hpropd.c b/crypto/heimdal/kdc/hpropd.c
new file mode 100644
index 000000000000..df29240ab2d3
--- /dev/null
+++ b/crypto/heimdal/kdc/hpropd.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 1997-2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "hprop.h"
+
+RCSID("$Id: hpropd.c,v 1.22 2000/01/06 21:39:24 assar Exp $");
+
+#ifdef KRB4
+static des_cblock mkey4;
+static des_key_schedule msched4;
+
+static char *
+time2str(time_t t)
+{
+ static char buf[128];
+ strftime(buf, sizeof(buf), "%Y%m%d%H%M", gmtime(&t));
+ return buf;
+}
+
+static int
+dump_krb4(krb5_context context, hdb_entry *ent, int fd)
+{
+ char name[ANAME_SZ];
+ char instance[INST_SZ];
+ char realm[REALM_SZ];
+ char buf[1024];
+ char *p;
+ int i;
+ int ret;
+ char *princ_name;
+ Event *modifier;
+ krb5_realm *realms;
+ int cmp;
+
+ ret = krb5_524_conv_principal(context, ent->principal,
+ name, instance, realm);
+ if (ret) {
+ krb5_unparse_name(context, ent->principal, &princ_name);
+ krb5_warn(context, ret, "%s", princ_name);
+ free(princ_name);
+ return -1;
+ }
+
+ ret = krb5_get_default_realms (context, &realms);
+ if (ret) {
+ krb5_warn(context, ret, "krb5_get_default_realms");
+ return -1;
+ }
+
+ cmp = strcmp (realms[0], ent->principal->realm);
+ krb5_free_host_realm (context, realms);
+ if (cmp != 0)
+ return -1;
+
+ snprintf (buf, sizeof(buf), "%s %s ", name,
+ (strlen(instance) != 0) ? instance : "*");
+
+ if (ent->max_life) {
+ asprintf(&p, "%d", krb_time_to_life(0, *ent->max_life));
+ strcat(buf, p);
+ free(p);
+ } else
+ strcat(buf, "255");
+ strcat(buf, " ");
+
+ i = 0;
+ while (i < ent->keys.len &&
+ ent->keys.val[i].key.keytype != KEYTYPE_DES)
+ ++i;
+
+ if (i == ent->keys.len) {
+ krb5_warnx(context, "No DES key for %s.%s", name, instance);
+ return -1;
+ }
+
+ if (ent->keys.val[i].mkvno)
+ asprintf(&p, "%d ", *ent->keys.val[i].mkvno);
+ else
+ asprintf(&p, "%d ", 1);
+ strcat(buf, p);
+ free(p);
+
+ asprintf(&p, "%d ", ent->kvno);
+ strcat(buf, p);
+ free(p);
+
+ asprintf(&p, "%d ", 0); /* Attributes are always 0*/
+ strcat(buf, p);
+ free(p);
+
+ {
+ u_int32_t *key = ent->keys.val[i].key.keyvalue.data;
+ kdb_encrypt_key((des_cblock*)key, (des_cblock*)key,
+ &mkey4, msched4, DES_ENCRYPT);
+ asprintf(&p, "%x %x ", (int)htonl(*key), (int)htonl(*(key+1)));
+ strcat(buf, p);
+ free(p);
+ }
+
+ if (ent->pw_end == NULL)
+ strcat(buf, time2str(60*60*24*365*50)); /* passwd will never expire */
+ else
+ strcat(buf, time2str(*ent->pw_end));
+ strcat(buf, " ");
+
+ if (ent->modified_by == NULL)
+ modifier = &ent->created_by;
+ else
+ modifier = ent->modified_by;
+
+ ret = krb5_524_conv_principal(context, modifier->principal,
+ name, instance, realm);
+ if (ret) {
+ krb5_unparse_name(context, modifier->principal, &princ_name);
+ krb5_warn(context, ret, "%s", princ_name);
+ free(princ_name);
+ return -1;
+ }
+ asprintf(&p, "%s %s %s\n", time2str(modifier->time),
+ (strlen(name) != 0) ? name : "*",
+ (strlen(instance) != 0) ? instance : "*");
+ strcat(buf, p);
+ free(p);
+
+ ret = write(fd, buf, strlen(buf));
+ if (ret == -1)
+ krb5_warnx(context, "write");
+ return 0;
+}
+#endif /* KRB4 */
+
+static int inetd_flag = -1;
+static int help_flag;
+static int version_flag;
+static int print_dump;
+static char *database = HDB_DEFAULT_DB;
+static int from_stdin;
+#ifdef KRB4
+static int v4dump;
+#endif
+
+struct getargs args[] = {
+ { "database", 'd', arg_string, &database, "database", "file" },
+ { "stdin", 'n', arg_flag, &from_stdin, "read from stdin" },
+ { "print", 0, arg_flag, &print_dump, "print dump to stdout" },
+ { "inetd", 'i', arg_negative_flag, &inetd_flag,
+ "Not started from inetd" },
+#ifdef KRB4
+ { "v4dump", '4', arg_flag, &v4dump, "create v4 type DB" },
+#endif
+ { "version", 0, arg_flag, &version_flag, NULL, NULL },
+ { "help", 'h', arg_flag, &help_flag, NULL, NULL}
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int ret)
+{
+ arg_printusage (args, num_args, NULL, "");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_auth_context ac = NULL;
+ krb5_principal server;
+ krb5_principal c1, c2;
+ krb5_authenticator authent;
+ krb5_keytab keytab;
+ int fd;
+ HDB *db;
+ char hostname[128];
+ int optind = 0;
+ char *tmp_db;
+ krb5_log_facility *fac;
+ int nprincs;
+#ifdef KRB4
+ int e;
+ int fd_out;
+#endif
+
+ set_progname(argv[0]);
+
+ ret = krb5_init_context(&context);
+ if(ret)
+ exit(1);
+
+ ret = krb5_openlog(context, "hpropd", &fac);
+ if(ret)
+ ;
+ krb5_set_warn_dest(context, fac);
+
+ if(getarg(args, num_args, argc, argv, &optind))
+ usage(1);
+
+#ifdef KRB4
+ if (v4dump && database == HDB_DEFAULT_DB)
+ database = "/var/kerberos/524_dump";
+#endif /* KRB4 */
+
+ if(help_flag)
+ usage(0);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage(1);
+
+ if(from_stdin)
+ fd = STDIN_FILENO;
+ else {
+ struct sockaddr_storage ss;
+ struct sockaddr *sa = (struct sockaddr *)&ss;
+ int sin_len = sizeof(ss);
+ char addr_name[256];
+
+ fd = STDIN_FILENO;
+ if (inetd_flag == -1) {
+ if (getpeername (fd, sa, &sin_len) < 0)
+ inetd_flag = 0;
+ else
+ inetd_flag = 1;
+ }
+ if (!inetd_flag) {
+ mini_inetd (krb5_getportbyname (context, "hprop", "tcp",
+ HPROP_PORT));
+ }
+ sin_len = sizeof(ss);
+ if(getpeername(fd, sa, &sin_len) < 0)
+ krb5_err(context, 1, errno, "getpeername");
+
+ if (inet_ntop(sa->sa_family,
+ socket_get_address (sa),
+ addr_name,
+ sizeof(addr_name)) == NULL)
+ strlcpy (addr_name, "unknown address",
+ sizeof(addr_name));
+
+ krb5_log(context, fac, 0, "Connection from %s", addr_name);
+
+ gethostname(hostname, sizeof(hostname));
+ ret = krb5_sname_to_principal(context, hostname, HPROP_NAME,
+ KRB5_NT_SRV_HST, &server);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_sname_to_principal");
+
+ ret = krb5_kt_default(context, &keytab);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_kt_default");
+
+ ret = krb5_recvauth(context, &ac, &fd, HPROP_VERSION,
+ server, 0, keytab, NULL);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_recvauth");
+
+ ret = krb5_auth_getauthenticator(context, ac, &authent);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_auth_getauthenticator");
+
+ ret = krb5_make_principal(context, &c1, NULL, "kadmin", "hprop", NULL);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_make_principal");
+ principalname2krb5_principal(&c2, authent->cname, authent->crealm);
+ if(!krb5_principal_compare(context, c1, c2)) {
+ char *s;
+ krb5_unparse_name(context, c2, &s);
+ krb5_errx(context, 1, "Unauthorized connection from %s", s);
+ }
+ krb5_free_principal(context, c1);
+ krb5_free_principal(context, c2);
+
+ ret = krb5_kt_close(context, keytab);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_kt_close");
+ }
+
+ if(!print_dump) {
+ asprintf(&tmp_db, "%s~", database);
+#ifdef KRB4
+ if (v4dump) {
+ fd_out = open(tmp_db, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ if (fd_out == -1)
+ krb5_errx(context, 1, "%s", strerror(errno));
+ }
+ else
+#endif /* KRB4 */
+ {
+ ret = hdb_create(context, &db, tmp_db);
+ if(ret)
+ krb5_err(context, 1, ret, "hdb_create(%s)", tmp_db);
+ ret = db->open(context, db, O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if(ret)
+ krb5_err(context, 1, ret, "hdb_open(%s)", tmp_db);
+ }
+ }
+
+#ifdef KRB4
+ if (v4dump) {
+ e = kdb_get_master_key(0, &mkey4, msched4);
+ if(e)
+ krb5_errx(context, 1, "kdb_get_master_key: %s",
+ krb_get_err_text(e));
+ }
+#endif /* KRB4 */
+
+ nprincs = 0;
+ while(1){
+ krb5_data data;
+ hdb_entry entry;
+
+ if(from_stdin){
+ ret = recv_clear(context, fd, &data);
+ if(ret)
+ krb5_err(context, 1, ret, "recv_clear");
+ }else{
+ ret = recv_priv(context, ac, fd, &data);
+ if(ret)
+ krb5_err(context, 1, ret, "recv_priv");
+ }
+
+ if(data.length == 0) {
+ if(!from_stdin) {
+ data.data = NULL;
+ data.length = 0;
+ send_priv(context, ac, &data, fd);
+ }
+ if(!print_dump) {
+#ifdef KRB4
+ if (v4dump) {
+ ret = rename(tmp_db, database);
+ if (ret)
+ krb5_errx(context, 1, "rename");
+ ret = close(fd_out);
+ if (ret)
+ krb5_errx(context, 1, "close");
+ } else
+#endif /* KRB4 */
+ {
+ ret = db->rename(context, db, database);
+ if(ret)
+ krb5_err(context, 1, ret, "db_rename");
+ ret = db->close(context, db);
+ if(ret)
+ krb5_err(context, 1, ret, "db_close");
+ }
+ }
+ break;
+ }
+ ret = hdb_value2entry(context, &data, &entry);
+ if(ret)
+ krb5_err(context, 1, ret, "hdb_value2entry");
+ if(print_dump)
+ hdb_print_entry(context, db, &entry, stdout);
+ else {
+#ifdef KRB4
+ if (v4dump) {
+ ret = dump_krb4(context, &entry, fd_out);
+ if(!ret) nprincs++;
+ }
+ else
+#endif /* KRB4 */
+ {
+ ret = db->store(context, db, 0, &entry);
+ if(ret == HDB_ERR_EXISTS) {
+ char *s;
+ krb5_unparse_name(context, entry.principal, &s);
+ krb5_warnx(context, "Entry exists: %s", s);
+ free(s);
+ } else if(ret)
+ krb5_err(context, 1, ret, "db_store");
+ else
+ nprincs++;
+ }
+ }
+ hdb_free_entry(context, &entry);
+ }
+ if (!print_dump)
+ krb5_log(context, fac, 0, "Received %d principals", nprincs);
+ exit(0);
+}
diff --git a/crypto/heimdal/kdc/kadb.h b/crypto/heimdal/kdc/kadb.h
new file mode 100644
index 000000000000..e85dbe2d5ba8
--- /dev/null
+++ b/crypto/heimdal/kdc/kadb.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: kadb.h,v 1.2 1999/12/02 17:04:59 joda Exp $ */
+
+#ifndef __kadb_h__
+#define __kadb_h__
+
+#define HASHSIZE 8191
+
+struct ka_header {
+ int32_t version1; /* file format version, should
+ match version2 */
+ int32_t size;
+ int32_t free_ptr;
+ int32_t eof_ptr;
+ int32_t kvno_ptr;
+ int32_t stats[8];
+ int32_t admin_accounts;
+ int32_t special_keys_version;
+ int32_t hashsize; /* allocated size of hash */
+ int32_t hash[HASHSIZE];
+ int32_t version2;
+};
+
+struct ka_entry {
+ int32_t flags; /* see below */
+ int32_t next; /* next in hash list */
+ int32_t pw_end; /* expiration date */
+ int32_t mod_time; /* time last modified */
+ int32_t mod_ptr; /* pointer to modifier */
+ int32_t pw_change; /* last pw change */
+ int32_t max_life; /* max ticket life */
+ int32_t kvno;
+ int32_t foo2[2]; /* huh? */
+ char name[64];
+ char instance[64];
+ char key[8];
+};
+
+#define KAFNORMAL (1<<0)
+#define KAFADMIN (1<<2) /* an administrator */
+#define KAFNOTGS (1<<3) /* ! allow principal to get or use TGT */
+#define KAFNOSEAL (1<<5) /* ! allow principal as server in GetTicket */
+#define KAFNOCPW (1<<6) /* ! allow principal to change its own key */
+#define KAFSPECIAL (1<<8) /* set if special AuthServer principal */
+
+#endif /* __kadb_h__ */
diff --git a/crypto/heimdal/kdc/kaserver.c b/crypto/heimdal/kdc/kaserver.c
new file mode 100644
index 000000000000..dc155faa95ec
--- /dev/null
+++ b/crypto/heimdal/kdc/kaserver.c
@@ -0,0 +1,794 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kdc_locl.h"
+
+RCSID("$Id: kaserver.c,v 1.9 1999/12/02 17:04:59 joda Exp $");
+
+#ifdef KASERVER
+
+#include "kerberos4.h"
+#include <rx.h>
+
+#define KA_AUTHENTICATION_SERVICE 731
+#define KA_TICKET_GRANTING_SERVICE 732
+#define KA_MAINTENANCE_SERVICE 733
+
+#define AUTHENTICATE_OLD 1
+#define CHANGEPASSWORD 2
+#define GETTICKET_OLD 3
+#define SETPASSWORD 4
+#define SETFIELDS 5
+#define CREATEUSER 6
+#define DELETEUSER 7
+#define GETENTRY 8
+#define LISTENTRY 9
+#define GETSTATS 10
+#define DEBUG 11
+#define GETPASSWORD 12
+#define GETRANDOMKEY 13
+#define AUTHENTICATE 21
+#define AUTHENTICATE_V2 22
+#define GETTICKET 23
+
+/* XXX - Where do we get these? */
+
+#define RXGEN_OPCODE (-455)
+
+#define KADATABASEINCONSISTENT (180480L)
+#define KAEXIST (180481L)
+#define KAIO (180482L)
+#define KACREATEFAIL (180483L)
+#define KANOENT (180484L)
+#define KAEMPTY (180485L)
+#define KABADNAME (180486L)
+#define KABADINDEX (180487L)
+#define KANOAUTH (180488L)
+#define KAANSWERTOOLONG (180489L)
+#define KABADREQUEST (180490L)
+#define KAOLDINTERFACE (180491L)
+#define KABADARGUMENT (180492L)
+#define KABADCMD (180493L)
+#define KANOKEYS (180494L)
+#define KAREADPW (180495L)
+#define KABADKEY (180496L)
+#define KAUBIKINIT (180497L)
+#define KAUBIKCALL (180498L)
+#define KABADPROTOCOL (180499L)
+#define KANOCELLS (180500L)
+#define KANOCELL (180501L)
+#define KATOOMANYUBIKS (180502L)
+#define KATOOMANYKEYS (180503L)
+#define KABADTICKET (180504L)
+#define KAUNKNOWNKEY (180505L)
+#define KAKEYCACHEINVALID (180506L)
+#define KABADSERVER (180507L)
+#define KABADUSER (180508L)
+#define KABADCPW (180509L)
+#define KABADCREATE (180510L)
+#define KANOTICKET (180511L)
+#define KAASSOCUSER (180512L)
+#define KANOTSPECIAL (180513L)
+#define KACLOCKSKEW (180514L)
+#define KANORECURSE (180515L)
+#define KARXFAIL (180516L)
+#define KANULLPASSWORD (180517L)
+#define KAINTERNALERROR (180518L)
+#define KAPWEXPIRED (180519L)
+#define KAREUSED (180520L)
+#define KATOOSOON (180521L)
+#define KALOCKED (180522L)
+
+static void
+decode_rx_header (krb5_storage *sp,
+ struct rx_header *h)
+{
+ krb5_ret_int32(sp, &h->epoch);
+ krb5_ret_int32(sp, &h->connid);
+ krb5_ret_int32(sp, &h->callid);
+ krb5_ret_int32(sp, &h->seqno);
+ krb5_ret_int32(sp, &h->serialno);
+ krb5_ret_int8(sp, &h->type);
+ krb5_ret_int8(sp, &h->flags);
+ krb5_ret_int8(sp, &h->status);
+ krb5_ret_int8(sp, &h->secindex);
+ krb5_ret_int16(sp, &h->reserved);
+ krb5_ret_int16(sp, &h->serviceid);
+}
+
+static void
+encode_rx_header (struct rx_header *h,
+ krb5_storage *sp)
+{
+ krb5_store_int32(sp, h->epoch);
+ krb5_store_int32(sp, h->connid);
+ krb5_store_int32(sp, h->callid);
+ krb5_store_int32(sp, h->seqno);
+ krb5_store_int32(sp, h->serialno);
+ krb5_store_int8(sp, h->type);
+ krb5_store_int8(sp, h->flags);
+ krb5_store_int8(sp, h->status);
+ krb5_store_int8(sp, h->secindex);
+ krb5_store_int16(sp, h->reserved);
+ krb5_store_int16(sp, h->serviceid);
+}
+
+static void
+init_reply_header (struct rx_header *hdr,
+ struct rx_header *reply_hdr,
+ u_char type,
+ u_char flags)
+{
+ reply_hdr->epoch = hdr->epoch;
+ reply_hdr->connid = hdr->connid;
+ reply_hdr->callid = hdr->callid;
+ reply_hdr->seqno = 1;
+ reply_hdr->serialno = 1;
+ reply_hdr->type = type;
+ reply_hdr->flags = flags;
+ reply_hdr->status = 0;
+ reply_hdr->secindex = 0;
+ reply_hdr->reserved = 0;
+ reply_hdr->serviceid = hdr->serviceid;
+}
+
+static void
+make_error_reply (struct rx_header *hdr,
+ u_int32_t ret,
+ krb5_data *reply)
+
+{
+ krb5_storage *sp;
+ struct rx_header reply_hdr;
+
+ init_reply_header (hdr, &reply_hdr, HT_ABORT, HF_LAST);
+ sp = krb5_storage_emem();
+ encode_rx_header (&reply_hdr, sp);
+ krb5_store_int32(sp, ret);
+ krb5_storage_to_data (sp, reply);
+ krb5_storage_free (sp);
+}
+
+static krb5_error_code
+krb5_ret_xdr_data(krb5_storage *sp,
+ krb5_data *data)
+{
+ int ret;
+ int size;
+ ret = krb5_ret_int32(sp, &size);
+ if(ret)
+ return ret;
+ data->length = size;
+ if (size) {
+ u_char foo[4];
+ size_t pad = (4 - size % 4) % 4;
+
+ data->data = malloc(size);
+ if (data->data == NULL)
+ return ENOMEM;
+ ret = sp->fetch(sp, data->data, size);
+ if(ret != size)
+ return (ret < 0)? errno : KRB5_CC_END;
+ if (pad) {
+ ret = sp->fetch(sp, foo, pad);
+ if (ret != pad)
+ return (ret < 0)? errno : KRB5_CC_END;
+ }
+ } else
+ data->data = NULL;
+ return 0;
+}
+
+static krb5_error_code
+krb5_store_xdr_data(krb5_storage *sp,
+ krb5_data data)
+{
+ u_char zero[4] = {0, 0, 0, 0};
+ int ret;
+ size_t pad;
+
+ ret = krb5_store_int32(sp, data.length);
+ if(ret < 0)
+ return ret;
+ ret = sp->store(sp, data.data, data.length);
+ if(ret != data.length){
+ if(ret < 0)
+ return errno;
+ return KRB5_CC_END;
+ }
+ pad = (4 - data.length % 4) % 4;
+ if (pad) {
+ ret = sp->store(sp, zero, pad);
+ if (ret != pad) {
+ if (ret < 0)
+ return errno;
+ return KRB5_CC_END;
+ }
+ }
+ return 0;
+}
+
+
+static krb5_error_code
+create_reply_ticket (struct rx_header *hdr,
+ Key *skey,
+ char *name, char *instance, char *realm,
+ struct sockaddr_in *addr,
+ int life,
+ int kvno,
+ int32_t max_seq_len,
+ char *sname, char *sinstance,
+ u_int32_t challenge,
+ char *label,
+ des_cblock *key,
+ krb5_data *reply)
+{
+ KTEXT_ST ticket;
+ des_cblock session;
+ krb5_storage *sp;
+ krb5_data enc_data;
+ des_key_schedule schedule;
+ struct rx_header reply_hdr;
+ des_cblock zero;
+ size_t pad;
+ unsigned fyrtiosjuelva;
+
+ /* create the ticket */
+
+ des_new_random_key(&session);
+
+ krb_create_ticket (&ticket, 0, name, instance, realm,
+ addr->sin_addr.s_addr,
+ &session, life, kdc_time,
+ sname, sinstance, skey->key.keyvalue.data);
+
+ /* create the encrypted part of the reply */
+ sp = krb5_storage_emem ();
+ krb5_generate_random_block(&fyrtiosjuelva, sizeof(fyrtiosjuelva));
+ fyrtiosjuelva &= 0xffffffff;
+ krb5_store_int32 (sp, fyrtiosjuelva);
+#if 0
+ krb5_store_int32 (sp, 4711); /* XXX */
+#endif
+ krb5_store_int32 (sp, challenge);
+ sp->store (sp, session, 8);
+ memset (&session, 0, sizeof(session));
+ krb5_store_int32 (sp, kdc_time);
+ krb5_store_int32 (sp, kdc_time + krb_life_to_time (0, life));
+ krb5_store_int32 (sp, kvno);
+ krb5_store_int32 (sp, ticket.length);
+ krb5_store_stringz (sp, name);
+ krb5_store_stringz (sp, instance);
+#if 1 /* XXX - Why shouldn't the realm go here? */
+ krb5_store_stringz (sp, "");
+#else
+ krb5_store_stringz (sp, realm);
+#endif
+ krb5_store_stringz (sp, sname);
+ krb5_store_stringz (sp, sinstance);
+ sp->store (sp, ticket.dat, ticket.length);
+ sp->store (sp, label, strlen(label));
+
+ /* pad to DES block */
+ memset (zero, 0, sizeof(zero));
+ pad = (8 - sp->seek (sp, 0, SEEK_CUR) % 8) % 8;
+ sp->store (sp, zero, pad);
+
+ krb5_storage_to_data (sp, &enc_data);
+ krb5_storage_free (sp);
+
+ if (enc_data.length > max_seq_len) {
+ krb5_data_free (&enc_data);
+ make_error_reply (hdr, KAANSWERTOOLONG, reply);
+ return 0;
+ }
+
+ /* encrypt it */
+ des_set_key (key, schedule);
+ des_pcbc_encrypt ((des_cblock *)enc_data.data,
+ (des_cblock *)enc_data.data,
+ enc_data.length,
+ schedule,
+ key,
+ DES_ENCRYPT);
+ memset (&schedule, 0, sizeof(schedule));
+
+ /* create the reply packet */
+ init_reply_header (hdr, &reply_hdr, HT_DATA, HF_LAST);
+ sp = krb5_storage_emem ();
+ encode_rx_header (&reply_hdr, sp);
+ krb5_store_int32 (sp, max_seq_len);
+ krb5_store_xdr_data (sp, enc_data);
+ krb5_data_free (&enc_data);
+ krb5_storage_to_data (sp, reply);
+ krb5_storage_free (sp);
+ return 0;
+}
+
+static krb5_error_code
+unparse_auth_args (krb5_storage *sp,
+ char **name,
+ char **instance,
+ time_t *start_time,
+ time_t *end_time,
+ krb5_data *request,
+ int32_t *max_seq_len)
+{
+ krb5_data data;
+ int32_t tmp;
+
+ krb5_ret_xdr_data (sp, &data);
+ *name = malloc(data.length + 1);
+ if (*name == NULL)
+ return ENOMEM;
+ memcpy (*name, data.data, data.length);
+ (*name)[data.length] = '\0';
+ krb5_data_free (&data);
+
+ krb5_ret_xdr_data (sp, &data);
+ *instance = malloc(data.length + 1);
+ if (*instance == NULL) {
+ free (*name);
+ return ENOMEM;
+ }
+ memcpy (*instance, data.data, data.length);
+ (*instance)[data.length] = '\0';
+ krb5_data_free (&data);
+
+ krb5_ret_int32 (sp, &tmp);
+ *start_time = tmp;
+ krb5_ret_int32 (sp, &tmp);
+ *end_time = tmp;
+ krb5_ret_xdr_data (sp, request);
+ krb5_ret_int32 (sp, max_seq_len);
+ /* ignore the rest */
+ return 0;
+}
+
+static void
+do_authenticate (struct rx_header *hdr,
+ krb5_storage *sp,
+ struct sockaddr_in *addr,
+ krb5_data *reply)
+{
+ krb5_error_code ret;
+ char *name = NULL;
+ char *instance = NULL;
+ time_t start_time;
+ time_t end_time;
+ krb5_data request;
+ int32_t max_seq_len;
+ hdb_entry *client_entry = NULL;
+ hdb_entry *server_entry = NULL;
+ Key *ckey = NULL;
+ Key *skey = NULL;
+ des_cblock key;
+ des_key_schedule schedule;
+ krb5_storage *reply_sp;
+ time_t max_life;
+ u_int8_t life;
+ int32_t chal;
+
+ krb5_data_zero (&request);
+
+ unparse_auth_args (sp, &name, &instance, &start_time, &end_time,
+ &request, &max_seq_len);
+
+ client_entry = db_fetch4 (name, instance, v4_realm);
+ if (client_entry == NULL) {
+ kdc_log(0, "Client not found in database: %s.%s@%s",
+ name, instance, v4_realm);
+ make_error_reply (hdr, KANOENT, reply);
+ goto out;
+ }
+
+ server_entry = db_fetch4 ("krbtgt", v4_realm, v4_realm);
+ if (server_entry == NULL) {
+ kdc_log(0, "Server not found in database: %s.%s@%s",
+ "krbtgt", v4_realm, v4_realm);
+ make_error_reply (hdr, KANOENT, reply);
+ goto out;
+ }
+
+ /* find a DES key */
+ ret = get_des_key(client_entry, &ckey);
+ if(ret){
+ kdc_log(0, "%s", krb5_get_err_text(context, ret));
+ make_error_reply (hdr, KANOKEYS, reply);
+ goto out;
+ }
+
+ /* find a DES key */
+ ret = get_des_key(server_entry, &skey);
+ if(ret){
+ kdc_log(0, "%s", krb5_get_err_text(context, ret));
+ make_error_reply (hdr, KANOKEYS, reply);
+ goto out;
+ }
+
+ /* try to decode the `request' */
+ memcpy (&key, ckey->key.keyvalue.data, sizeof(key));
+ des_set_key (&key, schedule);
+ des_pcbc_encrypt ((des_cblock *)request.data,
+ (des_cblock *)request.data,
+ request.length,
+ schedule,
+ &key,
+ DES_DECRYPT);
+ memset (&schedule, 0, sizeof(schedule));
+
+ /* check for the magic label */
+ if (memcmp ((char *)request.data + 4, "gTGS", 4) != 0) {
+ make_error_reply (hdr, KABADREQUEST, reply);
+ goto out;
+ }
+
+ reply_sp = krb5_storage_from_mem (request.data, 4);
+ krb5_ret_int32 (reply_sp, &chal);
+ krb5_storage_free (reply_sp);
+
+ /* life */
+ max_life = end_time - kdc_time;
+ if (client_entry->max_life)
+ max_life = min(max_life, *client_entry->max_life);
+ if (server_entry->max_life)
+ max_life = min(max_life, *server_entry->max_life);
+
+ life = krb_time_to_life(kdc_time, kdc_time + max_life);
+
+ create_reply_ticket (hdr, skey,
+ name, instance, v4_realm,
+ addr, life, client_entry->kvno,
+ max_seq_len,
+ "krbtgt", v4_realm,
+ chal + 1, "tgsT",
+ &key, reply);
+ memset (&key, 0, sizeof(key));
+
+out:
+ if (request.length) {
+ memset (request.data, 0, request.length);
+ krb5_data_free (&request);
+ }
+ if (name)
+ free (name);
+ if (instance)
+ free (instance);
+ if (client_entry) {
+ hdb_free_entry (context, client_entry);
+ free (client_entry);
+ }
+ if (server_entry) {
+ hdb_free_entry (context, server_entry);
+ free (server_entry);
+ }
+}
+
+static krb5_error_code
+unparse_getticket_args (krb5_storage *sp,
+ int *kvno,
+ char **auth_domain,
+ krb5_data *ticket,
+ char **name,
+ char **instance,
+ krb5_data *times,
+ int32_t *max_seq_len)
+{
+ krb5_data data;
+ int32_t tmp;
+
+ krb5_ret_int32 (sp, &tmp);
+ *kvno = tmp;
+
+ krb5_ret_xdr_data (sp, &data);
+ *auth_domain = malloc(data.length + 1);
+ if (*auth_domain == NULL)
+ return ENOMEM;
+ memcpy (*auth_domain, data.data, data.length);
+ (*auth_domain)[data.length] = '\0';
+ krb5_data_free (&data);
+
+ krb5_ret_xdr_data (sp, ticket);
+
+ krb5_ret_xdr_data (sp, &data);
+ *name = malloc(data.length + 1);
+ if (*name == NULL) {
+ free (*auth_domain);
+ return ENOMEM;
+ }
+ memcpy (*name, data.data, data.length);
+ (*name)[data.length] = '\0';
+ krb5_data_free (&data);
+
+ krb5_ret_xdr_data (sp, &data);
+ *instance = malloc(data.length + 1);
+ if (*instance == NULL) {
+ free (*auth_domain);
+ free (*name);
+ return ENOMEM;
+ }
+ memcpy (*instance, data.data, data.length);
+ (*instance)[data.length] = '\0';
+ krb5_data_free (&data);
+
+ krb5_ret_xdr_data (sp, times);
+
+ krb5_ret_int32 (sp, max_seq_len);
+ /* ignore the rest */
+ return 0;
+}
+
+static void
+do_getticket (struct rx_header *hdr,
+ krb5_storage *sp,
+ struct sockaddr_in *addr,
+ krb5_data *reply)
+{
+ krb5_error_code ret;
+ int kvno;
+ char *auth_domain = NULL;
+ krb5_data aticket;
+ char *name = NULL;
+ char *instance = NULL;
+ krb5_data times;
+ int32_t max_seq_len;
+ hdb_entry *server_entry = NULL;
+ hdb_entry *krbtgt_entry = NULL;
+ Key *kkey = NULL;
+ Key *skey = NULL;
+ des_cblock key;
+ des_key_schedule schedule;
+ des_cblock session;
+ time_t max_life;
+ int8_t life;
+ time_t start_time, end_time;
+ char pname[ANAME_SZ];
+ char pinst[INST_SZ];
+ char prealm[REALM_SZ];
+
+ krb5_data_zero (&aticket);
+ krb5_data_zero (&times);
+
+ unparse_getticket_args (sp, &kvno, &auth_domain, &aticket,
+ &name, &instance, &times, &max_seq_len);
+
+ server_entry = db_fetch4 (name, instance, v4_realm);
+ if (server_entry == NULL) {
+ kdc_log(0, "Server not found in database: %s.%s@%s",
+ name, instance, v4_realm);
+ make_error_reply (hdr, KANOENT, reply);
+ goto out;
+ }
+
+ krbtgt_entry = db_fetch4 ("krbtgt", v4_realm, v4_realm);
+ if (krbtgt_entry == NULL) {
+ kdc_log(0, "Server not found in database: %s.%s@%s",
+ "krbtgt", v4_realm, v4_realm);
+ make_error_reply (hdr, KANOENT, reply);
+ goto out;
+ }
+
+ /* find a DES key */
+ ret = get_des_key(krbtgt_entry, &kkey);
+ if(ret){
+ kdc_log(0, "%s", krb5_get_err_text(context, ret));
+ make_error_reply (hdr, KANOKEYS, reply);
+ goto out;
+ }
+
+ /* find a DES key */
+ ret = get_des_key(server_entry, &skey);
+ if(ret){
+ kdc_log(0, "%s", krb5_get_err_text(context, ret));
+ make_error_reply (hdr, KANOKEYS, reply);
+ goto out;
+ }
+
+ /* decrypt the incoming ticket */
+ memcpy (&key, kkey->key.keyvalue.data, sizeof(key));
+
+ /* unpack the ticket */
+ {
+ KTEXT_ST ticket;
+ u_char flags;
+ int life;
+ u_int32_t time_sec;
+ char sname[ANAME_SZ];
+ char sinstance[SNAME_SZ];
+ u_int32_t paddress;
+
+ ticket.length = aticket.length;
+ memcpy (ticket.dat, aticket.data, ticket.length);
+
+ des_set_key (&key, schedule);
+ decomp_ticket (&ticket, &flags, pname, pinst, prealm,
+ &paddress, session, &life, &time_sec,
+ sname, sinstance,
+ &key, schedule);
+
+ if (strcmp (sname, "krbtgt") != 0
+ || strcmp (sinstance, v4_realm) != 0) {
+ kdc_log(0, "no TGT: %s.%s for %s.%s@%s",
+ sname, sinstance,
+ pname, pinst, prealm);
+ make_error_reply (hdr, KABADTICKET, reply);
+ goto out;
+ }
+
+ if (kdc_time > krb_life_to_time(time_sec, life)) {
+ kdc_log(0, "TGT expired: %s.%s@%s",
+ pname, pinst, prealm);
+ make_error_reply (hdr, KABADTICKET, reply);
+ goto out;
+ }
+ }
+
+ /* decrypt the times */
+ des_set_key (&session, schedule);
+ des_ecb_encrypt (times.data,
+ times.data,
+ schedule,
+ DES_DECRYPT);
+ memset (&schedule, 0, sizeof(schedule));
+
+ /* and extract them */
+ {
+ krb5_storage *sp;
+ int32_t tmp;
+
+ sp = krb5_storage_from_mem (times.data, times.length);
+ krb5_ret_int32 (sp, &tmp);
+ start_time = tmp;
+ krb5_ret_int32 (sp, &tmp);
+ end_time = tmp;
+ krb5_storage_free (sp);
+ }
+
+ /* life */
+ max_life = end_time - kdc_time;
+ if (krbtgt_entry->max_life)
+ max_life = min(max_life, *krbtgt_entry->max_life);
+ if (server_entry->max_life)
+ max_life = min(max_life, *server_entry->max_life);
+
+ life = krb_time_to_life(kdc_time, kdc_time + max_life);
+
+ create_reply_ticket (hdr, skey,
+ pname, pinst, prealm,
+ addr, life, server_entry->kvno,
+ max_seq_len,
+ name, instance,
+ 0, "gtkt",
+ &session, reply);
+ memset (&session, 0, sizeof(session));
+
+out:
+ if (aticket.length) {
+ memset (aticket.data, 0, aticket.length);
+ krb5_data_free (&aticket);
+ }
+ if (times.length) {
+ memset (times.data, 0, times.length);
+ krb5_data_free (&times);
+ }
+ if (auth_domain)
+ free (auth_domain);
+ if (name)
+ free (name);
+ if (instance)
+ free (instance);
+ if (krbtgt_entry) {
+ hdb_free_entry (context, krbtgt_entry);
+ free (krbtgt_entry);
+ }
+ if (server_entry) {
+ hdb_free_entry (context, server_entry);
+ free (server_entry);
+ }
+}
+
+krb5_error_code
+do_kaserver(unsigned char *buf,
+ size_t len,
+ krb5_data *reply,
+ const char *from,
+ struct sockaddr_in *addr)
+{
+ krb5_error_code ret = 0;
+ struct rx_header hdr;
+ u_int32_t op;
+ krb5_storage *sp;
+
+ if (len < RX_HEADER_SIZE)
+ return -1;
+ sp = krb5_storage_from_mem (buf, len);
+
+ decode_rx_header (sp, &hdr);
+ buf += RX_HEADER_SIZE;
+ len -= RX_HEADER_SIZE;
+
+ switch (hdr.type) {
+ case HT_DATA :
+ break;
+ case HT_ACK :
+ case HT_BUSY :
+ case HT_ABORT :
+ case HT_ACKALL :
+ case HT_CHAL :
+ case HT_RESP :
+ case HT_DEBUG :
+ default:
+ /* drop */
+ goto out;
+ }
+
+
+ if (hdr.serviceid != KA_AUTHENTICATION_SERVICE
+ && hdr.serviceid != KA_TICKET_GRANTING_SERVICE) {
+ ret = -1;
+ goto out;
+ }
+
+ krb5_ret_int32(sp, &op);
+ switch (op) {
+ case AUTHENTICATE :
+ do_authenticate (&hdr, sp, addr, reply);
+ break;
+ case GETTICKET :
+ do_getticket (&hdr, sp, addr, reply);
+ break;
+ case AUTHENTICATE_OLD :
+ case CHANGEPASSWORD :
+ case GETTICKET_OLD :
+ case SETPASSWORD :
+ case SETFIELDS :
+ case CREATEUSER :
+ case DELETEUSER :
+ case GETENTRY :
+ case LISTENTRY :
+ case GETSTATS :
+ case DEBUG :
+ case GETPASSWORD :
+ case GETRANDOMKEY :
+ case AUTHENTICATE_V2 :
+ default :
+ make_error_reply (&hdr, RXGEN_OPCODE, reply);
+ break;
+ }
+
+out:
+ krb5_storage_free (sp);
+ return ret;
+}
+
+#endif /* KASERVER */
diff --git a/crypto/heimdal/kdc/kdc.8 b/crypto/heimdal/kdc/kdc.8
new file mode 100644
index 000000000000..89251118c3cf
--- /dev/null
+++ b/crypto/heimdal/kdc/kdc.8
@@ -0,0 +1,92 @@
+.\" $Id: kdc.8,v 1.3 1997/08/09 00:20:38 joda Exp $
+.\"
+.Dd July 27, 1997
+.Dt KDC 8
+.Os HEIMDAL
+.Sh NAME
+.Nm kdc
+.Nd
+Kerberos 5 server
+.Sh SYNOPSIS
+.Nm
+.Op Fl c Ar file
+.Op Fl -config-file= Ns Ar file
+.Op Fl k Ar file
+.Op Fl -key-file= Ns Ar file
+.Op Fl p
+.Op Fl -no-require-preauth
+.Op Fl r Ar realm
+.Op Fl -v4-realm= Ns Ar realm
+
+.Sh DESCRIPTION
+.Nm
+serves requests for tickets. When it starts, it first checks the flags
+passed, any options that are not specified with a command line flag is
+taken from a config file, or from a default compiled-in value.
+.Pp
+Options supported:
+.Bl -tag -width Ds
+.It Fl c Ar file
+.It Fl -config-file= Ns Ar file
+Specifies the location of the config file, the default is
+.Pa /var/heimdal/kdc.conf .
+This is the only value that can't be specified in the config file.
+.It Fl k Ar file
+.It Fl -key-file= Ns Ar file
+The location of the master-key file. All keys in the database is
+encrypted with this master key. The use of a master key is currently
+optional, so there is no default.
+.Em "Don't specify a master key file if your database is not encrypted."
+.It Fl p
+.It Fl -no-require-preauth
+Turn off the requirement for pre-autentication in the initial
+AS-REQ. The use of pre-authentication makes it more difficult to do
+offline password attacks. You might want to turn it off if you have
+clients that doesn't do pre-authentication. Since the version 4
+protocol doesn't support any pre-authentication, so serving version 4
+clients is just about the same as not requiring pre-athentication. The
+default is to require pre-authentication.
+.It Fl r Ar realm
+.It Fl -v4-realm= Ns Ar realm
+What realm this server should act as when dealing with version 4
+requests. The database can contain any number of realms, but since the
+version 4 protocol doesn't contain a realm for the server, it must be
+explicitly specified. The default is whatever is returned by
+.Fn krb_get_lrealm .
+This option is only availabe if the KDC has been compiled with version
+4 support.
+.El
+.Pp
+All activities , are logged to one or more destinations, see
+.Xr krb5.conf 5 ,
+and
+.Xr krb5_openlog 3 .
+The entity used for logging is
+.Nm kdc .
+.Sh CONFIGURATION FILE
+The configuration file has the same syntax as the
+.Pa krb5.conf
+file (you can actually put the configuration in
+.Pa /etc/krb5.conf ,
+and then start the KDC with
+.Fl -config-file= Ns Ar /etc/krb5.conf ) .
+All options should be in a section called
+.Dq kdc .
+Options are called the same as the long option name, and takes the
+same arguments. The only difference is the pre-authentication flag,
+that has to be specified as:
+.Pp
+.Dl require-preauth = no
+.Pp
+(in fact you can specify the option as
+.Fl -require-preauth=no ) .
+.Pp
+An example of a config file:
+.Bd -literal -offset indent
+[kdc]
+ require-preauth = no
+ v4-realm = FOO.SE
+ key-file = /key-file
+.Ed
+.Sh SEE ALSO
+.Xr kinit 1
diff --git a/crypto/heimdal/kdc/kdc_locl.h b/crypto/heimdal/kdc/kdc_locl.h
new file mode 100644
index 000000000000..727557693090
--- /dev/null
+++ b/crypto/heimdal/kdc/kdc_locl.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*
+ * $Id: kdc_locl.h,v 1.39 1999/12/02 17:04:59 joda Exp $
+ */
+
+#ifndef __KDC_LOCL_H__
+#define __KDC_LOCL_H__
+
+#include "headers.h"
+
+extern krb5_context context;
+
+extern int require_preauth;
+extern sig_atomic_t exit_flag;
+extern char *keyfile;
+extern size_t max_request;
+extern time_t kdc_warn_pwexpire;
+extern struct dbinfo {
+ char *realm;
+ char *dbname;
+ char *mkey_file;
+ struct dbinfo *next;
+} *databases;
+extern HDB **db;
+extern int num_db;
+extern char *port_str;
+extern int enable_http;
+extern krb5_boolean encode_as_rep_as_tgs_rep;
+extern krb5_boolean check_ticket_addresses;
+extern krb5_boolean allow_null_ticket_addresses;
+
+#ifdef KRB4
+extern char *v4_realm;
+#endif
+#ifdef KASERVER
+extern krb5_boolean enable_kaserver;
+#endif
+
+extern struct timeval now;
+#define kdc_time (now.tv_sec)
+
+krb5_error_code as_rep (KDC_REQ*, krb5_data*, const char*, struct sockaddr*);
+void configure (int, char**);
+hdb_entry* db_fetch (krb5_principal);
+void kdc_log (int, const char*, ...);
+char* kdc_log_msg (int, const char*, ...);
+char* kdc_log_msg_va (int, const char*, va_list);
+void kdc_openlog (krb5_config_section*);
+void loop (void);
+void set_master_key (EncryptionKey);
+krb5_error_code tgs_rep (KDC_REQ*, krb5_data*, const char*, struct sockaddr *);
+Key* unseal_key (Key*);
+
+#ifdef KRB4
+hdb_entry* db_fetch4 (const char*, const char*, const char*);
+krb5_error_code do_524 (Ticket*, krb5_data*, const char*, struct sockaddr*);
+krb5_error_code do_version4 (unsigned char*, size_t, krb5_data*, const char*,
+ struct sockaddr_in*);
+krb5_error_code encode_v4_ticket (void*, size_t, EncTicketPart*,
+ PrincipalName*, size_t*);
+krb5_error_code encrypt_v4_ticket (void*, size_t, des_cblock*, EncryptedData*);
+krb5_error_code get_des_key(hdb_entry*, Key**);
+int maybe_version4 (unsigned char*, int);
+#endif
+
+#ifdef KASERVER
+krb5_error_code do_kaserver (unsigned char*, size_t, krb5_data*, const char*,
+ struct sockaddr_in*);
+#endif
+
+#endif /* __KDC_LOCL_H__ */
diff --git a/crypto/heimdal/kdc/kerberos4.c b/crypto/heimdal/kdc/kerberos4.c
new file mode 100644
index 000000000000..9ff082c3698b
--- /dev/null
+++ b/crypto/heimdal/kdc/kerberos4.c
@@ -0,0 +1,557 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kdc_locl.h"
+
+RCSID("$Id: kerberos4.c,v 1.24 1999/12/02 17:04:59 joda Exp $");
+
+#ifdef KRB4
+
+#include "kerberos4.h"
+
+#ifndef swap32
+static u_int32_t
+swap32(u_int32_t x)
+{
+ return ((x << 24) & 0xff000000) |
+ ((x << 8) & 0xff0000) |
+ ((x >> 8) & 0xff00) |
+ ((x >> 24) & 0xff);
+}
+#endif /* swap32 */
+
+int
+maybe_version4(unsigned char *buf, int len)
+{
+ return len > 0 && *buf == 4;
+}
+
+static void
+make_err_reply(krb5_data *reply, int code, const char *msg)
+{
+ KTEXT_ST er;
+
+ /* name, instance and realm is not checked in most (all?) version
+ implementations; msg is also never used, but we send it anyway
+ (for debugging purposes) */
+
+ if(msg == NULL)
+ msg = krb_get_err_text(code);
+ cr_err_reply(&er, "", "", "", kdc_time, code, (char*)msg);
+ krb5_data_copy(reply, er.dat, er.length);
+}
+
+static krb5_boolean
+valid_princ(krb5_context context, krb5_principal princ)
+{
+ char *s;
+ hdb_entry *ent;
+ krb5_unparse_name(context, princ, &s);
+ ent = db_fetch(princ);
+ if(ent == NULL){
+ kdc_log(7, "Lookup %s failed", s);
+ free(s);
+ return 0;
+ }
+ kdc_log(7, "Lookup %s succeeded", s);
+ free(s);
+ hdb_free_entry(context, ent);
+ free(ent);
+ return 1;
+}
+
+hdb_entry*
+db_fetch4(const char *name, const char *instance, const char *realm)
+{
+ krb5_principal p;
+ hdb_entry *ent;
+ krb5_error_code ret;
+
+ ret = krb5_425_conv_principal_ext(context, name, instance, realm,
+ valid_princ, 0, &p);
+ if(ret)
+ return NULL;
+ ent = db_fetch(p);
+ krb5_free_principal(context, p);
+ return ent;
+}
+
+krb5_error_code
+get_des_key(hdb_entry *principal, Key **key)
+{
+ krb5_error_code ret;
+
+ ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD5, key);
+ if(ret)
+ ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD4, key);
+ if(ret)
+ ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_CRC, key);
+ if(ret)
+ return ret;
+ if ((*key)->key.keyvalue.length == 0)
+ return KERB_ERR_NULL_KEY;
+ return 0;
+}
+
+#define RCHECK(X, L) if(X){make_err_reply(reply, KFAILURE, "Packet too short"); goto L;}
+
+krb5_error_code
+do_version4(unsigned char *buf,
+ size_t len,
+ krb5_data *reply,
+ const char *from,
+ struct sockaddr_in *addr)
+{
+ krb5_storage *sp;
+ krb5_error_code ret;
+ hdb_entry *client = NULL, *server = NULL;
+ Key *ckey, *skey;
+ int8_t pvno;
+ int8_t msg_type;
+ int lsb;
+ char *name = NULL, *inst = NULL, *realm = NULL;
+ char *sname = NULL, *sinst = NULL;
+ int32_t req_time;
+ time_t max_life;
+ u_int8_t life;
+
+ sp = krb5_storage_from_mem(buf, len);
+ RCHECK(krb5_ret_int8(sp, &pvno), out);
+ if(pvno != 4){
+ kdc_log(0, "Protocol version mismatch (%d)", pvno);
+ make_err_reply(reply, KDC_PKT_VER, NULL);
+ goto out;
+ }
+ RCHECK(krb5_ret_int8(sp, &msg_type), out);
+ lsb = msg_type & 1;
+ msg_type &= ~1;
+ switch(msg_type){
+ case AUTH_MSG_KDC_REQUEST:
+ RCHECK(krb5_ret_stringz(sp, &name), out1);
+ RCHECK(krb5_ret_stringz(sp, &inst), out1);
+ RCHECK(krb5_ret_stringz(sp, &realm), out1);
+ RCHECK(krb5_ret_int32(sp, &req_time), out1);
+ if(lsb)
+ req_time = swap32(req_time);
+ RCHECK(krb5_ret_int8(sp, &life), out1);
+ RCHECK(krb5_ret_stringz(sp, &sname), out1);
+ RCHECK(krb5_ret_stringz(sp, &sinst), out1);
+ kdc_log(0, "AS-REQ %s.%s@%s from %s for %s.%s",
+ name, inst, realm, from, sname, sinst);
+
+ client = db_fetch4(name, inst, realm);
+ if(client == NULL){
+ kdc_log(0, "Client not found in database: %s.%s@%s",
+ name, inst, realm);
+ make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, NULL);
+ goto out1;
+ }
+ server = db_fetch4(sname, sinst, v4_realm);
+ if(server == NULL){
+ kdc_log(0, "Server not found in database: %s.%s@%s",
+ sname, sinst, v4_realm);
+ make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, NULL);
+ goto out1;
+ }
+
+ ret = get_des_key(client, &ckey);
+ if(ret){
+ kdc_log(0, "%s", krb5_get_err_text(context, ret));
+ /* XXX */
+ make_err_reply(reply, KDC_NULL_KEY,
+ "No DES key in database (client)");
+ goto out1;
+ }
+
+#if 0
+ /* this is not necessary with the new code in libkrb */
+ /* find a properly salted key */
+ while(ckey->salt == NULL || ckey->salt->salt.length != 0)
+ ret = hdb_next_keytype2key(context, client, KEYTYPE_DES, &ckey);
+ if(ret){
+ kdc_log(0, "No version-4 salted key in database -- %s.%s@%s",
+ name, inst, realm);
+ make_err_reply(reply, KDC_NULL_KEY,
+ "No version-4 salted key in database");
+ goto out1;
+ }
+#endif
+
+ ret = get_des_key(server, &skey);
+ if(ret){
+ kdc_log(0, "%s", krb5_get_err_text(context, ret));
+ /* XXX */
+ make_err_reply(reply, KDC_NULL_KEY,
+ "No DES key in database (server)");
+ goto out1;
+ }
+
+ max_life = krb_life_to_time(0, life);
+ if(client->max_life)
+ max_life = min(max_life, *client->max_life);
+ if(server->max_life)
+ max_life = min(max_life, *server->max_life);
+
+ life = krb_time_to_life(kdc_time, kdc_time + max_life);
+
+ {
+ KTEXT_ST cipher, ticket;
+ KTEXT r;
+ des_cblock session;
+
+ des_new_random_key(&session);
+
+ krb_create_ticket(&ticket, 0, name, inst, v4_realm,
+ addr->sin_addr.s_addr, session, life, kdc_time,
+ sname, sinst, skey->key.keyvalue.data);
+
+ create_ciph(&cipher, session, sname, sinst, v4_realm,
+ life, server->kvno, &ticket, kdc_time,
+ ckey->key.keyvalue.data);
+ memset(&session, 0, sizeof(session));
+ r = create_auth_reply(name, inst, realm, req_time, 0,
+ client->pw_end ? *client->pw_end : 0,
+ client->kvno, &cipher);
+ krb5_data_copy(reply, r->dat, r->length);
+ memset(&cipher, 0, sizeof(cipher));
+ memset(&ticket, 0, sizeof(ticket));
+ }
+ out1:
+ break;
+ case AUTH_MSG_APPL_REQUEST: {
+ int8_t kvno;
+ int8_t ticket_len;
+ int8_t req_len;
+ KTEXT_ST auth;
+ AUTH_DAT ad;
+ size_t pos;
+ krb5_principal tgt_princ = NULL;
+ hdb_entry *tgt = NULL;
+ Key *tkey;
+
+ RCHECK(krb5_ret_int8(sp, &kvno), out2);
+ RCHECK(krb5_ret_stringz(sp, &realm), out2);
+
+ ret = krb5_425_conv_principal(context, "krbtgt", realm, v4_realm,
+ &tgt_princ);
+ if(ret){
+ kdc_log(0, "Converting krbtgt principal: %s",
+ krb5_get_err_text(context, ret));
+ make_err_reply(reply, KFAILURE,
+ "Failed to convert v4 principal (krbtgt)");
+ goto out2;
+ }
+
+ tgt = db_fetch(tgt_princ);
+ if(tgt == NULL){
+ char *s;
+ s = kdc_log_msg(0, "Ticket-granting ticket not "
+ "found in database: krbtgt.%s@%s",
+ realm, v4_realm);
+ make_err_reply(reply, KFAILURE, s);
+ free(s);
+ goto out2;
+ }
+
+ if(tgt->kvno != kvno){
+ goto out2;
+ }
+
+ ret = get_des_key(tgt, &tkey);
+ if(ret){
+ kdc_log(0, "%s", krb5_get_err_text(context, ret));
+ /* XXX */
+ make_err_reply(reply, KDC_NULL_KEY,
+ "No DES key in database (krbtgt)");
+ goto out2;
+ }
+
+ RCHECK(krb5_ret_int8(sp, &ticket_len), out2);
+ RCHECK(krb5_ret_int8(sp, &req_len), out2);
+
+ pos = sp->seek(sp, ticket_len + req_len, SEEK_CUR);
+
+ memset(&auth, 0, sizeof(auth));
+ memcpy(&auth.dat, buf, pos);
+ auth.length = pos;
+ krb_set_key(tkey->key.keyvalue.data, 0);
+ ret = krb_rd_req(&auth, "krbtgt", realm,
+ addr->sin_addr.s_addr, &ad, 0);
+ if(ret){
+ kdc_log(0, "krb_rd_req: %s", krb_get_err_text(ret));
+ make_err_reply(reply, ret, NULL);
+ goto out2;
+ }
+
+ RCHECK(krb5_ret_int32(sp, &req_time), out2);
+ if(lsb)
+ req_time = swap32(req_time);
+ RCHECK(krb5_ret_int8(sp, &life), out2);
+ RCHECK(krb5_ret_stringz(sp, &sname), out2);
+ RCHECK(krb5_ret_stringz(sp, &sinst), out2);
+ kdc_log(0, "TGS-REQ %s.%s@%s from %s for %s.%s",
+ ad.pname, ad.pinst, ad.prealm, from, sname, sinst);
+
+ if(strcmp(ad.prealm, realm)){
+ kdc_log(0, "Can't hop realms %s -> %s", realm, ad.prealm);
+ make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN,
+ "Can't hop realms");
+ goto out2;
+ }
+
+ if(strcmp(sname, "changepw") == 0){
+ kdc_log(0, "Bad request for changepw ticket");
+ make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN,
+ "Can't authorize password change based on TGT");
+ goto out2;
+ }
+
+#if 0
+ client = db_fetch4(ad.pname, ad.pinst, ad.prealm);
+ if(client == NULL){
+ char *s;
+ s = kdc_log_msg(0, "Client not found in database: %s.%s@%s",
+ ad.pname, ad.pinst, ad.prealm);
+ make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, s);
+ free(s);
+ goto out2;
+ }
+#endif
+
+ server = db_fetch4(sname, sinst, v4_realm);
+ if(server == NULL){
+ char *s;
+ s = kdc_log_msg(0, "Server not found in database: %s.%s@%s",
+ sname, sinst, v4_realm);
+ make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, s);
+ free(s);
+ goto out2;
+ }
+
+ ret = get_des_key(server, &skey);
+ if(ret){
+ kdc_log(0, "%s", krb5_get_err_text(context, ret));
+ /* XXX */
+ make_err_reply(reply, KDC_NULL_KEY,
+ "No DES key in database (server)");
+ goto out2;
+ }
+
+ max_life = krb_life_to_time(ad.time_sec, ad.life);
+ max_life = min(max_life, krb_life_to_time(kdc_time, life));
+ life = min(life, krb_time_to_life(kdc_time, max_life));
+ max_life = krb_life_to_time(0, life);
+#if 0
+ if(client->max_life)
+ max_life = min(max_life, *client->max_life);
+#endif
+ if(server->max_life)
+ max_life = min(max_life, *server->max_life);
+
+ {
+ KTEXT_ST cipher, ticket;
+ KTEXT r;
+ des_cblock session;
+ des_new_random_key(&session);
+ krb_create_ticket(&ticket, 0, ad.pname, ad.pinst, ad.prealm,
+ addr->sin_addr.s_addr, &session, life, kdc_time,
+ sname, sinst, skey->key.keyvalue.data);
+
+ create_ciph(&cipher, session, sname, sinst, v4_realm,
+ life, server->kvno, &ticket,
+ kdc_time, &ad.session);
+
+ memset(&session, 0, sizeof(session));
+ memset(ad.session, 0, sizeof(ad.session));
+
+ r = create_auth_reply(ad.pname, ad.pinst, ad.prealm,
+ req_time, 0, 0, 0, &cipher);
+ krb5_data_copy(reply, r->dat, r->length);
+ memset(&cipher, 0, sizeof(cipher));
+ memset(&ticket, 0, sizeof(ticket));
+ }
+ out2:
+ if(tgt_princ)
+ krb5_free_principal(context, tgt_princ);
+ if(tgt){
+ hdb_free_entry(context, tgt);
+ free(tgt);
+ }
+
+ break;
+ }
+
+ case AUTH_MSG_ERR_REPLY:
+ break;
+ default:
+ kdc_log(0, "Unknown message type: %d from %s",
+ msg_type, from);
+
+ make_err_reply(reply, KFAILURE, "Unknown message type");
+ }
+out:
+ if(name)
+ free(name);
+ if(inst)
+ free(inst);
+ if(realm)
+ free(realm);
+ if(sname)
+ free(sname);
+ if(sinst)
+ free(sinst);
+ if(client){
+ hdb_free_entry(context, client);
+ free(client);
+ }
+ if(server){
+ hdb_free_entry(context, server);
+ free(server);
+ }
+ krb5_storage_free(sp);
+ return 0;
+}
+
+
+#define ETYPE_DES_PCBC 17 /* XXX */
+
+krb5_error_code
+encrypt_v4_ticket(void *buf, size_t len, des_cblock *key, EncryptedData *reply)
+{
+ des_key_schedule schedule;
+
+ reply->etype = ETYPE_DES_PCBC;
+ reply->kvno = NULL;
+ reply->cipher.length = len;
+ reply->cipher.data = malloc(len);
+ if(len != 0 && reply->cipher.data == NULL)
+ return ENOMEM;
+ des_set_key(key, schedule);
+ des_pcbc_encrypt(buf,
+ reply->cipher.data,
+ len,
+ schedule,
+ key,
+ DES_ENCRYPT);
+ memset(schedule, 0, sizeof(schedule));
+ return 0;
+}
+
+krb5_error_code
+encode_v4_ticket(void *buf, size_t len, EncTicketPart *et,
+ PrincipalName *service, size_t *size)
+{
+ krb5_storage *sp;
+ krb5_error_code ret;
+ char name[40], inst[40], realm[40];
+ char sname[40], sinst[40];
+
+ {
+ krb5_principal princ;
+ principalname2krb5_principal(&princ,
+ *service,
+ et->crealm);
+ ret = krb5_524_conv_principal(context,
+ princ,
+ sname,
+ sinst,
+ realm);
+ krb5_free_principal(context, princ);
+ if(ret)
+ return ret;
+
+ principalname2krb5_principal(&princ,
+ et->cname,
+ et->crealm);
+
+ ret = krb5_524_conv_principal(context,
+ princ,
+ name,
+ inst,
+ realm);
+ krb5_free_principal(context, princ);
+ }
+ if(ret)
+ return ret;
+
+ sp = krb5_storage_emem();
+
+ krb5_store_int8(sp, 0); /* flags */
+ krb5_store_stringz(sp, name);
+ krb5_store_stringz(sp, inst);
+ krb5_store_stringz(sp, realm);
+ {
+ unsigned char tmp[4] = { 0, 0, 0, 0 };
+ int i;
+ if(et->caddr){
+ for(i = 0; i < et->caddr->len; i++)
+ if(et->caddr->val[i].addr_type == AF_INET &&
+ et->caddr->val[i].address.length == 4){
+ memcpy(tmp, et->caddr->val[i].address.data, 4);
+ break;
+ }
+ }
+ sp->store(sp, tmp, sizeof(tmp));
+ }
+
+ if((et->key.keytype != ETYPE_DES_CBC_MD5 &&
+ et->key.keytype != ETYPE_DES_CBC_MD4 &&
+ et->key.keytype != ETYPE_DES_CBC_CRC) ||
+ et->key.keyvalue.length != 8)
+ return -1;
+ sp->store(sp, et->key.keyvalue.data, 8);
+
+ {
+ time_t start = et->starttime ? *et->starttime : et->authtime;
+ krb5_store_int8(sp, krb_time_to_life(start, et->endtime));
+ krb5_store_int32(sp, start);
+ }
+
+ krb5_store_stringz(sp, sname);
+ krb5_store_stringz(sp, sinst);
+
+ {
+ krb5_data data;
+ krb5_storage_to_data(sp, &data);
+ krb5_storage_free(sp);
+ *size = (data.length + 7) & ~7; /* pad to 8 bytes */
+ if(*size > len)
+ return -1;
+ memset((unsigned char*)buf - *size + 1, 0, *size);
+ memcpy((unsigned char*)buf - *size + 1, data.data, data.length);
+ krb5_data_free(&data);
+ }
+ return 0;
+}
+
+#endif /* KRB4 */
diff --git a/crypto/heimdal/kdc/kerberos4.h b/crypto/heimdal/kdc/kerberos4.h
new file mode 100644
index 000000000000..5bf3c2bc5502
--- /dev/null
+++ b/crypto/heimdal/kdc/kerberos4.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: kerberos4.h,v 1.2 1999/12/02 17:04:59 joda Exp $ */
+
+#ifndef __KERBEROS4_H__
+#define __KERBEROS4_H__
+
+hdb_entry* db_fetch4(const char *name,
+ const char *instance,
+ const char *realm);
+
+#endif /* __KERBEROS4_H__ */
diff --git a/crypto/heimdal/kdc/kerberos5.c b/crypto/heimdal/kdc/kerberos5.c
new file mode 100644
index 000000000000..1108e6df1d99
--- /dev/null
+++ b/crypto/heimdal/kdc/kerberos5.c
@@ -0,0 +1,1639 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kdc_locl.h"
+
+RCSID("$Id: kerberos5.c,v 1.108 1999/12/02 17:04:59 joda Exp $");
+
+#define MAX_TIME ((time_t)((1U << 31) - 1))
+
+static void
+fix_time(time_t **t)
+{
+ if(*t == NULL){
+ ALLOC(*t);
+ **t = MAX_TIME;
+ }
+ if(**t == 0) **t = MAX_TIME; /* fix for old clients */
+}
+
+static void
+set_salt_padata (METHOD_DATA **m, Salt *salt)
+{
+ if (salt) {
+ ALLOC(*m);
+ (*m)->len = 1;
+ ALLOC((*m)->val);
+ (*m)->val->padata_type = salt->type;
+ copy_octet_string(&salt->salt,
+ &(*m)->val->padata_value);
+ }
+}
+
+static PA_DATA*
+find_padata(KDC_REQ *req, int *start, int type)
+{
+ while(*start < req->padata->len){
+ (*start)++;
+ if(req->padata->val[*start - 1].padata_type == type)
+ return &req->padata->val[*start - 1];
+ }
+ return NULL;
+}
+
+#if 0
+
+static krb5_error_code
+find_keys(hdb_entry *client,
+ hdb_entry *server,
+ Key **ckey,
+ krb5_enctype *cetype,
+ Key **skey,
+ krb5_enctype *setype,
+ unsigned *etypes,
+ unsigned num_etypes)
+{
+ int i;
+ krb5_error_code ret;
+ for(i = 0; i < num_etypes; i++) {
+ if(client){
+ ret = hdb_enctype2key(context, client, etypes[i], ckey);
+ if(ret)
+ continue;
+ }
+ if(server){
+ ret = hdb_enctype2key(context, server, etypes[i], skey);
+ if(ret)
+ continue;
+ }
+ if(etype)
+ *cetype = *setype = etypes[i];
+ return 0;
+ }
+ return KRB5KDC_ERR_ETYPE_NOSUPP;
+}
+
+#else
+
+static krb5_error_code
+find_etype(hdb_entry *princ, unsigned *etypes, unsigned len,
+ Key **key, int *index)
+{
+ int i;
+ krb5_error_code ret = KRB5KDC_ERR_ETYPE_NOSUPP;
+
+ for(i = 0; i < len ; i++) {
+ krb5_error_code tmp;
+
+ tmp = hdb_enctype2key(context, princ, etypes[i], key);
+ if (tmp == 0) {
+ if ((*key)->key.keyvalue.length != 0) {
+ ret = 0;
+ break;
+ } else {
+ ret = KRB5KDC_ERR_NULL_KEY;
+ }
+ }
+ }
+ if(index)
+ *index = i;
+ return ret;
+}
+
+static krb5_error_code
+find_keys(hdb_entry *client,
+ hdb_entry *server,
+ Key **ckey,
+ krb5_enctype *cetype,
+ Key **skey,
+ krb5_enctype *setype,
+ int *etypes,
+ unsigned num_etypes)
+{
+ int i;
+ krb5_error_code ret;
+ if(client){
+ /* find client key */
+ ret = find_etype(client, etypes, num_etypes, ckey, &i);
+ if (ret) {
+ kdc_log(0, "Client has no support for etypes");
+ return ret;
+ }
+ *cetype = etypes[i];
+ }
+
+ if(server){
+ /* find server key */
+ ret = find_etype(server, etypes, num_etypes, skey, NULL);
+ if (ret) {
+ kdc_log(0, "Server has no support for etypes");
+ return ret;
+ }
+ *setype = (*skey)->key.keytype;
+ }
+ return 0;
+}
+#endif
+
+static krb5_error_code
+encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
+ krb5_enctype etype,
+ int skvno, EncryptionKey *skey,
+ int ckvno, EncryptionKey *ckey,
+ krb5_data *reply)
+{
+ unsigned char buf[8192]; /* XXX The data could be indefinite */
+ size_t len;
+ krb5_error_code ret;
+ krb5_crypto crypto;
+
+ ret = encode_EncTicketPart(buf + sizeof(buf) - 1, sizeof(buf), et, &len);
+ if(ret) {
+ kdc_log(0, "Failed to encode ticket: %s",
+ krb5_get_err_text(context, ret));
+ return ret;
+ }
+
+
+ krb5_crypto_init(context, skey, etype, &crypto);
+
+ krb5_encrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_TICKET,
+ buf + sizeof(buf) - len,
+ len,
+ skvno,
+ &rep->ticket.enc_part);
+
+ krb5_crypto_destroy(context, crypto);
+
+ if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep)
+ ret = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf),
+ ek, &len);
+ else
+ ret = encode_EncTGSRepPart(buf + sizeof(buf) - 1, sizeof(buf),
+ ek, &len);
+ if(ret) {
+ kdc_log(0, "Failed to encode KDC-REP: %s",
+ krb5_get_err_text(context, ret));
+ return ret;
+ }
+ krb5_crypto_init(context, ckey, 0, &crypto);
+ if(rep->msg_type == krb_as_rep) {
+ krb5_encrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_AS_REP_ENC_PART,
+ buf + sizeof(buf) - len,
+ len,
+ ckvno,
+ &rep->enc_part);
+ ret = encode_AS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len);
+ } else {
+ krb5_encrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_TGS_REP_ENC_PART_SESSION,
+ buf + sizeof(buf) - len,
+ len,
+ ckvno,
+ &rep->enc_part);
+ ret = encode_TGS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len);
+ }
+ krb5_crypto_destroy(context, crypto);
+ if(ret) {
+ kdc_log(0, "Failed to encode KDC-REP: %s",
+ krb5_get_err_text(context, ret));
+ return ret;
+ }
+ krb5_data_copy(reply, buf + sizeof(buf) - len, len);
+ return 0;
+}
+
+static int
+realloc_method_data(METHOD_DATA *md)
+{
+ PA_DATA *pa;
+ pa = realloc(md->val, (md->len + 1) * sizeof(*md->val));
+ if(pa == NULL)
+ return ENOMEM;
+ md->val = pa;
+ md->len++;
+ return 0;
+}
+
+static krb5_error_code
+get_pa_etype_info(METHOD_DATA *md, hdb_entry *client)
+{
+ krb5_error_code ret = 0;
+ int i;
+ ETYPE_INFO pa;
+ unsigned char *buf;
+ size_t len;
+
+
+ pa.len = client->keys.len;
+ pa.val = malloc(pa.len * sizeof(*pa.val));
+ if(pa.val == NULL)
+ return ENOMEM;
+ for(i = 0; i < client->keys.len; i++) {
+ pa.val[i].etype = client->keys.val[i].key.keytype;
+ ALLOC(pa.val[i].salttype);
+ if(client->keys.val[i].salt){
+#if 0
+ if(client->keys.val[i].salt->type == hdb_pw_salt)
+ *pa.val[i].salttype = 0; /* or 1? or NULL? */
+ else if(client->keys.val[i].salt->type == hdb_afs3_salt)
+ *pa.val[i].salttype = 2;
+ else {
+ free_ETYPE_INFO(&pa);
+ kdc_log(0, "unknown salt-type: %d",
+ client->keys.val[i].salt->type);
+ return KRB5KRB_ERR_GENERIC;
+ }
+ /* according to `the specs', we can't send a salt if
+ we have AFS3 salted key, but that requires that you
+ *know* what cell you are using (e.g by assuming
+ that the cell is the same as the realm in lower
+ case) */
+#else
+ *pa.val[i].salttype = client->keys.val[i].salt->type;
+#endif
+ krb5_copy_data(context, &client->keys.val[i].salt->salt,
+ &pa.val[i].salt);
+ } else {
+#if 0
+ *pa.val[i].salttype = 1; /* or 0 with salt? */
+#else
+ *pa.val[i].salttype = pa_pw_salt;
+#endif
+ pa.val[i].salt = NULL;
+ }
+ }
+ len = length_ETYPE_INFO(&pa);
+ buf = malloc(len);
+ if (buf) {
+ free_ETYPE_INFO(&pa);
+ return ret;
+ }
+ ret = encode_ETYPE_INFO(buf + len - 1, len, &pa, &len);
+ free_ETYPE_INFO(&pa);
+ if(ret) {
+ free(buf);
+ return ret;
+ }
+ ret = realloc_method_data(md);
+ if(ret) {
+ free(buf);
+ return ret;
+ }
+ md->val[md->len - 1].padata_type = pa_etype_info;
+ md->val[md->len - 1].padata_value.length = len;
+ md->val[md->len - 1].padata_value.data = buf;
+ return 0;
+}
+
+static int
+check_flags(hdb_entry *client, const char *client_name,
+ hdb_entry *server, const char *server_name,
+ krb5_boolean is_as_req)
+{
+ if(client != NULL) {
+ /* check client */
+ if (client->flags.invalid) {
+ kdc_log(0, "Client (%s) has invalid bit set", client_name);
+ return KRB5KDC_ERR_POLICY;
+ }
+
+ if(!client->flags.client){
+ kdc_log(0, "Principal may not act as client -- %s",
+ client_name);
+ return KRB5KDC_ERR_POLICY;
+ }
+
+ if (client->valid_start && *client->valid_start > kdc_time) {
+ kdc_log(0, "Client not yet valid -- %s", client_name);
+ return KRB5KDC_ERR_CLIENT_NOTYET;
+ }
+
+ if (client->valid_end && *client->valid_end < kdc_time) {
+ kdc_log(0, "Client expired -- %s", client_name);
+ return KRB5KDC_ERR_NAME_EXP;
+ }
+
+ if (client->pw_end && *client->pw_end < kdc_time
+ && !server->flags.change_pw) {
+ kdc_log(0, "Client's key has expired -- %s", client_name);
+ return KRB5KDC_ERR_KEY_EXPIRED;
+ }
+ }
+
+ /* check server */
+
+ if (server != NULL) {
+ if (server->flags.invalid) {
+ kdc_log(0, "Server has invalid flag set -- %s", server_name);
+ return KRB5KDC_ERR_POLICY;
+ }
+
+ if(!server->flags.server){
+ kdc_log(0, "Principal may not act as server -- %s",
+ server_name);
+ return KRB5KDC_ERR_POLICY;
+ }
+
+ if(!is_as_req && server->flags.initial) {
+ kdc_log(0, "AS-REQ is required for server -- %s", server_name);
+ return KRB5KDC_ERR_POLICY;
+ }
+
+ if (server->valid_start && *server->valid_start > kdc_time) {
+ kdc_log(0, "Server not yet valid -- %s", server_name);
+ return KRB5KDC_ERR_SERVICE_NOTYET;
+ }
+
+ if (server->valid_end && *server->valid_end < kdc_time) {
+ kdc_log(0, "Server expired -- %s", server_name);
+ return KRB5KDC_ERR_SERVICE_EXP;
+ }
+
+ if (server->pw_end && *server->pw_end < kdc_time) {
+ kdc_log(0, "Server's key has expired -- %s", server_name);
+ return KRB5KDC_ERR_KEY_EXPIRED;
+ }
+ }
+ return 0;
+}
+
+static krb5_boolean
+check_addresses(HostAddresses *addresses, struct sockaddr *from)
+{
+ krb5_error_code ret;
+ krb5_address addr;
+
+ if(check_ticket_addresses == 0)
+ return TRUE;
+
+ if(addresses == NULL)
+ return allow_null_ticket_addresses;
+
+ ret = krb5_sockaddr2address (from, &addr);
+ if(ret)
+ return FALSE;
+
+ return krb5_address_search(context, &addr, addresses);
+}
+
+krb5_error_code
+as_rep(KDC_REQ *req,
+ krb5_data *reply,
+ const char *from,
+ struct sockaddr *from_addr)
+{
+ KDC_REQ_BODY *b = &req->req_body;
+ AS_REP rep;
+ KDCOptions f = b->kdc_options;
+ hdb_entry *client = NULL, *server = NULL;
+ krb5_enctype cetype, setype;
+ EncTicketPart et;
+ EncKDCRepPart ek;
+ krb5_principal client_princ, server_princ;
+ char *client_name, *server_name;
+ krb5_error_code ret = 0;
+ const char *e_text = NULL;
+ krb5_crypto crypto;
+
+ Key *ckey, *skey;
+
+ if(b->sname == NULL){
+ server_name = "<unknown server>";
+ ret = KRB5KRB_ERR_GENERIC;
+ e_text = "No server in request";
+ } else{
+ principalname2krb5_principal (&server_princ, *(b->sname), b->realm);
+ krb5_unparse_name(context, server_princ, &server_name);
+ }
+
+ if(b->cname == NULL){
+ client_name = "<unknown client>";
+ ret = KRB5KRB_ERR_GENERIC;
+ e_text = "No client in request";
+ } else {
+ principalname2krb5_principal (&client_princ, *(b->cname), b->realm);
+ krb5_unparse_name(context, client_princ, &client_name);
+ }
+ kdc_log(0, "AS-REQ %s from %s for %s",
+ client_name, from, server_name);
+
+ if(ret)
+ goto out;
+
+ client = db_fetch(client_princ);
+ if(client == NULL){
+ kdc_log(0, "UNKNOWN -- %s", client_name);
+ ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+ goto out;
+ }
+
+ server = db_fetch(server_princ);
+
+ if(server == NULL){
+ kdc_log(0, "UNKNOWN -- %s", server_name);
+ ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
+ goto out;
+ }
+
+ ret = check_flags(client, client_name, server, server_name, TRUE);
+ if(ret)
+ goto out;
+
+ memset(&et, 0, sizeof(et));
+ memset(&ek, 0, sizeof(ek));
+
+ if(req->padata){
+ int i = 0;
+ PA_DATA *pa;
+ int found_pa = 0;
+ kdc_log(5, "Looking for pa-data -- %s", client_name);
+ while((pa = find_padata(req, &i, pa_enc_timestamp))){
+ krb5_data ts_data;
+ PA_ENC_TS_ENC p;
+ time_t patime;
+ size_t len;
+ EncryptedData enc_data;
+ Key *pa_key;
+
+ found_pa = 1;
+
+ ret = decode_EncryptedData(pa->padata_value.data,
+ pa->padata_value.length,
+ &enc_data,
+ &len);
+ if (ret) {
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ kdc_log(5, "Failed to decode PA-DATA -- %s",
+ client_name);
+ goto out;
+ }
+
+ ret = hdb_enctype2key(context, client, enc_data.etype, &pa_key);
+ if(ret){
+ char *estr;
+ e_text = "No key matches pa-data";
+ ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ if(krb5_enctype_to_string(context, enc_data.etype, &estr))
+ estr = NULL;
+ if(estr == NULL)
+ kdc_log(5, "No client key matching pa-data (%d) -- %s",
+ enc_data.etype, client_name);
+ else
+ kdc_log(5, "No client key matching pa-data (%s) -- %s",
+ estr, client_name);
+ free(estr);
+
+ free_EncryptedData(&enc_data);
+ continue;
+ }
+
+ krb5_crypto_init(context, &pa_key->key, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_PA_ENC_TIMESTAMP,
+ &enc_data,
+ &ts_data);
+ krb5_crypto_destroy(context, crypto);
+ free_EncryptedData(&enc_data);
+ if(ret){
+ e_text = "Failed to decrypt PA-DATA";
+ kdc_log (5, "Failed to decrypt PA-DATA -- %s",
+ client_name);
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ continue;
+ }
+ ret = decode_PA_ENC_TS_ENC(ts_data.data,
+ ts_data.length,
+ &p,
+ &len);
+ krb5_data_free(&ts_data);
+ if(ret){
+ e_text = "Failed to decode PA-ENC-TS-ENC";
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ kdc_log (5, "Failed to decode PA-ENC-TS_ENC -- %s",
+ client_name);
+ continue;
+ }
+ patime = p.patimestamp;
+ free_PA_ENC_TS_ENC(&p);
+ if (abs(kdc_time - p.patimestamp) > context->max_skew) {
+ ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ e_text = "Too large time skew";
+ kdc_log(0, "Too large time skew -- %s", client_name);
+ goto out;
+ }
+ et.flags.pre_authent = 1;
+ kdc_log(2, "Pre-authentication succeded -- %s", client_name);
+ break;
+ }
+ if(found_pa == 0 && require_preauth)
+ goto use_pa;
+ /* We come here if we found a pa-enc-timestamp, but if there
+ was some problem with it, other than too large skew */
+ if(found_pa && et.flags.pre_authent == 0){
+ kdc_log(0, "%s -- %s", e_text, client_name);
+ e_text = NULL;
+ goto out;
+ }
+ }else if (require_preauth || client->flags.require_preauth || server->flags.require_preauth) {
+ METHOD_DATA method_data;
+ PA_DATA *pa;
+ unsigned char *buf;
+ size_t len;
+ krb5_data foo_data;
+
+ use_pa:
+ method_data.len = 0;
+ method_data.val = NULL;
+
+ ret = realloc_method_data(&method_data);
+ pa = &method_data.val[method_data.len-1];
+ pa->padata_type = pa_enc_timestamp;
+ pa->padata_value.length = 0;
+ pa->padata_value.data = NULL;
+
+ ret = get_pa_etype_info(&method_data, client); /* XXX check ret */
+
+ len = length_METHOD_DATA(&method_data);
+ buf = malloc(len);
+ encode_METHOD_DATA(buf + len - 1,
+ len,
+ &method_data,
+ &len);
+ free_METHOD_DATA(&method_data);
+ foo_data.length = len;
+ foo_data.data = buf;
+
+ ret = KRB5KDC_ERR_PREAUTH_REQUIRED;
+ krb5_mk_error(context,
+ ret,
+ "Need to use PA-ENC-TIMESTAMP",
+ &foo_data,
+ client_princ,
+ server_princ,
+ 0,
+ reply);
+ free(buf);
+ kdc_log(0, "No PA-ENC-TIMESTAMP -- %s", client_name);
+ ret = 0;
+ goto out2;
+ }
+
+ ret = find_keys(client, server, &ckey, &cetype, &skey, &setype,
+ b->etype.val, b->etype.len);
+ if(ret) {
+ kdc_log(0, "Server/client has no support for etypes");
+ goto out;
+ }
+
+ {
+ char *cet;
+ char *set;
+ krb5_enctype_to_string(context, cetype, &cet);
+ krb5_enctype_to_string(context, setype, &set);
+ kdc_log(5, "Using %s/%s", cet, set);
+ free(cet);
+ free(set);
+ }
+
+
+ memset(&rep, 0, sizeof(rep));
+ rep.pvno = 5;
+ rep.msg_type = krb_as_rep;
+ copy_Realm(&b->realm, &rep.crealm);
+ copy_PrincipalName(b->cname, &rep.cname);
+ rep.ticket.tkt_vno = 5;
+ copy_Realm(&b->realm, &rep.ticket.realm);
+ copy_PrincipalName(b->sname, &rep.ticket.sname);
+
+ {
+ char str[128];
+ unparse_flags(KDCOptions2int(f), KDCOptions_units, str, sizeof(str));
+ if(*str)
+ kdc_log(2, "Requested flags: %s", str);
+ }
+
+ if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey ||
+ f.request_anonymous){
+ ret = KRB5KDC_ERR_BADOPTION;
+ kdc_log(0, "Bad KDC options -- %s", client_name);
+ goto out;
+ }
+
+ et.flags.initial = 1;
+ if(client->flags.forwardable && server->flags.forwardable)
+ et.flags.forwardable = f.forwardable;
+ else if (f.forwardable) {
+ ret = KRB5KDC_ERR_POLICY;
+ kdc_log(0, "Ticket may not be forwardable -- %s", client_name);
+ goto out;
+ }
+ if(client->flags.proxiable && server->flags.proxiable)
+ et.flags.proxiable = f.proxiable;
+ else if (f.proxiable) {
+ ret = KRB5KDC_ERR_POLICY;
+ kdc_log(0, "Ticket may not be proxiable -- %s", client_name);
+ goto out;
+ }
+ if(client->flags.postdate && server->flags.postdate)
+ et.flags.may_postdate = f.allow_postdate;
+ else if (f.allow_postdate){
+ ret = KRB5KDC_ERR_POLICY;
+ kdc_log(0, "Ticket may not be postdatable -- %s", client_name);
+ goto out;
+ }
+
+ /* check for valid set of addresses */
+ if(!check_addresses(b->addresses, from_addr)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ kdc_log(0, "Bad address list requested -- %s", client_name);
+ goto out;
+ }
+
+ krb5_generate_random_keyblock(context, setype, &et.key);
+ copy_PrincipalName(b->cname, &et.cname);
+ copy_Realm(&b->realm, &et.crealm);
+
+ {
+ time_t start;
+ time_t t;
+
+ start = et.authtime = kdc_time;
+
+ if(f.postdated && req->req_body.from){
+ ALLOC(et.starttime);
+ start = *et.starttime = *req->req_body.from;
+ et.flags.invalid = 1;
+ et.flags.postdated = 1; /* XXX ??? */
+ }
+ fix_time(&b->till);
+ t = *b->till;
+ if(client->max_life)
+ t = min(t, start + *client->max_life);
+ if(server->max_life)
+ t = min(t, start + *server->max_life);
+#if 0
+ t = min(t, start + realm->max_life);
+#endif
+ et.endtime = t;
+ if(f.renewable_ok && et.endtime < *b->till){
+ f.renewable = 1;
+ if(b->rtime == NULL){
+ ALLOC(b->rtime);
+ *b->rtime = 0;
+ }
+ if(*b->rtime < *b->till)
+ *b->rtime = *b->till;
+ }
+ if(f.renewable && b->rtime){
+ t = *b->rtime;
+ if(t == 0)
+ t = MAX_TIME;
+ if(client->max_renew)
+ t = min(t, start + *client->max_renew);
+ if(server->max_renew)
+ t = min(t, start + *server->max_renew);
+#if 0
+ t = min(t, start + realm->max_renew);
+#endif
+ ALLOC(et.renew_till);
+ *et.renew_till = t;
+ et.flags.renewable = 1;
+ }
+ }
+
+ if(b->addresses){
+ ALLOC(et.caddr);
+ copy_HostAddresses(b->addresses, et.caddr);
+ }
+
+ {
+ krb5_data empty_string;
+
+ krb5_data_zero(&empty_string);
+ et.transited.tr_type = DOMAIN_X500_COMPRESS;
+ et.transited.contents = empty_string;
+ }
+
+ copy_EncryptionKey(&et.key, &ek.key);
+
+ /* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
+ * as 0 and as 0x80 (meaning indefinite length) apart, and is thus
+ * incapable of correctly decoding SEQUENCE OF's of zero length.
+ *
+ * To fix this, always send at least one no-op last_req
+ *
+ * If there's a pw_end or valid_end we will use that,
+ * otherwise just a dummy lr.
+ */
+ ek.last_req.val = malloc(2 * sizeof(*ek.last_req.val));
+ ek.last_req.len = 0;
+ if (client->pw_end
+ && (kdc_warn_pwexpire == 0
+ || kdc_time + kdc_warn_pwexpire <= *client->pw_end)) {
+ ek.last_req.val[ek.last_req.len].lr_type = 6;
+ ek.last_req.val[ek.last_req.len].lr_value = *client->pw_end;
+ ++ek.last_req.len;
+ }
+ if (client->valid_end) {
+ ek.last_req.val[ek.last_req.len].lr_type = 7;
+ ek.last_req.val[ek.last_req.len].lr_value = *client->valid_end;
+ ++ek.last_req.len;
+ }
+ if (ek.last_req.len == 0) {
+ ek.last_req.val[ek.last_req.len].lr_type = 0;
+ ek.last_req.val[ek.last_req.len].lr_value = 0;
+ ++ek.last_req.len;
+ }
+ ek.nonce = b->nonce;
+ if (client->valid_end || client->pw_end) {
+ ALLOC(ek.key_expiration);
+ if (client->valid_end) {
+ if (client->pw_end)
+ *ek.key_expiration = min(*client->valid_end, *client->pw_end);
+ else
+ *ek.key_expiration = *client->valid_end;
+ } else
+ *ek.key_expiration = *client->pw_end;
+ } else
+ ek.key_expiration = NULL;
+ ek.flags = et.flags;
+ ek.authtime = et.authtime;
+ if (et.starttime) {
+ ALLOC(ek.starttime);
+ *ek.starttime = *et.starttime;
+ }
+ ek.endtime = et.endtime;
+ if (et.renew_till) {
+ ALLOC(ek.renew_till);
+ *ek.renew_till = *et.renew_till;
+ }
+ copy_Realm(&rep.ticket.realm, &ek.srealm);
+ copy_PrincipalName(&rep.ticket.sname, &ek.sname);
+ if(et.caddr){
+ ALLOC(ek.caddr);
+ copy_HostAddresses(et.caddr, ek.caddr);
+ }
+
+ set_salt_padata (&rep.padata, ckey->salt);
+ ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key,
+ client->kvno, &ckey->key, reply);
+ free_EncTicketPart(&et);
+ free_EncKDCRepPart(&ek);
+ free_AS_REP(&rep);
+out:
+ if(ret){
+ krb5_mk_error(context,
+ ret,
+ e_text,
+ NULL,
+ client_princ,
+ server_princ,
+ 0,
+ reply);
+ ret = 0;
+ }
+out2:
+ krb5_free_principal(context, client_princ);
+ free(client_name);
+ krb5_free_principal(context, server_princ);
+ free(server_name);
+ if(client){
+ hdb_free_entry(context, client);
+ free(client);
+ }
+ if(server){
+ hdb_free_entry(context, server);
+ free(server);
+ }
+
+ return ret;
+}
+
+
+static krb5_error_code
+check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et)
+{
+ KDCOptions f = b->kdc_options;
+
+ if(f.validate){
+ if(!tgt->flags.invalid || tgt->starttime == NULL){
+ kdc_log(0, "Bad request to validate ticket");
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ if(*tgt->starttime > kdc_time){
+ kdc_log(0, "Early request to validate ticket");
+ return KRB5KRB_AP_ERR_TKT_NYV;
+ }
+ /* XXX tkt = tgt */
+ et->flags.invalid = 0;
+ }else if(tgt->flags.invalid){
+ kdc_log(0, "Ticket-granting ticket has INVALID flag set");
+ return KRB5KRB_AP_ERR_TKT_INVALID;
+ }
+
+ if(f.forwardable){
+ if(!tgt->flags.forwardable){
+ kdc_log(0, "Bad request for forwardable ticket");
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ et->flags.forwardable = 1;
+ }
+ if(f.forwarded){
+ if(!tgt->flags.forwardable){
+ kdc_log(0, "Request to forward non-forwardable ticket");
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ et->flags.forwarded = 1;
+ et->caddr = b->addresses;
+ }
+ if(tgt->flags.forwarded)
+ et->flags.forwarded = 1;
+
+ if(f.proxiable){
+ if(!tgt->flags.proxiable){
+ kdc_log(0, "Bad request for proxiable ticket");
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ et->flags.proxiable = 1;
+ }
+ if(f.proxy){
+ if(!tgt->flags.proxiable){
+ kdc_log(0, "Request to proxy non-proxiable ticket");
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ et->flags.proxy = 1;
+ et->caddr = b->addresses;
+ }
+ if(tgt->flags.proxy)
+ et->flags.proxy = 1;
+
+ if(f.allow_postdate){
+ if(!tgt->flags.may_postdate){
+ kdc_log(0, "Bad request for post-datable ticket");
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ et->flags.may_postdate = 1;
+ }
+ if(f.postdated){
+ if(!tgt->flags.may_postdate){
+ kdc_log(0, "Bad request for postdated ticket");
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ if(b->from)
+ *et->starttime = *b->from;
+ et->flags.postdated = 1;
+ et->flags.invalid = 1;
+ }else if(b->from && *b->from > kdc_time + context->max_skew){
+ kdc_log(0, "Ticket cannot be postdated");
+ return KRB5KDC_ERR_CANNOT_POSTDATE;
+ }
+
+ if(f.renewable){
+ if(!tgt->flags.renewable){
+ kdc_log(0, "Bad request for renewable ticket");
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ et->flags.renewable = 1;
+ ALLOC(et->renew_till);
+ fix_time(&b->rtime);
+ *et->renew_till = *b->rtime;
+ }
+ if(f.renew){
+ time_t old_life;
+ if(!tgt->flags.renewable || tgt->renew_till == NULL){
+ kdc_log(0, "Request to renew non-renewable ticket");
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ old_life = tgt->endtime;
+ if(tgt->starttime)
+ old_life -= *tgt->starttime;
+ else
+ old_life -= tgt->authtime;
+ et->endtime = min(*b->till, *et->starttime + old_life);
+ }
+
+ /* checks for excess flags */
+ if(f.request_anonymous){
+ kdc_log(0, "Request for anonymous ticket");
+ return KRB5KDC_ERR_BADOPTION;
+ }
+ return 0;
+}
+
+static krb5_error_code
+fix_transited_encoding(TransitedEncoding *tr,
+ const char *client_realm,
+ const char *server_realm,
+ const char *tgt_realm)
+{
+ krb5_error_code ret = 0;
+ if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)){
+ char **realms = NULL, **tmp;
+ int num_realms = 0;
+ int i;
+ if(tr->tr_type && tr->contents.length != 0) {
+ if(tr->tr_type != DOMAIN_X500_COMPRESS){
+ kdc_log(0, "Unknown transited type: %u",
+ tr->tr_type);
+ return KRB5KDC_ERR_TRTYPE_NOSUPP;
+ }
+ ret = krb5_domain_x500_decode(tr->contents,
+ &realms,
+ &num_realms,
+ client_realm,
+ server_realm);
+ if(ret){
+ krb5_warn(context, ret, "Decoding transited encoding");
+ return ret;
+ }
+ }
+ tmp = realloc(realms, (num_realms + 1) * sizeof(*realms));
+ if(tmp == NULL){
+ ret = ENOMEM;
+ goto free_realms;
+ }
+ realms = tmp;
+ realms[num_realms] = strdup(tgt_realm);
+ if(realms[num_realms] == NULL){
+ ret = ENOMEM;
+ goto free_realms;
+ }
+ num_realms++;
+ free_TransitedEncoding(tr);
+ tr->tr_type = DOMAIN_X500_COMPRESS;
+ ret = krb5_domain_x500_encode(realms, num_realms, &tr->contents);
+ if(ret)
+ krb5_warn(context, ret, "Encoding transited encoding");
+ free_realms:
+ for(i = 0; i < num_realms; i++)
+ free(realms[i]);
+ free(realms);
+ }
+ return ret;
+}
+
+
+static krb5_error_code
+tgs_make_reply(KDC_REQ_BODY *b,
+ EncTicketPart *tgt,
+ EncTicketPart *adtkt,
+ AuthorizationData *auth_data,
+ hdb_entry *server,
+ hdb_entry *client,
+ krb5_principal client_principal,
+ hdb_entry *krbtgt,
+ krb5_enctype cetype,
+ krb5_data *reply)
+{
+ KDC_REP rep;
+ EncKDCRepPart ek;
+ EncTicketPart et;
+ KDCOptions f = b->kdc_options;
+ krb5_error_code ret;
+ krb5_enctype etype;
+ Key *skey;
+ EncryptionKey *ekey;
+
+ if(adtkt) {
+ int i;
+ krb5_keytype kt;
+ ekey = &adtkt->key;
+ for(i = 0; i < b->etype.len; i++){
+ ret = krb5_enctype_to_keytype(context, b->etype.val[i], &kt);
+ if(ret)
+ continue;
+ if(adtkt->key.keytype == kt)
+ break;
+ }
+ if(i == b->etype.len)
+ return KRB5KDC_ERR_ETYPE_NOSUPP;
+ etype = b->etype.val[i];
+ }else{
+ ret = find_keys(NULL, server, NULL, NULL, &skey, &etype,
+ b->etype.val, b->etype.len);
+ if(ret) {
+ kdc_log(0, "Server has no support for etypes");
+ return ret;
+ }
+ ekey = &skey->key;
+ }
+
+ memset(&rep, 0, sizeof(rep));
+ memset(&et, 0, sizeof(et));
+ memset(&ek, 0, sizeof(ek));
+
+ rep.pvno = 5;
+ rep.msg_type = krb_tgs_rep;
+
+ et.authtime = tgt->authtime;
+ fix_time(&b->till);
+ et.endtime = min(tgt->endtime, *b->till);
+ ALLOC(et.starttime);
+ *et.starttime = kdc_time;
+
+ ret = check_tgs_flags(b, tgt, &et);
+ if(ret)
+ return ret;
+
+ copy_TransitedEncoding(&tgt->transited, &et.transited);
+ ret = fix_transited_encoding(&et.transited,
+ *krb5_princ_realm(context, client_principal),
+ *krb5_princ_realm(context, server->principal),
+ *krb5_princ_realm(context, krbtgt->principal));
+ if(ret){
+ free_TransitedEncoding(&et.transited);
+ return ret;
+ }
+
+
+ copy_Realm(krb5_princ_realm(context, server->principal),
+ &rep.ticket.realm);
+ krb5_principal2principalname(&rep.ticket.sname, server->principal);
+ copy_Realm(&tgt->crealm, &rep.crealm);
+ copy_PrincipalName(&tgt->cname, &rep.cname);
+ rep.ticket.tkt_vno = 5;
+
+ ek.caddr = et.caddr;
+ if(et.caddr == NULL)
+ et.caddr = tgt->caddr;
+
+ {
+ time_t life;
+ life = et.endtime - *et.starttime;
+ if(client && client->max_life)
+ life = min(life, *client->max_life);
+ if(server->max_life)
+ life = min(life, *server->max_life);
+ et.endtime = *et.starttime + life;
+ }
+ if(f.renewable_ok && tgt->flags.renewable &&
+ et.renew_till == NULL && et.endtime < *b->till){
+ et.flags.renewable = 1;
+ ALLOC(et.renew_till);
+ *et.renew_till = *b->till;
+ }
+ if(et.renew_till){
+ time_t renew;
+ renew = *et.renew_till - et.authtime;
+ if(client && client->max_renew)
+ renew = min(renew, *client->max_renew);
+ if(server->max_renew)
+ renew = min(renew, *server->max_renew);
+ *et.renew_till = et.authtime + renew;
+ }
+
+ if(et.renew_till){
+ *et.renew_till = min(*et.renew_till, *tgt->renew_till);
+ *et.starttime = min(*et.starttime, *et.renew_till);
+ et.endtime = min(et.endtime, *et.renew_till);
+ }
+
+ *et.starttime = min(*et.starttime, et.endtime);
+
+ if(*et.starttime == et.endtime){
+ ret = KRB5KDC_ERR_NEVER_VALID;
+ goto out;
+ }
+ if(et.renew_till && et.endtime == *et.renew_till){
+ free(et.renew_till);
+ et.renew_till = NULL;
+ et.flags.renewable = 0;
+ }
+
+ et.flags.pre_authent = tgt->flags.pre_authent;
+ et.flags.hw_authent = tgt->flags.hw_authent;
+
+ /* XXX Check enc-authorization-data */
+ et.authorization_data = auth_data;
+
+ krb5_generate_random_keyblock(context, etype, &et.key);
+ et.crealm = tgt->crealm;
+ et.cname = tgt->cname;
+
+ ek.key = et.key;
+ /* MIT must have at least one last_req */
+ ek.last_req.len = 1;
+ ek.last_req.val = calloc(1, sizeof(*ek.last_req.val));
+ ek.nonce = b->nonce;
+ ek.flags = et.flags;
+ ek.authtime = et.authtime;
+ ek.starttime = et.starttime;
+ ek.endtime = et.endtime;
+ ek.renew_till = et.renew_till;
+ ek.srealm = rep.ticket.realm;
+ ek.sname = rep.ticket.sname;
+
+ /* It is somewhat unclear where the etype in the following
+ encryption should come from. What we have is a session
+ key in the passed tgt, and a list of preferred etypes
+ *for the new ticket*. Should we pick the best possible
+ etype, given the keytype in the tgt, or should we look
+ at the etype list here as well? What if the tgt
+ session key is DES3 and we want a ticket with a (say)
+ CAST session key. Should the DES3 etype be added to the
+ etype list, even if we don't want a session key with
+ DES3? */
+ ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey,
+ 0, &tgt->key, reply);
+out:
+ free_TGS_REP(&rep);
+ free_TransitedEncoding(&et.transited);
+ if(et.starttime)
+ free(et.starttime);
+ if(et.renew_till)
+ free(et.renew_till);
+ free_LastReq(&ek.last_req);
+ memset(et.key.keyvalue.data, 0, et.key.keyvalue.length);
+ free_EncryptionKey(&et.key);
+ return ret;
+}
+
+static krb5_error_code
+tgs_check_authenticator(krb5_auth_context ac,
+ KDC_REQ_BODY *b,
+ krb5_keyblock *key)
+{
+ krb5_authenticator auth;
+ size_t len;
+ unsigned char buf[8192];
+ krb5_error_code ret;
+ krb5_crypto crypto;
+
+ krb5_auth_getauthenticator(context, ac, &auth);
+ if(auth->cksum == NULL){
+ kdc_log(0, "No authenticator in request");
+ ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
+ goto out;
+ }
+ /*
+ * according to RFC1510 it doesn't need to be keyed,
+ * but according to the latest draft it needs to.
+ */
+ if (
+#if 0
+!krb5_checksum_is_keyed(context, auth->cksum->cksumtype)
+ ||
+#endif
+ !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
+ kdc_log(0, "Bad checksum type in authenticator: %d",
+ auth->cksum->cksumtype);
+ ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
+ goto out;
+ }
+
+ /* XXX should not re-encode this */
+ ret = encode_KDC_REQ_BODY(buf + sizeof(buf) - 1, sizeof(buf),
+ b, &len);
+ if(ret){
+ kdc_log(0, "Failed to encode KDC-REQ-BODY: %s",
+ krb5_get_err_text(context, ret));
+ goto out;
+ }
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_verify_checksum(context,
+ crypto,
+ KRB5_KU_TGS_REQ_AUTH_CKSUM,
+ buf + sizeof(buf) - len,
+ len,
+ auth->cksum);
+ krb5_crypto_destroy(context, crypto);
+ if(ret){
+ kdc_log(0, "Failed to verify checksum: %s",
+ krb5_get_err_text(context, ret));
+ }
+out:
+ free_Authenticator(auth);
+ free(auth);
+ return ret;
+}
+
+static Realm
+is_krbtgt(PrincipalName *p)
+{
+ if(p->name_string.len == 2 && strcmp(p->name_string.val[0], "krbtgt") == 0)
+ return p->name_string.val[1];
+ else
+ return NULL;
+}
+
+static Realm
+find_rpath(Realm r)
+{
+ const char *new_realm = krb5_config_get_string(context,
+ NULL,
+ "libdefaults",
+ "capath",
+ r,
+ NULL);
+ return (Realm)new_realm;
+}
+
+
+static krb5_error_code
+tgs_rep2(KDC_REQ_BODY *b,
+ PA_DATA *tgs_req,
+ krb5_data *reply,
+ const char *from,
+ struct sockaddr *from_addr)
+{
+ krb5_ap_req ap_req;
+ krb5_error_code ret;
+ krb5_principal princ;
+ krb5_auth_context ac = NULL;
+ krb5_ticket *ticket = NULL;
+ krb5_flags ap_req_options;
+ krb5_flags verify_ap_req_flags;
+ const char *e_text = NULL;
+ krb5_crypto crypto;
+
+ hdb_entry *krbtgt = NULL;
+ EncTicketPart *tgt;
+ Key *tkey;
+ krb5_enctype cetype;
+ krb5_principal cp = NULL;
+ krb5_principal sp = NULL;
+ AuthorizationData *auth_data = NULL;
+
+ memset(&ap_req, 0, sizeof(ap_req));
+ ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
+ if(ret){
+ kdc_log(0, "Failed to decode AP-REQ: %s",
+ krb5_get_err_text(context, ret));
+ goto out2;
+ }
+
+ if(!is_krbtgt(&ap_req.ticket.sname)){
+ /* XXX check for ticket.sname == req.sname */
+ kdc_log(0, "PA-DATA is not a ticket-granting ticket");
+ ret = KRB5KDC_ERR_POLICY; /* ? */
+ goto out2;
+ }
+
+ principalname2krb5_principal(&princ,
+ ap_req.ticket.sname,
+ ap_req.ticket.realm);
+
+ krbtgt = db_fetch(princ);
+
+ if(krbtgt == NULL) {
+ char *p;
+ krb5_unparse_name(context, princ, &p);
+ kdc_log(0, "Ticket-granting ticket not found in database: %s", p);
+ free(p);
+ ret = KRB5KRB_AP_ERR_NOT_US;
+ goto out2;
+ }
+
+ if(ap_req.ticket.enc_part.kvno &&
+ *ap_req.ticket.enc_part.kvno != krbtgt->kvno){
+ char *p;
+
+ krb5_unparse_name (context, princ, &p);
+ kdc_log(0, "Ticket kvno = %d, DB kvno = %d (%s)",
+ *ap_req.ticket.enc_part.kvno,
+ krbtgt->kvno,
+ p);
+ free (p);
+ ret = KRB5KRB_AP_ERR_BADKEYVER;
+ goto out2;
+ }
+
+ ret = hdb_enctype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey);
+ if(ret){
+ char *str;
+ krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
+ kdc_log(0, "No server key found for %s", str);
+ free(str);
+ ret = KRB5KRB_AP_ERR_BADKEYVER;
+ goto out2;
+ }
+
+ if (b->kdc_options.validate)
+ verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID;
+ else
+ verify_ap_req_flags = 0;
+
+ ret = krb5_verify_ap_req(context,
+ &ac,
+ &ap_req,
+ princ,
+ &tkey->key,
+ verify_ap_req_flags,
+ &ap_req_options,
+ &ticket);
+
+ krb5_free_principal(context, princ);
+ if(ret) {
+ kdc_log(0, "Failed to verify AP-REQ: %s",
+ krb5_get_err_text(context, ret));
+ goto out2;
+ }
+
+ cetype = ap_req.authenticator.etype;
+
+ tgt = &ticket->ticket;
+
+ ret = tgs_check_authenticator(ac, b, &tgt->key);
+
+ if (b->enc_authorization_data) {
+ krb5_keyblock *subkey;
+ krb5_data ad;
+ ret = krb5_auth_con_getremotesubkey(context,
+ ac,
+ &subkey);
+ if(ret){
+ kdc_log(0, "Failed to get remote subkey: %s",
+ krb5_get_err_text(context, ret));
+ goto out2;
+ }
+ if(subkey == NULL){
+ ret = krb5_auth_con_getkey(context, ac, &subkey);
+ if(ret) {
+ kdc_log(0, "Failed to get session key: %s",
+ krb5_get_err_text(context, ret));
+ goto out2;
+ }
+ }
+ if(subkey == NULL){
+ kdc_log(0, "Failed to get key for enc-authorization-data");
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+ goto out2;
+ }
+ krb5_crypto_init(context, subkey, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
+ b->enc_authorization_data,
+ &ad);
+ krb5_crypto_destroy(context, crypto);
+ if(ret){
+ kdc_log(0, "Failed to decrypt enc-authorization-data");
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+ goto out2;
+ }
+ krb5_free_keyblock(context, subkey);
+ ALLOC(auth_data);
+ ret = decode_AuthorizationData(ad.data, ad.length, auth_data, NULL);
+ if(ret){
+ free(auth_data);
+ auth_data = NULL;
+ kdc_log(0, "Failed to decode authorization data");
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+ goto out2;
+ }
+ }
+
+ krb5_auth_con_free(context, ac);
+
+ if(ret){
+ kdc_log(0, "Failed to verify authenticator: %s",
+ krb5_get_err_text(context, ret));
+ goto out2;
+ }
+
+ {
+ PrincipalName *s;
+ Realm r;
+ char *spn = NULL, *cpn = NULL;
+ hdb_entry *server = NULL, *client = NULL;
+ int loop = 0;
+ EncTicketPart adtkt;
+ char opt_str[128];
+
+ s = b->sname;
+ r = b->realm;
+ if(b->kdc_options.enc_tkt_in_skey){
+ Ticket *t;
+ hdb_entry *uu;
+ krb5_principal p;
+ Key *tkey;
+
+ if(b->additional_tickets == NULL ||
+ b->additional_tickets->len == 0){
+ ret = KRB5KDC_ERR_BADOPTION; /* ? */
+ kdc_log(0, "No second ticket present in request");
+ goto out;
+ }
+ t = &b->additional_tickets->val[0];
+ if(!is_krbtgt(&t->sname)){
+ kdc_log(0, "Additional ticket is not a ticket-granting ticket");
+ ret = KRB5KDC_ERR_POLICY;
+ goto out2;
+ }
+ principalname2krb5_principal(&p, t->sname, t->realm);
+ uu = db_fetch(p);
+ krb5_free_principal(context, p);
+ if(uu == NULL){
+ ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
+ goto out;
+ }
+ ret = hdb_enctype2key(context, uu, t->enc_part.etype, &tkey);
+ if(ret){
+ ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
+ goto out;
+ }
+ ret = krb5_decrypt_ticket(context, t, &tkey->key, &adtkt, 0);
+
+ if(ret)
+ goto out;
+ s = &adtkt.cname;
+ r = adtkt.crealm;
+ }
+
+ principalname2krb5_principal(&sp, *s, r);
+ krb5_unparse_name(context, sp, &spn);
+ principalname2krb5_principal(&cp, tgt->cname, tgt->crealm);
+ krb5_unparse_name(context, cp, &cpn);
+ unparse_flags (KDCOptions2int(b->kdc_options), KDCOptions_units,
+ opt_str, sizeof(opt_str));
+ if(*opt_str)
+ kdc_log(0, "TGS-REQ %s from %s for %s [%s]",
+ cpn, from, spn, opt_str);
+ else
+ kdc_log(0, "TGS-REQ %s from %s for %s", cpn, from, spn);
+ server_lookup:
+ server = db_fetch(sp);
+
+
+ if(server == NULL){
+ Realm req_rlm, new_rlm;
+ if(loop++ < 2 && (req_rlm = is_krbtgt(&sp->name))){
+ new_rlm = find_rpath(req_rlm);
+ if(new_rlm) {
+ kdc_log(5, "krbtgt for realm %s not found, trying %s",
+ req_rlm, new_rlm);
+ krb5_free_principal(context, sp);
+ free(spn);
+ krb5_make_principal(context, &sp, r,
+ "krbtgt", new_rlm, NULL);
+ krb5_unparse_name(context, sp, &spn);
+ goto server_lookup;
+ }
+ }
+ kdc_log(0, "Server not found in database: %s", spn);
+ ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
+ goto out;
+ }
+
+ client = db_fetch(cp);
+ if(client == NULL)
+ kdc_log(1, "Client not found in database: %s", cpn);
+#if 0
+ /* XXX check client only if same realm as krbtgt-instance */
+ if(client == NULL){
+ kdc_log(0, "Client not found in database: %s", cpn);
+ ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+ goto out;
+ }
+#endif
+
+ ret = check_flags(client, cpn, server, spn, FALSE);
+ if(ret)
+ goto out;
+
+ if((b->kdc_options.validate || b->kdc_options.renew) &&
+ !krb5_principal_compare(context,
+ krbtgt->principal,
+ server->principal)){
+ kdc_log(0, "Inconsistent request.");
+ ret = KRB5KDC_ERR_SERVER_NOMATCH;
+ goto out;
+ }
+
+ /* check for valid set of addresses */
+ if(!check_addresses(tgt->caddr, from_addr)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ kdc_log(0, "Request from wrong address");
+ goto out;
+ }
+
+ ret = tgs_make_reply(b,
+ tgt,
+ b->kdc_options.enc_tkt_in_skey ? &adtkt : NULL,
+ auth_data,
+ server,
+ client,
+ cp,
+ krbtgt,
+ cetype,
+ reply);
+
+ out:
+ free(spn);
+ free(cpn);
+
+ if(server){
+ hdb_free_entry(context, server);
+ free(server);
+ }
+ if(client){
+ hdb_free_entry(context, client);
+ free(client);
+ }
+
+ }
+out2:
+ if(ret)
+ krb5_mk_error(context,
+ ret,
+ e_text,
+ NULL,
+ cp,
+ sp,
+ 0,
+ reply);
+ krb5_free_principal(context, cp);
+ krb5_free_principal(context, sp);
+ if (ticket) {
+ krb5_free_ticket(context, ticket);
+ free(ticket);
+ }
+ free_AP_REQ(&ap_req);
+ if(auth_data){
+ free_AuthorizationData(auth_data);
+ free(auth_data);
+ }
+
+ if(krbtgt){
+ hdb_free_entry(context, krbtgt);
+ free(krbtgt);
+ }
+ return ret;
+}
+
+
+krb5_error_code
+tgs_rep(KDC_REQ *req,
+ krb5_data *data,
+ const char *from,
+ struct sockaddr *from_addr)
+{
+ krb5_error_code ret;
+ int i = 0;
+ PA_DATA *tgs_req = NULL;
+
+ if(req->padata == NULL){
+ ret = KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */
+ kdc_log(0, "TGS-REQ from %s without PA-DATA", from);
+ goto out;
+ }
+
+ tgs_req = find_padata(req, &i, pa_tgs_req);
+
+ if(tgs_req == NULL){
+ ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
+
+ kdc_log(0, "TGS-REQ from %s without PA-TGS-REQ", from);
+ goto out;
+ }
+ ret = tgs_rep2(&req->req_body, tgs_req, data, from, from_addr);
+out:
+ if(ret && data->data == NULL){
+ krb5_mk_error(context,
+ ret,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ data);
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/kdc/kstash.8 b/crypto/heimdal/kdc/kstash.8
new file mode 100644
index 000000000000..e9a7502a194f
--- /dev/null
+++ b/crypto/heimdal/kdc/kstash.8
@@ -0,0 +1,27 @@
+.\" $Id: kstash.8,v 1.2 2000/01/08 10:57:31 assar Exp $
+.\"
+.Dd Aug 27, 1997
+.Dt KSTASH 8
+.Os HEIMDAL
+.Sh NAME
+.Nm kstash
+.Nd
+Store the KDC master password in a file
+.Sh SYNOPSIS
+.Nm
+.Op Fl k Ar file
+.Op Fl -key-file= Ns Ar file
+.Sh DESCRIPTION
+.Nm
+allows you to the master password and store in a file that will be read
+by the KDC.
+.Pp
+Options supported:
+.Bl -tag -width Ds
+.It Fl k Ar file
+.It Fl -key-file= Ns Ar file
+Specify what file the master key is stored in. The default is
+.Pa m-key .
+.El
+.Sh SEE ALSO
+.Xr kdc 8
diff --git a/crypto/heimdal/kdc/kstash.c b/crypto/heimdal/kdc/kstash.c
new file mode 100644
index 000000000000..5b79fd1e6553
--- /dev/null
+++ b/crypto/heimdal/kdc/kstash.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "headers.h"
+
+RCSID("$Id: kstash.c,v 1.10 1999/11/13 04:14:17 assar Exp $");
+
+krb5_context context;
+
+char *keyfile = HDB_DB_DIR "/m-key";
+char *v4_keyfile;
+int convert_flag;
+int help_flag;
+int version_flag;
+
+struct getargs args[] = {
+ { "key-file", 'k', arg_string, &keyfile, "master key file", "file" },
+ { "version4-key-file", '4', arg_string, &v4_keyfile,
+ "kerberos 4 master key file", "file" },
+ { "convert-file", 0, arg_flag, &convert_flag,
+ "convert keytype of keyfile" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 0, arg_flag, &version_flag }
+};
+
+int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+write_keyfile(EncryptionKey key)
+{
+ FILE *f;
+ char buf[1024];
+ size_t len;
+
+#ifdef HAVE_UMASK
+ umask(077);
+#endif
+
+ f = fopen(keyfile, "w");
+ if(f == NULL)
+ krb5_err(context, 1, errno, "%s", keyfile);
+ encode_EncryptionKey((unsigned char *)buf + sizeof(buf) - 1,
+ sizeof(buf), &key, &len);
+ fwrite(buf + sizeof(buf) - len, len, 1, f);
+ memset(buf, 0, sizeof(buf));
+ if(ferror(f)) {
+ int e = errno;
+ unlink(keyfile);
+ krb5_err(context, 1, e, "%s", keyfile);
+ }
+ fclose(f);
+ chmod(keyfile, 0400);
+}
+
+static int
+convert_file(void)
+{
+ FILE *f;
+ unsigned char buf[1024];
+ char *fn;
+ size_t len;
+ EncryptionKey key;
+ krb5_error_code ret;
+
+ f = fopen(keyfile, "r");
+ if(f == NULL) {
+ krb5_warn(context, errno, "%s", keyfile);
+ return 1;
+ }
+ len = fread(buf, 1, sizeof(buf), f);
+ if(ferror(f)) {
+ krb5_warn(context, errno, "fread");
+ ret = 1;
+ goto out1;
+ }
+ fclose(f);
+ ret = decode_EncryptionKey(buf, len, &key, &len);
+ memset(buf, 0, sizeof(buf));
+ if(ret) {
+ krb5_warn(context, ret, "decode_EncryptionKey");
+ goto out2;
+ }
+ if(key.keytype == KEYTYPE_DES)
+ key.keytype = ETYPE_DES_CBC_MD5;
+ else if(key.keytype == ETYPE_DES_CBC_MD5) {
+ krb5_warnx(context, "keyfile already converted");
+ ret = 0;
+ goto out2;
+ } else {
+ krb5_warnx(context, "bad encryption key type (%d)", key.keytype);
+ ret = 1;
+ goto out2;
+ }
+ asprintf(&fn, "%s.old", keyfile);
+ if(fn == NULL) {
+ krb5_warn(context, ENOMEM, "malloc");
+ ret = 1;
+ goto out1;
+ }
+ if(rename(keyfile, fn) < 0) {
+ krb5_warn(context, errno, "rename");
+ ret = 1;
+ goto out1;
+ }
+ write_keyfile(key);
+ krb5_free_keyblock_contents(context, &key);
+ return 0;
+out1:
+ memset(buf, 0, sizeof(buf));
+ return ret ? 1 : 0;
+out2:
+ krb5_free_keyblock_contents(context, &key);
+ return ret ? 1 : 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ char buf[1024];
+ EncryptionKey key;
+ FILE *f;
+
+ krb5_program_setup(&context, argc, argv, args, num_args, NULL);
+
+ if(help_flag)
+ krb5_std_usage(0, args, num_args);
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ if(convert_flag)
+ exit(convert_file());
+
+ key.keytype = ETYPE_DES_CBC_MD5; /* XXX */
+ if(v4_keyfile) {
+ f = fopen(v4_keyfile, "r");
+ if(f == NULL)
+ krb5_err(context, 1, errno, "fopen(%s)", v4_keyfile);
+ key.keyvalue.length = sizeof(des_cblock);
+ key.keyvalue.data = malloc(key.keyvalue.length);
+ fread(key.keyvalue.data, 1, key.keyvalue.length, f);
+ fclose(f);
+ } else {
+ krb5_salt salt;
+ salt.salttype = KRB5_PW_SALT;
+ /* XXX better value? */
+ salt.saltvalue.data = NULL;
+ salt.saltvalue.length = 0;
+ if(des_read_pw_string(buf, sizeof(buf), "Master key: ", 1))
+ exit(1);
+ krb5_string_to_key_salt(context, key.keytype, buf, salt, &key);
+ }
+
+ write_keyfile(key);
+ krb5_free_keyblock_contents(context, &key);
+ exit(0);
+}
diff --git a/crypto/heimdal/kdc/log.c b/crypto/heimdal/kdc/log.c
new file mode 100644
index 000000000000..ddbdbeea8e13
--- /dev/null
+++ b/crypto/heimdal/kdc/log.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kdc_locl.h"
+RCSID("$Id: log.c,v 1.12 1999/12/02 17:05:00 joda Exp $");
+
+static krb5_log_facility *logf;
+
+void
+kdc_openlog(krb5_config_section *cf)
+{
+ char **s = NULL, **p;
+ krb5_initlog(context, "kdc", &logf);
+ if(cf)
+ s = krb5_config_get_strings(context, cf, "kdc", "logging", NULL);
+
+ if(s == NULL)
+ s = krb5_config_get_strings(context, NULL, "logging", "kdc", NULL);
+ if(s){
+ for(p = s; *p; p++)
+ krb5_addlog_dest(context, logf, *p);
+ krb5_config_free_strings(s);
+ }else
+ krb5_addlog_dest(context, logf, "0-1/FILE:" HDB_DB_DIR "/kdc.log");
+ krb5_set_warn_dest(context, logf);
+}
+
+char*
+kdc_log_msg_va(int level, const char *fmt, va_list ap)
+{
+ char *msg;
+ krb5_vlog_msg(context, logf, &msg, level, fmt, ap);
+ return msg;
+}
+
+char*
+kdc_log_msg(int level, const char *fmt, ...)
+{
+ va_list ap;
+ char *s;
+ va_start(ap, fmt);
+ s = kdc_log_msg_va(level, fmt, ap);
+ va_end(ap);
+ return s;
+}
+
+void
+kdc_log(int level, const char *fmt, ...)
+{
+ va_list ap;
+ char *s;
+ va_start(ap, fmt);
+ s = kdc_log_msg_va(level, fmt, ap);
+ if(s) free(s);
+ va_end(ap);
+}
diff --git a/crypto/heimdal/kdc/main.c b/crypto/heimdal/kdc/main.c
new file mode 100644
index 000000000000..46d7aba32f8c
--- /dev/null
+++ b/crypto/heimdal/kdc/main.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kdc_locl.h"
+
+RCSID("$Id: main.c,v 1.21 1999/12/02 17:05:00 joda Exp $");
+
+sig_atomic_t exit_flag = 0;
+krb5_context context;
+
+static RETSIGTYPE
+sigterm(int sig)
+{
+ exit_flag = 1;
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ set_progname(argv[0]);
+
+ krb5_init_context(&context);
+
+ configure(argc, argv);
+
+ if(databases == NULL) {
+ db = malloc(sizeof(*db));
+ num_db = 1;
+ ret = hdb_create(context, &db[0], NULL);
+ if(ret)
+ krb5_err(context, 1, ret, "hdb_create %s", HDB_DEFAULT_DB);
+ ret = hdb_set_master_keyfile(context, db[0], NULL);
+ if (ret)
+ krb5_err(context, 1, ret, "hdb_set_master_keyfile");
+ } else {
+ struct dbinfo *d;
+ int i;
+ /* count databases */
+ for(d = databases, i = 0; d; d = d->next, i++);
+ db = malloc(i * sizeof(*db));
+ for(d = databases, num_db = 0; d; d = d->next, num_db++) {
+ ret = hdb_create(context, &db[num_db], d->dbname);
+ if(ret)
+ krb5_err(context, 1, ret, "hdb_create %s", d->dbname);
+ ret = hdb_set_master_keyfile(context, db[num_db], d->mkey_file);
+ if (ret)
+ krb5_err(context, 1, ret, "hdb_set_master_keyfile");
+ }
+ }
+
+#ifdef HAVE_SIGACTION
+ {
+ struct sigaction sa;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = sigterm;
+ sigemptyset(&sa.sa_mask);
+
+ sigaction(SIGINT, &sa, NULL);
+ }
+#else
+ signal(SIGINT, sigterm);
+#endif
+ loop();
+ krb5_free_context(context);
+ return 0;
+}
diff --git a/crypto/heimdal/kdc/misc.c b/crypto/heimdal/kdc/misc.c
new file mode 100644
index 000000000000..e476ebc0282a
--- /dev/null
+++ b/crypto/heimdal/kdc/misc.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kdc_locl.h"
+
+RCSID("$Id: misc.c,v 1.18 1999/12/02 17:05:00 joda Exp $");
+
+struct timeval now;
+
+hdb_entry*
+db_fetch(krb5_principal principal)
+{
+ hdb_entry *ent;
+ krb5_error_code ret;
+ int i;
+ ALLOC(ent);
+ ent->principal = principal;
+
+ for(i = 0; i < num_db; i++) {
+ ret = db[i]->open(context, db[i], O_RDONLY, 0);
+ if (ret) {
+ kdc_log(0, "Failed to open database: %s",
+ krb5_get_err_text(context, ret));
+ continue;
+ }
+ ret = db[i]->fetch(context, db[i], HDB_F_DECRYPT, ent);
+ db[i]->close(context, db[i]);
+ if(ret == 0)
+ return ent;
+ }
+ free(ent);
+ return NULL;
+}
diff --git a/crypto/heimdal/kdc/rx.h b/crypto/heimdal/kdc/rx.h
new file mode 100644
index 000000000000..ab8ec8052318
--- /dev/null
+++ b/crypto/heimdal/kdc/rx.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: rx.h,v 1.4 1999/12/02 17:05:00 joda Exp $ */
+
+#ifndef __RX_H__
+#define __RX_H__
+
+/* header of a RPC packet */
+
+enum rx_header_type {
+ HT_DATA = 1,
+ HT_ACK = 2,
+ HT_BUSY = 3,
+ HT_ABORT = 4,
+ HT_ACKALL = 5,
+ HT_CHAL = 6,
+ HT_RESP = 7,
+ HT_DEBUG = 8
+};
+
+/* For flags in header */
+
+enum rx_header_flag {
+ HF_CLIENT_INITIATED = 1,
+ HF_REQ_ACK = 2,
+ HF_LAST = 4,
+ HF_MORE = 8
+};
+
+struct rx_header {
+ u_int32_t epoch;
+ u_int32_t connid; /* And channel ID */
+ u_int32_t callid;
+ u_int32_t seqno;
+ u_int32_t serialno;
+ u_char type;
+ u_char flags;
+ u_char status;
+ u_char secindex;
+ u_int16_t reserved; /* ??? verifier? */
+ u_int16_t serviceid;
+/* This should be the other way around according to everything but */
+/* tcpdump */
+};
+
+#define RX_HEADER_SIZE 28
+
+#endif /* __RX_H__ */
diff --git a/crypto/heimdal/kdc/string2key.c b/crypto/heimdal/kdc/string2key.c
new file mode 100644
index 000000000000..e0cc87105bc6
--- /dev/null
+++ b/crypto/heimdal/kdc/string2key.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "headers.h"
+#include <getarg.h>
+
+RCSID("$Id: string2key.c,v 1.18 1999/12/02 17:05:00 joda Exp $");
+
+int version5;
+int version4;
+int afs;
+char *principal;
+char *cell;
+char *password;
+char *keytype_str = "des-cbc-md5";
+int version;
+int help;
+
+struct getargs args[] = {
+ { "version5", '5', arg_flag, &version5, "Output Kerberos v5 string-to-key" },
+ { "version4", '4', arg_flag, &version4, "Output Kerberos v4 string-to-key" },
+ { "afs", 'a', arg_flag, &afs, "Output AFS string-to-key" },
+ { "cell", 'c', arg_string, &cell, "AFS cell to use", "cell" },
+ { "password", 'w', arg_string, &password, "Password to use", "password" },
+ { "principal",'p', arg_string, &principal, "Kerberos v5 principal to use", "principal" },
+ { "keytype", 'k', arg_string, &keytype_str, "Keytype" },
+ { "version", 0, arg_flag, &version, "print version" },
+ { "help", 0, arg_flag, &help, NULL }
+};
+
+int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int status)
+{
+ arg_printusage (args, num_args, NULL, "password");
+ exit(status);
+}
+
+static void
+tokey(krb5_context context,
+ krb5_enctype enctype,
+ const char *password,
+ krb5_salt salt,
+ const char *label)
+{
+ int i;
+ krb5_keyblock key;
+ krb5_string_to_key_salt(context, enctype, password, salt, &key);
+ printf("%s: ", label);
+ for(i = 0; i < key.keyvalue.length; i++)
+ printf("%02x", ((unsigned char*)key.keyvalue.data)[i]);
+ printf("\n");
+ krb5_free_keyblock_contents(context, &key);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context;
+ krb5_principal princ;
+ krb5_salt salt;
+ int optind;
+ char buf[1024];
+ krb5_enctype etype;
+ krb5_error_code ret;
+
+ optind = krb5_program_setup(&context, argc, argv, args, num_args, NULL);
+
+ if(help)
+ usage(0);
+
+ if(version){
+ print_version (NULL);
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 1)
+ usage(1);
+
+ if(!version5 && !version4 && !afs)
+ version5 = 1;
+
+ ret = krb5_string_to_enctype(context, keytype_str, &etype);
+#if 0
+ if(ret) {
+ krb5_keytype keytype;
+ ret = krb5_string_to_keytype(context, keytype_str, &keytype);
+ ret = krb5_keytype_to_enctype(context, keytype, &etype);
+ }
+#endif
+ if(ret)
+ krb5_err(context, 1, ret, "%s", keytype_str);
+
+ if((etype != ETYPE_DES_CBC_CRC &&
+ etype != ETYPE_DES_CBC_MD4 &&
+ etype != ETYPE_DES_CBC_MD5) &&
+ (afs || version4))
+ krb5_errx(context, 1,
+ "DES is the only valid keytype for AFS and Kerberos 4");
+
+
+ if(version5 && principal == NULL){
+ printf("Kerberos v5 principal: ");
+ if(fgets(buf, sizeof(buf), stdin) == NULL)
+ return 1;
+ if(buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ principal = estrdup(buf);
+ }
+ if(afs && cell == NULL){
+ printf("AFS cell: ");
+ if(fgets(buf, sizeof(buf), stdin) == NULL)
+ return 1;
+ if(buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ cell = estrdup(buf);
+ }
+ if(argv[0])
+ password = argv[0];
+ if(password == NULL){
+ if(des_read_pw_string(buf, sizeof(buf), "Password: ", 0))
+ return 1;
+ password = buf;
+ }
+
+ if(version5){
+ krb5_parse_name(context, principal, &princ);
+ krb5_get_pw_salt(context, princ, &salt);
+ tokey(context, etype, password, salt, "Kerberos v5 key");
+ krb5_free_salt(context, salt);
+ }
+ if(version4){
+ salt.salttype = KRB5_PW_SALT;
+ salt.saltvalue.length = 0;
+ salt.saltvalue.data = NULL;
+ tokey(context, ETYPE_DES_CBC_MD5, password, salt, "Kerberos v4 key");
+ }
+ if(afs){
+ salt.salttype = KRB5_AFS3_SALT;
+ salt.saltvalue.length = strlen(cell);
+ salt.saltvalue.data = cell;
+ tokey(context, ETYPE_DES_CBC_MD5, password, salt, "AFS key");
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/kpasswd/Makefile.am b/crypto/heimdal/kpasswd/Makefile.am
new file mode 100644
index 000000000000..fba61e3a3784
--- /dev/null
+++ b/crypto/heimdal/kpasswd/Makefile.am
@@ -0,0 +1,25 @@
+# $Id: Makefile.am,v 1.11 1999/04/20 16:48:34 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+man_MANS = kpasswd.1 kpasswdd.8
+
+bin_PROGRAMS = kpasswd
+
+kpasswd_SOURCES = kpasswd.c kpasswd_locl.h
+
+libexec_PROGRAMS = kpasswdd
+
+kpasswdd_SOURCES = kpasswdd.c kpasswd_locl.h
+
+kpasswdd_LDADD = \
+ $(top_builddir)/lib/kadm5/libkadm5srv.la \
+ $(top_builddir)/lib/hdb/libhdb.la \
+ $(LDADD) \
+ $(LIB_dlopen) \
+ $(DBLIB)
+
+LDADD = $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
diff --git a/crypto/heimdal/kpasswd/Makefile.in b/crypto/heimdal/kpasswd/Makefile.in
new file mode 100644
index 000000000000..11e169b2ddb6
--- /dev/null
+++ b/crypto/heimdal/kpasswd/Makefile.in
@@ -0,0 +1,758 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.11 1999/04/20 16:48:34 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+man_MANS = kpasswd.1 kpasswdd.8
+
+bin_PROGRAMS = kpasswd
+
+kpasswd_SOURCES = kpasswd.c kpasswd_locl.h
+
+libexec_PROGRAMS = kpasswdd
+
+kpasswdd_SOURCES = kpasswdd.c kpasswd_locl.h
+
+kpasswdd_LDADD = $(top_builddir)/lib/kadm5/libkadm5srv.la $(top_builddir)/lib/hdb/libhdb.la $(LDADD) $(LIB_dlopen) $(DBLIB)
+
+
+LDADD = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = kpasswd$(EXEEXT)
+libexec_PROGRAMS = kpasswdd$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+kpasswd_OBJECTS = kpasswd.$(OBJEXT)
+kpasswd_LDADD = $(LDADD)
+kpasswd_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+kpasswd_LDFLAGS =
+kpasswdd_OBJECTS = kpasswdd.$(OBJEXT)
+kpasswdd_DEPENDENCIES = $(top_builddir)/lib/kadm5/libkadm5srv.la \
+$(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+kpasswdd_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man1dir = $(mandir)/man1
+man8dir = $(mandir)/man8
+MANS = $(man_MANS)
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(kpasswd_SOURCES) $(kpasswdd_SOURCES)
+OBJECTS = $(kpasswd_OBJECTS) $(kpasswdd_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign kpasswd/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-libexecPROGRAMS:
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+
+distclean-libexecPROGRAMS:
+
+maintainer-clean-libexecPROGRAMS:
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+kpasswd$(EXEEXT): $(kpasswd_OBJECTS) $(kpasswd_DEPENDENCIES)
+ @rm -f kpasswd$(EXEEXT)
+ $(LINK) $(kpasswd_LDFLAGS) $(kpasswd_OBJECTS) $(kpasswd_LDADD) $(LIBS)
+
+kpasswdd$(EXEEXT): $(kpasswdd_OBJECTS) $(kpasswdd_DEPENDENCIES)
+ @rm -f kpasswdd$(EXEEXT)
+ $(LINK) $(kpasswdd_LDFLAGS) $(kpasswdd_OBJECTS) $(kpasswdd_LDADD) $(LIBS)
+
+install-man1:
+ $(mkinstalldirs) $(DESTDIR)$(man1dir)
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
+ done
+
+uninstall-man1:
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man1dir)/$$inst; \
+ done
+
+install-man8:
+ $(mkinstalldirs) $(DESTDIR)$(man8dir)
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
+ done
+
+uninstall-man8:
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man8dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man1 install-man8
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man1 uninstall-man8
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = kpasswd
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS install-libexecPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-man install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS uninstall-libexecPROGRAMS \
+ uninstall-man
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(MANS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(libexecdir) \
+ $(DESTDIR)$(mandir)/man1 $(DESTDIR)$(mandir)/man8
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-libexecPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-libexecPROGRAMS clean-compile \
+ clean-libtool clean-tags clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-libexecPROGRAMS \
+ distclean-compile distclean-libtool distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-libexecPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-libexecPROGRAMS distclean-libexecPROGRAMS \
+clean-libexecPROGRAMS maintainer-clean-libexecPROGRAMS \
+uninstall-libexecPROGRAMS install-libexecPROGRAMS mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool install-man1 uninstall-man1 install-man8 \
+uninstall-man8 install-man uninstall-man tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/kpasswd/kpasswd.1 b/crypto/heimdal/kpasswd/kpasswd.1
new file mode 100644
index 000000000000..8cbc83b36e39
--- /dev/null
+++ b/crypto/heimdal/kpasswd/kpasswd.1
@@ -0,0 +1,20 @@
+.\" $Id: kpasswd.1,v 1.1 1997/08/27 23:44:08 assar Exp $
+.\"
+.Dt Aug 27, 1997
+.Dt KPASSWD 1
+.Os HEIMDAL
+.Sh NAME
+.Nm kpasswd
+.Nd
+Kerberos 5 password changing program
+.Sh SYNOPSIS
+.Nm
+.Op Ar principal
+.Sh DESCRIPTION
+.Nm
+is the client for changing passwords.
+.Sh DIAGNOSTICS
+If the password quality check fails or some other error occurs, an
+explanation is printed.
+.Sh SEE ALSO
+.Xr kpasswdd 8
diff --git a/crypto/heimdal/kpasswd/kpasswd.c b/crypto/heimdal/kpasswd/kpasswd.c
new file mode 100644
index 000000000000..eecea783f8be
--- /dev/null
+++ b/crypto/heimdal/kpasswd/kpasswd.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kpasswd_locl.h"
+RCSID("$Id: kpasswd.c,v 1.20 1999/12/02 17:05:00 joda Exp $");
+
+static int version_flag;
+static int help_flag;
+
+static struct getargs args[] = {
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "[principal]");
+ exit (ret);
+}
+
+int
+main (int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_principal principal;
+ int optind = 0;
+ krb5_get_init_creds_opt opt;
+ krb5_creds cred;
+ int result_code;
+ krb5_data result_code_string, result_string;
+ char pwbuf[BUFSIZ];
+
+ optind = krb5_program_setup(&context, argc, argv,
+ args, sizeof(args) / sizeof(args[0]), NULL);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version (NULL);
+ exit(0);
+ }
+
+ krb5_get_init_creds_opt_init (&opt);
+
+ krb5_get_init_creds_opt_set_tkt_life (&opt, 300);
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 1)
+ usage(1);
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx (1, "krb5_init_context: %s", krb5_get_err_text(context, ret));
+
+ if(argv[0]) {
+ ret = krb5_parse_name (context, argv[0], &principal);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name");
+ } else
+ principal = NULL;
+
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ principal,
+ NULL,
+ krb5_prompter_posix,
+ NULL,
+ 0,
+ "kadmin/changepw",
+ &opt);
+ switch (ret) {
+ case 0:
+ break;
+ case KRB5_LIBOS_PWDINTR :
+ return 1;
+ case KRB5KRB_AP_ERR_BAD_INTEGRITY :
+ case KRB5KRB_AP_ERR_MODIFIED :
+ krb5_errx(context, 1, "Password incorrect");
+ break;
+ default:
+ krb5_err(context, 1, ret, "krb5_get_init_creds");
+ }
+
+ krb5_data_zero (&result_code_string);
+ krb5_data_zero (&result_string);
+
+ if(des_read_pw_string (pwbuf, sizeof(pwbuf), "New password: ", 1) != 0)
+ return 1;
+
+ ret = krb5_change_password (context, &cred, pwbuf,
+ &result_code,
+ &result_code_string,
+ &result_string);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_change_password");
+
+ printf ("Reply from server: %.*s\n", (int)result_string.length,
+ (char *)result_string.data);
+
+ krb5_data_free (&result_code_string);
+ krb5_data_free (&result_string);
+
+ krb5_free_creds_contents (context, &cred);
+ krb5_free_context (context);
+ return result_code;
+}
diff --git a/crypto/heimdal/kpasswd/kpasswd_locl.h b/crypto/heimdal/kpasswd/kpasswd_locl.h
new file mode 100644
index 000000000000..0e05489725e9
--- /dev/null
+++ b/crypto/heimdal/kpasswd/kpasswd_locl.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: kpasswd_locl.h,v 1.7 1999/12/02 17:05:00 joda Exp $ */
+
+#ifndef __KPASSWD_LOCL_H__
+#define __KPASSWD_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <err.h>
+#include <roken.h>
+#include <getarg.h>
+#include <krb5.h>
+
+#endif /* __KPASSWD_LOCL_H__ */
diff --git a/crypto/heimdal/kpasswd/kpasswdd.8 b/crypto/heimdal/kpasswd/kpasswdd.8
new file mode 100644
index 000000000000..f4db441166a4
--- /dev/null
+++ b/crypto/heimdal/kpasswd/kpasswdd.8
@@ -0,0 +1,60 @@
+.\" $Id: kpasswdd.8,v 1.2 1999/04/19 16:32:01 joda Exp $
+.\"
+.Dd April 19, 1999
+.Dt KPASSWDD 8
+.Os HEIMDAL
+.Sh NAME
+.Nm kpasswdd
+.Nd
+Kerberos 5 password changing server
+.Sh SYNOPSIS
+.Nm
+.Op Fl -check-library= Ns Ar library
+.Op Fl -check-function= Ns Ar function
+.Sh DESCRIPTION
+.Nm
+serves request for password changes. It listens on UDP port 464
+(service kpasswd) and processes requests when they arrive. It changes
+the database directly and should thus only run on the master KDC.
+.Pp
+Supported options:
+.Bl -tag -width Ds
+.It Xo
+.Fl -check-library= Ns Ar library
+.Xc
+If your system has support for dynamic loading of shared libraries,
+you can use an external function to check password quality. This
+option specifies which library to load.
+.It Xo
+.Fl -check-function= Ns Ar function
+.Xc
+This is the function to call in the loaded library. The function
+should look like this:
+.Pp
+.Ft const char *
+.Fn passwd_check "krb5_context context" "krb5_principal principal" "krb5_data *password"
+.Pp
+.Fa context
+is an initialized context;
+.Fa principal
+is the one who tries to change passwords, and
+.Fa password
+is the new password. Note that the password (in
+.Fa password->data )
+is not zero terminated.
+.El
+.Sh DIAGNOSTICS
+If an error occurs, the error message is returned to the user and/or
+logged to syslog.
+.Sh BUGS
+The default password quality checks are too basic.
+.Sh SEE ALSO
+.Xr kdc 8 ,
+.Xr kpasswd 1
+.\".Sh ENVIRONMENT
+.\".Sh FILES
+.\".Sh EXAMPLES
+.\".Sh SEE ALSO
+.\".Sh STANDARDS
+.\".Sh HISTORY
+.\".Sh AUTHORS
diff --git a/crypto/heimdal/kpasswd/kpasswdd.c b/crypto/heimdal/kpasswd/kpasswdd.c
new file mode 100644
index 000000000000..04b8ea391d00
--- /dev/null
+++ b/crypto/heimdal/kpasswd/kpasswdd.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kpasswd_locl.h"
+RCSID("$Id: kpasswdd.c,v 1.41 1999/12/02 17:05:00 joda Exp $");
+
+#include <kadm5/admin.h>
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <hdb.h>
+
+static krb5_context context;
+static krb5_log_facility *log_facility;
+
+static sig_atomic_t exit_flag = 0;
+
+static void
+send_reply (int s,
+ struct sockaddr *sa,
+ int sa_size,
+ krb5_data *ap_rep,
+ krb5_data *rest)
+{
+ struct msghdr msghdr;
+ struct iovec iov[3];
+ u_int16_t len, ap_rep_len;
+ u_char header[6];
+ u_char *p;
+
+ if (ap_rep)
+ ap_rep_len = ap_rep->length;
+ else
+ ap_rep_len = 0;
+
+ len = 6 + ap_rep_len + rest->length;
+ p = header;
+ *p++ = (len >> 8) & 0xFF;
+ *p++ = (len >> 0) & 0xFF;
+ *p++ = 0;
+ *p++ = 1;
+ *p++ = (ap_rep_len >> 8) & 0xFF;
+ *p++ = (ap_rep_len >> 0) & 0xFF;
+
+ memset (&msghdr, 0, sizeof(msghdr));
+ msghdr.msg_name = (void *)sa;
+ msghdr.msg_namelen = sa_size;
+ msghdr.msg_iov = iov;
+ msghdr.msg_iovlen = sizeof(iov)/sizeof(*iov);
+#if 0
+ msghdr.msg_control = NULL;
+ msghdr.msg_controllen = 0;
+#endif
+
+ iov[0].iov_base = (char *)header;
+ iov[0].iov_len = 6;
+ if (ap_rep_len) {
+ iov[1].iov_base = ap_rep->data;
+ iov[1].iov_len = ap_rep->length;
+ } else {
+ iov[1].iov_base = NULL;
+ iov[1].iov_len = 0;
+ }
+ iov[2].iov_base = rest->data;
+ iov[2].iov_len = rest->length;
+
+ if (sendmsg (s, &msghdr, 0) < 0)
+ krb5_warn (context, errno, "sendmsg");
+}
+
+static int
+make_result (krb5_data *data,
+ u_int16_t result_code,
+ const char *expl)
+{
+ krb5_data_zero (data);
+
+ data->length = asprintf ((char **)&data->data,
+ "%c%c%s",
+ (result_code >> 8) & 0xFF,
+ result_code & 0xFF,
+ expl);
+
+ if (data->data == NULL) {
+ krb5_warnx (context, "Out of memory generating error reply");
+ return 1;
+ }
+ return 0;
+}
+
+static void
+reply_error (krb5_principal server,
+ int s,
+ struct sockaddr *sa,
+ int sa_size,
+ krb5_error_code error_code,
+ u_int16_t result_code,
+ const char *expl)
+{
+ krb5_error_code ret;
+ krb5_data error_data;
+ krb5_data e_data;
+
+ if (make_result(&e_data, result_code, expl))
+ return;
+
+ ret = krb5_mk_error (context,
+ error_code,
+ NULL,
+ &e_data,
+ NULL,
+ server,
+ 0,
+ &error_data);
+ krb5_data_free (&e_data);
+ if (ret) {
+ krb5_warn (context, ret, "Could not even generate error reply");
+ return;
+ }
+ send_reply (s, sa, sa_size, NULL, &error_data);
+ krb5_data_free (&error_data);
+}
+
+static void
+reply_priv (krb5_auth_context auth_context,
+ int s,
+ struct sockaddr *sa,
+ int sa_size,
+ u_int16_t result_code,
+ const char *expl)
+{
+ krb5_error_code ret;
+ krb5_data krb_priv_data;
+ krb5_data ap_rep_data;
+ krb5_data e_data;
+
+ ret = krb5_mk_rep (context,
+ &auth_context,
+ &ap_rep_data);
+ if (ret) {
+ krb5_warn (context, ret, "Could not even generate error reply");
+ return;
+ }
+
+ if (make_result(&e_data, result_code, expl))
+ return;
+
+ ret = krb5_mk_priv (context,
+ auth_context,
+ &e_data,
+ &krb_priv_data,
+ NULL);
+ krb5_data_free (&e_data);
+ if (ret) {
+ krb5_warn (context, ret, "Could not even generate error reply");
+ return;
+ }
+ send_reply (s, sa, sa_size, &ap_rep_data, &krb_priv_data);
+ krb5_data_free (&ap_rep_data);
+ krb5_data_free (&krb_priv_data);
+}
+
+/*
+ * Change the password for `principal', sending the reply back on `s'
+ * (`sa', `sa_size') to `pwd_data'.
+ */
+
+static void
+change (krb5_auth_context auth_context,
+ krb5_principal principal,
+ int s,
+ struct sockaddr *sa,
+ int sa_size,
+ krb5_data *pwd_data)
+{
+ krb5_error_code ret;
+ char *client;
+ kadm5_principal_ent_rec ent;
+ krb5_key_data *kd;
+ krb5_salt salt;
+ krb5_keyblock new_keyblock;
+ const char *pwd_reason;
+ int unchanged;
+ kadm5_config_params conf;
+ void *kadm5_handle;
+
+ memset (&conf, 0, sizeof(conf));
+
+ krb5_unparse_name (context, principal, &client);
+
+ ret = kadm5_init_with_password_ctx(context,
+ client,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm5_handle);
+ if (ret) {
+ free (client);
+ krb5_warn (context, ret, "kadm5_init_with_password_ctx");
+ reply_priv (auth_context, s, sa, sa_size, 2,
+ "Internal error");
+ return;
+ }
+
+ krb5_warnx (context, "Changing password for %s", client);
+ free (client);
+
+ pwd_reason = kadm5_check_password_quality (context, principal, pwd_data);
+ if (pwd_reason != NULL ) {
+ krb5_warnx (context, "%s", pwd_reason);
+ reply_priv (auth_context, s, sa, sa_size, 4, pwd_reason);
+ kadm5_destroy (kadm5_handle);
+ return;
+ }
+
+ ret = kadm5_get_principal (kadm5_handle,
+ principal,
+ &ent,
+ KADM5_KEY_DATA);
+ if (ret) {
+ krb5_warn (context, ret, "kadm5_get_principal");
+ reply_priv (auth_context, s, sa, sa_size, 2,
+ "Internal error");
+ kadm5_destroy (kadm5_handle);
+ return;
+ }
+
+ /*
+ * Compare with the first key to see if it already has been
+ * changed. If it hasn't, store the new key in the database and
+ * string2key all the rest of them.
+ */
+
+ kd = &ent.key_data[0];
+
+ salt.salttype = kd->key_data_type[1];
+ salt.saltvalue.length = kd->key_data_length[1];
+ salt.saltvalue.data = kd->key_data_contents[1];
+
+ memset (&new_keyblock, 0, sizeof(new_keyblock));
+ krb5_string_to_key_data_salt (context,
+ kd->key_data_type[0],
+ *pwd_data,
+ salt,
+ &new_keyblock);
+
+ unchanged = new_keyblock.keytype == kd->key_data_type[0]
+ && new_keyblock.keyvalue.length == kd->key_data_length[0]
+ && memcmp(new_keyblock.keyvalue.data,
+ kd->key_data_contents[0],
+ new_keyblock.keyvalue.length) == 0;
+
+ krb5_free_keyblock_contents (context, &new_keyblock);
+
+ if (unchanged) {
+ ret = 0;
+ } else {
+ char *tmp;
+
+ tmp = malloc (pwd_data->length + 1);
+ if (tmp == NULL) {
+ krb5_warnx (context, "malloc: out of memory");
+ reply_priv (auth_context, s, sa, sa_size, 2,
+ "Internal error");
+ goto out;
+ }
+ memcpy (tmp, pwd_data->data, pwd_data->length);
+ tmp[pwd_data->length] = '\0';
+
+ ret = kadm5_chpass_principal (kadm5_handle,
+ principal,
+ tmp);
+ memset (tmp, 0, pwd_data->length);
+ free (tmp);
+ if (ret) {
+ krb5_warn (context, ret, "kadm5_s_chpass_principal");
+ reply_priv (auth_context, s, sa, sa_size, 2,
+ "Internal error");
+ goto out;
+ }
+ }
+ reply_priv (auth_context, s, sa, sa_size, 0, "Password changed");
+out:
+ kadm5_free_principal_ent (kadm5_handle, &ent);
+ kadm5_destroy (kadm5_handle);
+}
+
+static int
+verify (krb5_auth_context *auth_context,
+ krb5_principal server,
+ krb5_keytab keytab,
+ krb5_ticket **ticket,
+ krb5_data *out_data,
+ int s,
+ struct sockaddr *sa,
+ int sa_size,
+ u_char *msg,
+ size_t len)
+{
+ krb5_error_code ret;
+ u_int16_t pkt_len, pkt_ver, ap_req_len;
+ krb5_data ap_req_data;
+ krb5_data krb_priv_data;
+
+ pkt_len = (msg[0] << 8) | (msg[1]);
+ pkt_ver = (msg[2] << 8) | (msg[3]);
+ ap_req_len = (msg[4] << 8) | (msg[5]);
+ if (pkt_len != len) {
+ krb5_warnx (context, "Strange len: %ld != %ld",
+ (long)pkt_len, (long)len);
+ reply_error (server, s, sa, sa_size, 0, 1, "Bad request");
+ return 1;
+ }
+ if (pkt_ver != 0x0001) {
+ krb5_warnx (context, "Bad version (%d)", pkt_ver);
+ reply_error (server, s, sa, sa_size, 0, 1, "Wrong program version");
+ return 1;
+ }
+
+ ap_req_data.data = msg + 6;
+ ap_req_data.length = ap_req_len;
+
+ ret = krb5_rd_req (context,
+ auth_context,
+ &ap_req_data,
+ server,
+ keytab,
+ NULL,
+ ticket);
+ if (ret) {
+ if(ret == KRB5_KT_NOTFOUND) {
+ char *name;
+ krb5_unparse_name(context, server, &name);
+ krb5_warnx (context, "krb5_rd_req: %s (%s)",
+ krb5_get_err_text(context, ret), name);
+ free(name);
+ } else
+ krb5_warn (context, ret, "krb5_rd_req");
+ reply_error (server, s, sa, sa_size, ret, 3, "Authentication failed");
+ return 1;
+ }
+
+ if (!(*ticket)->ticket.flags.initial) {
+ krb5_warnx (context, "initial flag not set");
+ reply_error (server, s, sa, sa_size, ret, 1,
+ "Bad request");
+ goto out;
+ }
+ krb_priv_data.data = msg + 6 + ap_req_len;
+ krb_priv_data.length = len - 6 - ap_req_len;
+
+ ret = krb5_rd_priv (context,
+ *auth_context,
+ &krb_priv_data,
+ out_data,
+ NULL);
+
+ if (ret) {
+ krb5_warn (context, ret, "krb5_rd_priv");
+ reply_error (server, s, sa, sa_size, ret, 3, "Bad request");
+ goto out;
+ }
+ return 0;
+out:
+ krb5_free_ticket (context, *ticket);
+ return 1;
+}
+
+static void
+process (krb5_principal server,
+ krb5_keytab keytab,
+ int s,
+ krb5_address *this_addr,
+ struct sockaddr *sa,
+ int sa_size,
+ u_char *msg,
+ int len)
+{
+ krb5_error_code ret;
+ krb5_auth_context auth_context = NULL;
+ krb5_data out_data;
+ krb5_ticket *ticket;
+ krb5_address other_addr;
+
+ krb5_data_zero (&out_data);
+
+ ret = krb5_auth_con_init (context, &auth_context);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_auth_con_init");
+ return;
+ }
+
+ krb5_auth_con_setflags (context, auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+
+ ret = krb5_sockaddr2address (sa, &other_addr);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_sockaddr2address");
+ goto out;
+ }
+
+ ret = krb5_auth_con_setaddrs (context,
+ auth_context,
+ this_addr,
+ &other_addr);
+ krb5_free_address (context, &other_addr);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_auth_con_setaddr");
+ goto out;
+ }
+
+ if (verify (&auth_context, server, keytab, &ticket, &out_data,
+ s, sa, sa_size, msg, len) == 0) {
+ change (auth_context,
+ ticket->client,
+ s,
+ sa, sa_size,
+ &out_data);
+ krb5_free_ticket (context, ticket);
+ free (ticket);
+ }
+
+out:
+ krb5_data_free (&out_data);
+ krb5_auth_con_free (context, auth_context);
+}
+
+static int
+doit (krb5_keytab keytab,
+ int port)
+{
+ krb5_error_code ret;
+ krb5_principal server;
+ int *sockets;
+ int maxfd;
+ char *realm;
+ krb5_addresses addrs;
+ unsigned n, i;
+ fd_set real_fdset;
+ struct sockaddr_storage __ss;
+ struct sockaddr *sa = (struct sockaddr *)&__ss;
+
+ ret = krb5_get_default_realm (context, &realm);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_default_realm");
+
+ ret = krb5_build_principal (context,
+ &server,
+ strlen(realm),
+ realm,
+ "kadmin",
+ "changepw",
+ NULL);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_build_principal");
+
+ free (realm);
+
+ ret = krb5_get_all_server_addrs (context, &addrs);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_all_server_addrs");
+
+ n = addrs.len;
+
+ sockets = malloc (n * sizeof(*sockets));
+ if (sockets == NULL)
+ krb5_errx (context, 1, "out of memory");
+ maxfd = 0;
+ FD_ZERO(&real_fdset);
+ for (i = 0; i < n; ++i) {
+ int sa_size;
+
+ krb5_addr2sockaddr (&addrs.val[i], sa, &sa_size, port);
+
+
+ sockets[i] = socket (sa->sa_family, SOCK_DGRAM, 0);
+ if (sockets[i] < 0)
+ krb5_err (context, 1, errno, "socket");
+ if (bind (sockets[i], sa, sa_size) < 0) {
+ char str[128];
+ size_t len;
+ ret = krb5_print_address (&addrs.val[i], str, sizeof(str), &len);
+ krb5_err (context, 1, errno, "bind(%s)", str);
+ }
+ maxfd = max (maxfd, sockets[i]);
+ FD_SET(sockets[i], &real_fdset);
+ }
+
+ while(exit_flag == 0) {
+ int ret;
+ fd_set fdset = real_fdset;
+
+ ret = select (maxfd + 1, &fdset, NULL, NULL, NULL);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ krb5_err (context, 1, errno, "select");
+ }
+ for (i = 0; i < n; ++i)
+ if (FD_ISSET(sockets[i], &fdset)) {
+ u_char buf[BUFSIZ];
+ int addrlen = sizeof(__ss);
+
+ ret = recvfrom (sockets[i], buf, sizeof(buf), 0,
+ sa, &addrlen);
+ if (ret < 0) {
+ if(errno == EINTR)
+ break;
+ else
+ krb5_err (context, 1, errno, "recvfrom");
+ }
+
+ process (server, keytab, sockets[i],
+ &addrs.val[i],
+ sa, addrlen,
+ buf, ret);
+ }
+ }
+ krb5_free_addresses (context, &addrs);
+ krb5_free_principal (context, server);
+ krb5_free_context (context);
+ return 0;
+}
+
+static RETSIGTYPE
+sigterm(int sig)
+{
+ exit_flag = 1;
+}
+
+const char *check_library = NULL;
+const char *check_function = NULL;
+char *keytab_str = "HDB:";
+char *realm_str;
+int version_flag;
+int help_flag;
+
+struct getargs args[] = {
+#ifdef HAVE_DLOPEN
+ { "check-library", 0, arg_string, &check_library,
+ "library to load password check function from", "library" },
+ { "check-function", 0, arg_string, &check_function,
+ "password check function to load", "function" },
+#endif
+ { "keytab", 'k', arg_string, &keytab_str,
+ "keytab to get authentication key from", "kspec" },
+ { "realm", 'r', arg_string, &realm_str, "default realm", "realm" },
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+int num_args = sizeof(args) / sizeof(args[0]);
+
+int
+main (int argc, char **argv)
+{
+ int optind;
+ krb5_keytab keytab;
+ krb5_error_code ret;
+
+ optind = krb5_program_setup(&context, argc, argv, args, num_args, NULL);
+
+ if(help_flag)
+ krb5_std_usage(0, args, num_args);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ if(realm_str)
+ krb5_set_default_realm(context, realm_str);
+
+ krb5_openlog (context, "kpasswdd", &log_facility);
+ krb5_set_warn_dest(context, log_facility);
+
+ ret = krb5_kt_register(context, &hdb_kt_ops);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_kt_register");
+
+ ret = krb5_kt_resolve(context, keytab_str, &keytab);
+ if(ret)
+ krb5_err(context, 1, ret, "%s", keytab_str);
+
+ kadm5_setup_passwd_quality_check (context, check_library, check_function);
+
+#ifdef HAVE_SIGACTION
+ {
+ struct sigaction sa;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = sigterm;
+ sigemptyset(&sa.sa_mask);
+
+ sigaction(SIGINT, &sa, NULL);
+ }
+#else
+ signal(SIGINT, sigterm);
+#endif
+
+ return doit (keytab,
+ krb5_getportbyname (context, "kpasswd",
+ "udp", KPASSWD_PORT));
+}
diff --git a/crypto/heimdal/krb5.conf b/crypto/heimdal/krb5.conf
new file mode 100644
index 000000000000..c9f4c44a5e4f
--- /dev/null
+++ b/crypto/heimdal/krb5.conf
@@ -0,0 +1,26 @@
+[libdefaults]
+ default_realm = MY.REALM
+ clockskew = 300
+ v4_instance_resolve = false
+ v4_name_convert = {
+ host = {
+ rcmd = host
+ ftp = ftp
+ }
+ plain = {
+ something = something-else
+ }
+ }
+
+[realms]
+ MY.REALM = {
+ kdc = MY.COMPUTER
+ }
+ OTHER.REALM = {
+ v4_instance_convert = {
+ kerberos = kerberos
+ computer = computer.some.other.domain
+ }
+ }
+[domain_realm]
+ .my.domain = MY.REALM
diff --git a/crypto/heimdal/kuser/Makefile.am b/crypto/heimdal/kuser/Makefile.am
new file mode 100644
index 000000000000..4faed9a79ca1
--- /dev/null
+++ b/crypto/heimdal/kuser/Makefile.am
@@ -0,0 +1,37 @@
+# $Id: Makefile.am,v 1.25 1999/09/21 05:12:29 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+man_MANS = kinit.1 klist.1 kdestroy.1 kgetcred.1
+
+bin_PROGRAMS = kinit kauth klist kdestroy kgetcred
+
+kinit_SOURCES = kinit.c kinit_options.c
+
+kauth_SOURCES = kinit.c kauth_options.c
+
+noinst_PROGRAMS = kverify kdecode_ticket
+
+CHECK_LOCAL = $(bin_PROGRAMS)
+
+kauth_LDADD = \
+ $(LIB_kafs) \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
+
+kinit_LDADD = $(kauth_LDADD)
+
+kdestroy_LDADD = $(kauth_LDADD)
+
+klist_LDADD = $(kauth_LDADD)
+
+LDADD = \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
diff --git a/crypto/heimdal/kuser/Makefile.in b/crypto/heimdal/kuser/Makefile.in
new file mode 100644
index 000000000000..06ec47166f83
--- /dev/null
+++ b/crypto/heimdal/kuser/Makefile.in
@@ -0,0 +1,777 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.25 1999/09/21 05:12:29 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(bin_PROGRAMS)
+
+man_MANS = kinit.1 klist.1 kdestroy.1 kgetcred.1
+
+bin_PROGRAMS = kinit kauth klist kdestroy kgetcred
+
+kinit_SOURCES = kinit.c kinit_options.c
+
+kauth_SOURCES = kinit.c kauth_options.c
+
+noinst_PROGRAMS = kverify kdecode_ticket
+
+kauth_LDADD = $(LIB_kafs) $(top_builddir)/lib/krb5/libkrb5.la $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken)
+
+
+kinit_LDADD = $(kauth_LDADD)
+
+kdestroy_LDADD = $(kauth_LDADD)
+
+klist_LDADD = $(kauth_LDADD)
+
+LDADD = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = kinit$(EXEEXT) kauth$(EXEEXT) klist$(EXEEXT) \
+kdestroy$(EXEEXT) kgetcred$(EXEEXT)
+noinst_PROGRAMS = kverify$(EXEEXT) kdecode_ticket$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+kinit_OBJECTS = kinit.$(OBJEXT) kinit_options.$(OBJEXT)
+@KRB4_TRUE@kinit_DEPENDENCIES = $(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@kinit_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+kinit_LDFLAGS =
+kauth_OBJECTS = kinit.$(OBJEXT) kauth_options.$(OBJEXT)
+@KRB4_TRUE@kauth_DEPENDENCIES = $(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@kauth_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+kauth_LDFLAGS =
+klist_SOURCES = klist.c
+klist_OBJECTS = klist.$(OBJEXT)
+@KRB4_TRUE@klist_DEPENDENCIES = $(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@klist_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+klist_LDFLAGS =
+kdestroy_SOURCES = kdestroy.c
+kdestroy_OBJECTS = kdestroy.$(OBJEXT)
+@KRB4_TRUE@kdestroy_DEPENDENCIES = $(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@kdestroy_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+kdestroy_LDFLAGS =
+kgetcred_SOURCES = kgetcred.c
+kgetcred_OBJECTS = kgetcred.$(OBJEXT)
+kgetcred_LDADD = $(LDADD)
+kgetcred_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+kgetcred_LDFLAGS =
+kverify_SOURCES = kverify.c
+kverify_OBJECTS = kverify.$(OBJEXT)
+kverify_LDADD = $(LDADD)
+kverify_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+kverify_LDFLAGS =
+kdecode_ticket_SOURCES = kdecode_ticket.c
+kdecode_ticket_OBJECTS = kdecode_ticket.$(OBJEXT)
+kdecode_ticket_LDADD = $(LDADD)
+kdecode_ticket_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la
+kdecode_ticket_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man1dir = $(mandir)/man1
+MANS = $(man_MANS)
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(kinit_SOURCES) $(kauth_SOURCES) klist.c kdestroy.c kgetcred.c kverify.c kdecode_ticket.c
+OBJECTS = $(kinit_OBJECTS) $(kauth_OBJECTS) klist.$(OBJEXT) kdestroy.$(OBJEXT) kgetcred.$(OBJEXT) kverify.$(OBJEXT) kdecode_ticket.$(OBJEXT)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign kuser/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+kinit$(EXEEXT): $(kinit_OBJECTS) $(kinit_DEPENDENCIES)
+ @rm -f kinit$(EXEEXT)
+ $(LINK) $(kinit_LDFLAGS) $(kinit_OBJECTS) $(kinit_LDADD) $(LIBS)
+
+kauth$(EXEEXT): $(kauth_OBJECTS) $(kauth_DEPENDENCIES)
+ @rm -f kauth$(EXEEXT)
+ $(LINK) $(kauth_LDFLAGS) $(kauth_OBJECTS) $(kauth_LDADD) $(LIBS)
+
+klist$(EXEEXT): $(klist_OBJECTS) $(klist_DEPENDENCIES)
+ @rm -f klist$(EXEEXT)
+ $(LINK) $(klist_LDFLAGS) $(klist_OBJECTS) $(klist_LDADD) $(LIBS)
+
+kdestroy$(EXEEXT): $(kdestroy_OBJECTS) $(kdestroy_DEPENDENCIES)
+ @rm -f kdestroy$(EXEEXT)
+ $(LINK) $(kdestroy_LDFLAGS) $(kdestroy_OBJECTS) $(kdestroy_LDADD) $(LIBS)
+
+kgetcred$(EXEEXT): $(kgetcred_OBJECTS) $(kgetcred_DEPENDENCIES)
+ @rm -f kgetcred$(EXEEXT)
+ $(LINK) $(kgetcred_LDFLAGS) $(kgetcred_OBJECTS) $(kgetcred_LDADD) $(LIBS)
+
+kverify$(EXEEXT): $(kverify_OBJECTS) $(kverify_DEPENDENCIES)
+ @rm -f kverify$(EXEEXT)
+ $(LINK) $(kverify_LDFLAGS) $(kverify_OBJECTS) $(kverify_LDADD) $(LIBS)
+
+kdecode_ticket$(EXEEXT): $(kdecode_ticket_OBJECTS) $(kdecode_ticket_DEPENDENCIES)
+ @rm -f kdecode_ticket$(EXEEXT)
+ $(LINK) $(kdecode_ticket_LDFLAGS) $(kdecode_ticket_OBJECTS) $(kdecode_ticket_LDADD) $(LIBS)
+
+install-man1:
+ $(mkinstalldirs) $(DESTDIR)$(man1dir)
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
+ done
+
+uninstall-man1:
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man1dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man1
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man1
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = kuser
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-man install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS uninstall-man
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(MANS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-noinstPROGRAMS clean-compile \
+ clean-libtool clean-tags clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-noinstPROGRAMS \
+ distclean-compile distclean-libtool distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-noinstPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool install-man1 uninstall-man1 \
+install-man uninstall-man tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-local install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/kuser/kauth_options.c b/crypto/heimdal/kuser/kauth_options.c
new file mode 100644
index 000000000000..c432d32ac14a
--- /dev/null
+++ b/crypto/heimdal/kuser/kauth_options.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kuser_locl.h"
+RCSID("$Id: kauth_options.c,v 1.2 1999/12/02 17:05:00 joda Exp $");
+
+#ifdef KRB4
+int do_afslog = 1;
+int get_v4_tgt = 1;
+#endif
diff --git a/crypto/heimdal/kuser/kdecode_ticket.c b/crypto/heimdal/kuser/kdecode_ticket.c
new file mode 100644
index 000000000000..dd365dcb7852
--- /dev/null
+++ b/crypto/heimdal/kuser/kdecode_ticket.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kuser_locl.h"
+
+RCSID("$Id: kdecode_ticket.c,v 1.2 1999/12/02 17:05:00 joda Exp $");
+
+static char *etype_str;
+static int version_flag;
+static int help_flag;
+
+static void
+print_and_decode_tkt (krb5_context context,
+ krb5_data *ticket,
+ krb5_principal server,
+ krb5_enctype enctype)
+{
+ krb5_error_code ret;
+ krb5_crypto crypto;
+ krb5_data dec_data;
+ size_t len;
+ EncTicketPart decr_part;
+ krb5_keyblock key;
+ Ticket tkt;
+
+ ret = decode_Ticket (ticket->data, ticket->length, &tkt, &len);
+ if (ret)
+ krb5_err (context, 1, ret, "decode_Ticket");
+
+ ret = krb5_string_to_key (context, enctype, "foo", server, &key);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_string_to_key");
+
+ krb5_crypto_init(context, &key, 0, &crypto);
+
+ ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET,
+ &tkt.enc_part, &dec_data);
+ krb5_crypto_destroy (context, crypto);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_decrypt_EncryptedData");
+ ret = krb5_decode_EncTicketPart (context, dec_data.data, dec_data.length,
+ &decr_part, &len);
+ krb5_data_free (&dec_data);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_decode_EncTicketPart");
+}
+
+struct getargs args[] = {
+ { "enctype", 'e', arg_string, &etype_str,
+ "encryption type to use", "enctype"},
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "service");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache cache;
+ krb5_creds in, *out;
+ int optind = 0;
+
+ set_progname (argv[0]);
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx(1, "krb5_init_context failed: %u", ret);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ usage (1);
+
+ ret = krb5_cc_default(context, &cache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_default");
+
+ memset(&in, 0, sizeof(in));
+
+ if (etype_str) {
+ krb5_enctype enctype;
+
+ ret = krb5_string_to_enctype(context, etype_str, &enctype);
+ if (ret)
+ krb5_errx (context, 1, "unrecognized enctype: %s", etype_str);
+ in.session.keytype = enctype;
+ }
+
+ ret = krb5_cc_get_principal(context, cache, &in.client);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_get_principal");
+
+ ret = krb5_parse_name(context, argv[0], &in.server);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name %s", argv[0]);
+
+ in.times.endtime = 0;
+ ret = krb5_get_credentials(context, 0, cache, &in, &out);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_credentials");
+
+ print_and_decode_tkt (context, &out->ticket, out->server,
+ out->session.keytype);
+
+ krb5_free_creds_contents(context, out);
+ return 0;
+}
diff --git a/crypto/heimdal/kuser/kdestroy.1 b/crypto/heimdal/kuser/kdestroy.1
new file mode 100644
index 000000000000..18c5320befc6
--- /dev/null
+++ b/crypto/heimdal/kuser/kdestroy.1
@@ -0,0 +1,34 @@
+.\" $Id: kdestroy.1,v 1.2 1999/05/14 14:05:40 assar Exp $
+.\"
+.Dd Aug 27, 1997
+.Dt KDESTROY 1
+.Os HEIMDAL
+.Sh NAME
+.Nm kdestroy
+.Nd
+destroy the current ticket file
+.Sh SYNOPSIS
+.Nm
+.Op Fl c Ar cachefile
+.Op Fl -cache= Ns Ar cachefile
+.Op Fl -no-unlog
+.Op Fl -no-delete-v4
+.Op Fl -version
+.Op Fl -help
+.Sh DESCRIPTION
+.Nm
+remove the current set of tickets.
+.Pp
+Supported options:
+.Bl -tag -width Ds
+.It Fl c Ar cachefile
+.It Fl cache= Ns Ar cachefile
+The cache file to remove.
+.It Fl -no-unlog
+Do not remove AFS tokens.
+.It Fl -no-delete-v4
+Do not remove v4 tickets.
+.El
+.Sh SEE ALSO
+.Xr kinit 1 ,
+.Xr klist 1
diff --git a/crypto/heimdal/kuser/kdestroy.c b/crypto/heimdal/kuser/kdestroy.c
new file mode 100644
index 000000000000..632d02ea62eb
--- /dev/null
+++ b/crypto/heimdal/kuser/kdestroy.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kuser_locl.h"
+RCSID("$Id: kdestroy.c,v 1.11 1999/12/02 17:05:01 joda Exp $");
+
+static const char *cache;
+static int help_flag;
+static int version_flag;
+static int unlog_flag = 1;
+static int dest_tkt_flag = 1;
+
+struct getargs args[] = {
+ { "cache", 'c', arg_string, &cache, "cache to destroy", "cache" },
+ { "unlog", 0, arg_negative_flag, &unlog_flag,
+ "do not destroy tokens", NULL },
+ { "delete-v4", 0, arg_negative_flag, &dest_tkt_flag,
+ "do not destroy v4 tickets", NULL },
+ { "version", 0, arg_flag, &version_flag, NULL, NULL },
+ { "help", 'h', arg_flag, &help_flag, NULL, NULL}
+};
+
+int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage (int status)
+{
+ arg_printusage (args, num_args, NULL, "");
+ exit (status);
+}
+
+int
+main (int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache ccache;
+ int optind = 0;
+ int exit_val = 0;
+
+ set_progname (argv[0]);
+
+ if(getarg(args, num_args, argc, argv, &optind))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage (1);
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx (1, "krb5_init_context: %s", krb5_get_err_text(context, ret));
+
+ if(cache == NULL)
+ cache = krb5_cc_default_name(context);
+
+ ret = krb5_cc_resolve(context,
+ cache,
+ &ccache);
+
+ if (ret == 0) {
+ ret = krb5_cc_destroy (context, ccache);
+ if (ret) {
+ warnx ("krb5_cc_destroy: %s", krb5_get_err_text(context, ret));
+ exit_val = 1;
+ }
+ } else {
+ warnx ("krb5_cc_resolve(%s): %s", cache,
+ krb5_get_err_text(context, ret));
+ exit_val = 1;
+ }
+
+ krb5_free_context (context);
+
+#if KRB4
+ if(dest_tkt_flag && dest_tkt ())
+ exit_val = 1;
+ if (unlog_flag && k_hasafs ()) {
+ if (k_unlog ())
+ exit_val = 1;
+ }
+#endif
+
+ return exit_val;
+}
diff --git a/crypto/heimdal/kuser/kgetcred.1 b/crypto/heimdal/kuser/kgetcred.1
new file mode 100644
index 000000000000..0dbbbff94d20
--- /dev/null
+++ b/crypto/heimdal/kuser/kgetcred.1
@@ -0,0 +1,41 @@
+.\" $Id: kgetcred.1,v 1.2 1999/05/13 22:26:35 assar Exp $
+.\"
+.Dd May 14, 1999
+.Dt KGETCRED 1
+.Os HEIMDAL
+.Sh NAME
+.Nm kgetcred
+.Nd
+get a ticket for a particular service
+.Sh SYNOPSIS
+.Nm
+.Oo Fl e Ar enctype \*(Ba Xo
+.Fl -enctype= Ns Ar enctype Oc
+.Xc
+.Op Fl -version
+.Op Fl -help
+.Ar service
+.Sh DESCRIPTION
+.Nm
+obtains a ticket for a service.
+Usually tickets for services are obtained automatically when needed
+but sometimes for some odd reason you want to obtain a particular
+ticket or of a special type.
+.Pp
+Supported options:
+.Bl -tag -width Ds
+.It Xo
+.Fl e Ar enctype Ns ,
+.Fl -enctype= Ns Ar enctype
+.Xc
+encryption type to use
+.It Xo
+.Fl -version
+.Xc
+.It Xo
+.Fl -help
+.Xc
+.El
+.Sh SEE ALSO
+.Xr kinit 1 ,
+.Xr klist 1
diff --git a/crypto/heimdal/kuser/kgetcred.c b/crypto/heimdal/kuser/kgetcred.c
new file mode 100644
index 000000000000..644e69e83a7a
--- /dev/null
+++ b/crypto/heimdal/kuser/kgetcred.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kuser_locl.h"
+
+RCSID("$Id: kgetcred.c,v 1.3 1999/12/02 17:05:01 joda Exp $");
+
+static char *etype_str;
+static int version_flag;
+static int help_flag;
+
+struct getargs args[] = {
+ { "enctype", 'e', arg_string, &etype_str,
+ "encryption type to use", "enctype"},
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "service");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache cache;
+ krb5_creds in, *out;
+ int optind = 0;
+
+ set_progname (argv[0]);
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx(1, "krb5_init_context failed: %u", ret);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ usage (1);
+
+ ret = krb5_cc_default(context, &cache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_default");
+
+ memset(&in, 0, sizeof(in));
+
+ if (etype_str) {
+ krb5_enctype enctype;
+
+ ret = krb5_string_to_enctype(context, etype_str, &enctype);
+ if (ret)
+ krb5_errx (context, 1, "unrecognized enctype: %s", etype_str);
+ in.session.keytype = enctype;
+ }
+
+ ret = krb5_cc_get_principal(context, cache, &in.client);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_get_principal");
+
+ ret = krb5_parse_name(context, argv[0], &in.server);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name %s", argv[0]);
+
+ in.times.endtime = 0;
+ ret = krb5_get_credentials(context, 0, cache, &in, &out);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_credentials");
+
+ krb5_free_creds_contents(context, out);
+ return 0;
+}
diff --git a/crypto/heimdal/kuser/kinit.1 b/crypto/heimdal/kuser/kinit.1
new file mode 100644
index 000000000000..d779365b7574
--- /dev/null
+++ b/crypto/heimdal/kuser/kinit.1
@@ -0,0 +1,175 @@
+.\" $Id: kinit.1,v 1.3 1999/05/14 14:02:49 assar Exp $
+.\"
+.Dd May 29, 1998
+.Dt KAUTH 1
+.Os HEIMDAL
+.Sh NAME
+.Nm kauth
+.Nd
+acquire initial tickets
+.Sh SYNOPSIS
+.Nm
+.Op Fl 4
+.Op Fl -524init
+.Op Fl -afslog
+.Op Fl c Ar cachename
+.Op Fl -cache= Ns Ar cachename
+.Op Fl c Ar cachename
+.Op Fl -cache= Ns Ar cachename
+.Op Fl f
+.Op Fl -forwardable
+.Op Fl t Ar keytabname
+.Op Fl -keytab= Ns Ar keytabname
+.Op Fl l Ar seconds
+.Op Fl -lifetime= Ns Ar seconds
+.Op Fl p
+.Op Fl -proxiable
+.Op Fl R
+.Op Fl -renew
+.Op Fl -renewable
+.Op Fl r Ar seconds
+.Op Fl -renewable-life= Ns Ar seconds
+.Op Fl S Ar principal
+.Op Fl -server= Ns Ar principal
+.Op Fl s Ar seconds
+.Op Fl -start-time= Ns Ar seconds
+.Op Fl k
+.Op Fl -use-keytab
+.Op Fl v
+.Op Fl -validate
+.Op Fl e
+.Op Fl -enctypes= Ns Ar enctypes
+.Op Fl -fcache-version= Ns Ar version
+.Op Fl -noaddresses
+.Op Fl -version
+.Op Fl -help
+.Op Ar principal
+.Sh DESCRIPTION
+.Nm
+is used to authenticate to the kerberos server as
+.Ar principal ,
+or if none is given, a system generated default, and acquire a ticket
+granting ticket that can later be used to obtain tickets for other
+services.
+Supported options:
+.Bl -tag -width Ds
+.It Xo
+.Fl c Ar cachename
+.Fl -cache= Ns Ar cachename
+.Xc
+The credentials cache to put the acquired ticket in, if other than
+default.
+.It Xo
+.Fl f Ns ,
+.Fl -forwardable
+.Xc
+Get ticket that can be forwarded to another host.
+.It Xo
+.Fl t Ar keytabname Ns ,
+.Fl -keytab= Ns Ar keytabname
+.Xc
+Don't ask for a password, but instead get the key from the specified
+keytab.
+.It Xo
+.Fl l Ar seconds Ns ,
+.Fl -lifetime= Ns Ar seconds
+.Xc
+Specifies the lifetime of the ticket.
+.It Xo
+.Fl p Ns ,
+.Fl -proxiable
+.Xc
+Request tickets with the proxiable flag set.
+.It Xo
+.Fl R Ns ,
+.Fl -renew
+.Xc
+Try to renew ticket. The ticket must have the
+.Sq renewable
+flag set, and must not be expired.
+.It Fl -renewable
+The same as
+.Fl -renewable-life ,
+with an infinite time.
+.It Xo
+.Fl r Ar seconds Ns ,
+.Fl -renewable-life= Ns Ar seconds
+.Xc
+The max renewable ticket life.
+.It Xo
+.Fl S Ar principal Ns ,
+.Fl -server= Ns Ar principal
+.Xc
+Get a ticket for a service other than krbtgt/LOCAL.REALM.
+.It Xo
+.Fl s Ar seconds Ns ,
+.Fl -start-time= Ns Ar seconds
+.Xc
+Start time of ticket, if other than the current time.
+.It Xo
+.Fl k Ns ,
+.Fl -use-keytab
+.Xc
+The same as
+.Fl -keytab ,
+but with the default keytab name (normally
+.Ar FILE:/etc/krb5.keytab ) .
+.It Xo
+.Fl v Ns ,
+.Fl -validate
+.Xc
+Try to validate an invalid ticket.
+.It Xo
+.Fl e ,
+.Fl -enctypes= Ns Ar enctypes
+.Xc
+Request tickets with this particular enctype.
+.It Xo
+.Fl -fcache-version= Ns Ar version
+.Xc
+Create a credentials cache of version
+.Nm version .
+.It Xo
+.Fl -noaddresses
+.Xc
+Request a ticket with no addresses.
+.El
+
+The following options are only available if
+.Nm
+has been compiled with support for Kerberos 4.
+.Bl -tag -width Ds
+.It Xo
+.Fl 4 Ns ,
+.Fl -524init
+.Xc
+Try to convert the obtained krbtgt to a version 4 compatible
+ticket. It will store this ticket in the default Kerberos 4 ticket
+file.
+.It Fl -afslog
+Gets AFS tickets, converts them to version 4 format, and stores them
+in the kernel. Only useful if you have AFS.
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width Ds
+.It Ev KRB5CCNAME
+Specifies the default cache file.
+.It Ev KRB5_CONFIG
+The directory where the
+.Pa krb5.conf
+can be found, default is
+.Pa /etc .
+.It Ev KRBTKFILE
+Specifies the Kerberos 4 ticket file to store version 4 tickets in.
+.El
+.\".Sh FILES
+.\".Sh EXAMPLES
+.\".Sh DIAGNOSTICS
+.Sh SEE ALSO
+.Xr krb5.conf 5 ,
+.Xr klist 1 ,
+.Xr kdestroy 1
+.\".Sh STANDARDS
+.\".Sh HISTORY
+.\".Sh AUTHORS
+.\".Sh BUGS
diff --git a/crypto/heimdal/kuser/kinit.c b/crypto/heimdal/kuser/kinit.c
new file mode 100644
index 000000000000..328a334d2652
--- /dev/null
+++ b/crypto/heimdal/kuser/kinit.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kuser_locl.h"
+RCSID("$Id: kinit.c,v 1.59 1999/12/02 17:05:01 joda Exp $");
+
+int forwardable = 0;
+int proxiable = 0;
+int renewable = 0;
+int renew_flag = 0;
+int validate_flag = 0;
+int version_flag = 0;
+int help_flag = 0;
+int no_addrs_flag = 0;
+char *lifetime = NULL;
+char *renew_life = NULL;
+char *server = NULL;
+char *cred_cache = NULL;
+char *start_str = NULL;
+struct getarg_strings etype_str;
+int use_keytab = 0;
+char *keytab_str = NULL;
+#ifdef KRB4
+extern int do_afslog;
+extern int get_v4_tgt;
+#endif
+int fcache_version;
+
+struct getargs args[] = {
+#ifdef KRB4
+ { "524init", '4', arg_flag, &get_v4_tgt,
+ "obtain version 4 TGT" },
+
+ { "afslog", 0 , arg_flag, &do_afslog,
+ "obtain afs tokens" },
+#endif
+ { "cache", 'c', arg_string, &cred_cache,
+ "credentials cache", "cachename" },
+
+ { "forwardable", 'f', arg_flag, &forwardable,
+ "get forwardable tickets"},
+
+ { "keytab", 't', arg_string, &keytab_str,
+ "keytab to use", "keytabname" },
+
+ { "lifetime", 'l', arg_string, &lifetime,
+ "lifetime of tickets", "seconds"},
+
+ { "proxiable", 'p', arg_flag, &proxiable,
+ "get proxiable tickets" },
+
+ { "renew", 'R', arg_flag, &renew_flag,
+ "renew TGT" },
+
+ { "renewable", 0, arg_flag, &renewable,
+ "get renewable tickets" },
+
+ { "renewable-life", 'r', arg_string, &renew_life,
+ "renewable lifetime of tickets", "seconds" },
+
+ { "server", 'S', arg_string, &server,
+ "server to get ticket for", "principal" },
+
+ { "start-time", 's', arg_string, &start_str,
+ "when ticket gets valid", "seconds" },
+
+ { "use-keytab", 'k', arg_flag, &use_keytab,
+ "get key from keytab" },
+
+ { "validate", 'v', arg_flag, &validate_flag,
+ "validate TGT" },
+
+ { "enctypes", 'e', arg_strings, &etype_str,
+ "encryption type to use", "enctype" },
+
+ { "fcache-version", 0, arg_integer, &fcache_version,
+ "file cache version to create" },
+
+ { "noaddresses", 0, arg_flag, &no_addrs_flag,
+ "request a ticket with no addresses" },
+
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "[principal]");
+ exit (ret);
+}
+
+static int
+renew_validate(krb5_context context,
+ int renew,
+ int validate,
+ krb5_ccache cache,
+ const char *server,
+ krb5_deltat life)
+{
+ krb5_error_code ret;
+ krb5_creds in, *out;
+ krb5_kdc_flags flags;
+
+ memset(&in, 0, sizeof(in));
+
+ ret = krb5_cc_get_principal(context, cache, &in.client);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_cc_get_principal");
+ return ret;
+ }
+ if(server) {
+ ret = krb5_parse_name(context, server, &in.server);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_parse_name");
+ goto out;
+ }
+ } else {
+ krb5_realm *client_realm = krb5_princ_realm (context, in.client);
+
+ ret = krb5_make_principal(context, &in.server, *client_realm,
+ KRB5_TGS_NAME, *client_realm, NULL);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_make_principal");
+ goto out;
+ }
+ }
+ flags.i = 0;
+ flags.b.renewable = flags.b.renew = renew;
+ flags.b.validate = validate;
+ flags.b.forwardable = forwardable;
+ flags.b.proxiable = proxiable;
+ if(life)
+ in.times.endtime = time(NULL) + life;
+
+ ret = krb5_get_kdc_cred(context,
+ cache,
+ flags,
+ NULL,
+ NULL,
+ &in,
+ &out);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_get_kdc_cred");
+ goto out;
+ }
+ ret = krb5_cc_initialize(context, cache, in.client);
+ if(ret) {
+ krb5_free_creds (context, out);
+ krb5_warn(context, ret, "krb5_cc_initialize");
+ goto out;
+ }
+ ret = krb5_cc_store_cred(context, cache, out);
+ krb5_free_creds (context, out);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_cc_store_cred");
+ goto out;
+ }
+out:
+ krb5_free_creds_contents(context, &in);
+ return ret;
+}
+
+int
+main (int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache ccache;
+ krb5_principal principal;
+ krb5_creds cred;
+ int optind = 0;
+ krb5_get_init_creds_opt opt;
+ krb5_deltat start_time = 0;
+ krb5_deltat ticket_life = 0;
+ krb5_addresses no_addrs;
+
+ set_progname (argv[0]);
+ memset(&cred, 0, sizeof(cred));
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx(1, "krb5_init_context failed: %u", ret);
+
+ forwardable = krb5_config_get_bool (context, NULL,
+ "libdefaults",
+ "forwardable",
+ NULL);
+
+#ifdef KRB4
+ get_v4_tgt = krb5_config_get_bool_default (context, NULL,
+ get_v4_tgt,
+ "libdefaults",
+ "krb4_get_tickets",
+ NULL);
+#endif
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ if(fcache_version)
+ krb5_set_fcache_version(context, fcache_version);
+
+ if(cred_cache)
+ ret = krb5_cc_resolve(context, cred_cache, &ccache);
+ else
+ ret = krb5_cc_default (context, &ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "resolving credentials cache");
+
+ if (lifetime) {
+ int tmp = parse_time (lifetime, "s");
+ if (tmp < 0)
+ errx (1, "unparsable time: %s", lifetime);
+
+ ticket_life = tmp;
+ }
+ if(renew_flag || validate_flag) {
+ ret = renew_validate(context, renew_flag, validate_flag,
+ ccache, server, ticket_life);
+ exit(ret != 0);
+ }
+
+ krb5_get_init_creds_opt_init (&opt);
+
+ krb5_get_init_creds_opt_set_forwardable (&opt, forwardable);
+ krb5_get_init_creds_opt_set_proxiable (&opt, proxiable);
+
+ if (no_addrs_flag) {
+ no_addrs.len = 0;
+ no_addrs.val = NULL;
+
+ krb5_get_init_creds_opt_set_address_list (&opt, &no_addrs);
+ }
+
+ if(renew_life) {
+ int tmp = parse_time (renew_life, "s");
+ if (tmp < 0)
+ errx (1, "unparsable time: %s", renew_life);
+
+ krb5_get_init_creds_opt_set_renew_life (&opt, tmp);
+ } else if (renewable)
+ krb5_get_init_creds_opt_set_renew_life (&opt, 1 << 30);
+
+ if(ticket_life != 0)
+ krb5_get_init_creds_opt_set_tkt_life (&opt, ticket_life);
+
+ if(start_str) {
+ int tmp = parse_time (start_str, "s");
+ if (tmp < 0)
+ errx (1, "unparsable time: %s", start_str);
+
+ start_time = tmp;
+ }
+
+ if(etype_str.num_strings) {
+ krb5_enctype *enctype = NULL;
+ int i;
+ enctype = malloc(etype_str.num_strings * sizeof(*enctype));
+ if(enctype == NULL)
+ errx(1, "out of memory");
+ for(i = 0; i < etype_str.num_strings; i++) {
+ ret = krb5_string_to_enctype(context,
+ etype_str.strings[i],
+ &enctype[i]);
+ if(ret)
+ errx(1, "unrecognized enctype: %s", etype_str.strings[i]);
+ }
+ krb5_get_init_creds_opt_set_etype_list(&opt, enctype,
+ etype_str.num_strings);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 1)
+ usage (1);
+
+ if (argv[0]) {
+ ret = krb5_parse_name (context, argv[0], &principal);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name");
+ } else
+ principal = NULL;
+
+ if(use_keytab || keytab_str) {
+ krb5_keytab kt;
+ if(keytab_str)
+ ret = krb5_kt_resolve(context, keytab_str, &kt);
+ else
+ ret = krb5_kt_default(context, &kt);
+ if (ret)
+ krb5_err (context, 1, ret, "resolving keytab");
+ ret = krb5_get_init_creds_keytab (context,
+ &cred,
+ principal,
+ kt,
+ start_time,
+ server,
+ &opt);
+ krb5_kt_close(context, kt);
+ } else
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ principal,
+ NULL,
+ krb5_prompter_posix,
+ NULL,
+ start_time,
+ server,
+ &opt);
+ switch(ret){
+ case 0:
+ break;
+ case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */
+ exit(1);
+ case KRB5KRB_AP_ERR_BAD_INTEGRITY:
+ case KRB5KRB_AP_ERR_MODIFIED:
+ krb5_errx(context, 1, "Password incorrect");
+ break;
+ default:
+ krb5_err(context, 1, ret, "krb5_get_init_creds");
+ }
+
+ ret = krb5_cc_initialize (context, ccache, cred.client);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_initialize");
+
+ ret = krb5_cc_store_cred (context, ccache, &cred);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_store_cred");
+
+#ifdef KRB4
+ if(get_v4_tgt) {
+ CREDENTIALS c;
+ ret = krb524_convert_creds_kdc(context, ccache, &cred, &c);
+ if(ret)
+ krb5_warn(context, ret, "converting creds");
+ else
+ tf_setup(&c, c.pname, c.pinst);
+ memset(&c, 0, sizeof(c));
+ }
+ if(do_afslog && k_hasafs())
+ krb5_afslog(context, ccache, NULL, NULL);
+#endif
+ krb5_free_creds_contents (context, &cred);
+ krb5_cc_close (context, ccache);
+ krb5_free_context (context);
+ return 0;
+}
diff --git a/crypto/heimdal/kuser/kinit_options.c b/crypto/heimdal/kuser/kinit_options.c
new file mode 100644
index 000000000000..5a7dcd98753d
--- /dev/null
+++ b/crypto/heimdal/kuser/kinit_options.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kuser_locl.h"
+RCSID("$Id: kinit_options.c,v 1.2 1999/12/02 17:05:01 joda Exp $");
+
+#ifdef KRB4
+int do_afslog = 0;
+int get_v4_tgt = 0;
+#endif
diff --git a/crypto/heimdal/kuser/klist.1 b/crypto/heimdal/kuser/klist.1
new file mode 100644
index 000000000000..e875401264f8
--- /dev/null
+++ b/crypto/heimdal/kuser/klist.1
@@ -0,0 +1,37 @@
+.\" $Id: klist.1,v 1.4 1999/05/14 14:03:55 assar Exp $
+.\"
+.Dd Aug 27, 1997
+.Dt KLIST 1
+.Os HEIMDAL
+.Sh NAME
+.Nm klist
+.Nd
+list the current tickets
+.Sh SYNOPSIS
+.Nm
+.Op Fl t | Fl -test
+.Op Fl v | Fl -verbose
+.Op Fl -version
+.Op Fl -help
+.Sh DESCRIPTION
+.Nm
+reads and displays the current tickets in the crential cache (also
+knows as the ticket file).
+.Pp
+Options supported:
+.Bl -tag -width Ds
+.It Xo
+.Fl t Ns ,
+.Fl -test
+.Xc
+Test for there being an active and valid TGT for the local realm of
+the user in the credential cache.
+.It Xo
+.Fl v Ns ,
+.Fl -verbose
+.Xc
+Verbose output. Include all information from tickets.
+.El
+.Sh SEE ALSO
+.Xr kinit 1 ,
+.Xr kdestroy 1
diff --git a/crypto/heimdal/kuser/klist.c b/crypto/heimdal/kuser/klist.c
new file mode 100644
index 000000000000..9135d293895f
--- /dev/null
+++ b/crypto/heimdal/kuser/klist.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kuser_locl.h"
+
+RCSID("$Id: klist.c,v 1.52 1999/12/02 17:05:01 joda Exp $");
+
+static char*
+printable_time(time_t t)
+{
+ static char s[128];
+ strcpy(s, ctime(&t)+ 4);
+ s[15] = 0;
+ return s;
+}
+
+static char*
+printable_time_long(time_t t)
+{
+ static char s[128];
+ strcpy(s, ctime(&t)+ 4);
+ s[20] = 0;
+ return s;
+}
+
+static void
+print_cred(krb5_context context, krb5_creds *cred)
+{
+ char *str;
+ krb5_error_code ret;
+ int32_t sec;
+
+ krb5_timeofday (context, &sec);
+
+ if(cred->times.starttime)
+ printf ("%s ", printable_time(cred->times.starttime));
+ else
+ printf ("%s ", printable_time(cred->times.authtime));
+
+ if(cred->times.endtime > sec)
+ printf ("%s ", printable_time(cred->times.endtime));
+ else
+ printf ("%-15s ", ">>>Expired<<<");
+ ret = krb5_unparse_name (context, cred->server, &str);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_unparse_name");
+ printf ("%s\n", str);
+ free (str);
+}
+
+static void
+print_cred_verbose(krb5_context context, krb5_creds *cred)
+{
+ int j;
+ char *str;
+ krb5_error_code ret;
+ int first_flag;
+ int32_t sec;
+
+ krb5_timeofday (context, &sec);
+
+ ret = krb5_unparse_name(context, cred->server, &str);
+ if(ret)
+ exit(1);
+ printf("Server: %s\n", str);
+ free (str);
+ {
+ Ticket t;
+ size_t len;
+ char *s;
+
+ decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len);
+ ret = krb5_enctype_to_string(context, t.enc_part.etype, &s);
+ if (ret == 0) {
+ printf("Ticket etype: %s", s);
+ free(s);
+ } else {
+ printf("Unknown etype: %d", t.enc_part.etype);
+ }
+ if(t.enc_part.kvno)
+ printf(", kvno %d", *t.enc_part.kvno);
+ printf("\n");
+ if(cred->session.keytype != t.enc_part.etype) {
+ ret = krb5_keytype_to_string(context, cred->session.keytype, &str);
+ if(ret == KRB5_PROG_KEYTYPE_NOSUPP)
+ ret = krb5_enctype_to_string(context, cred->session.keytype,
+ &str);
+ if(ret)
+ krb5_warn(context, ret, "session keytype");
+ else {
+ printf("Session key: %s\n", str);
+ free(str);
+ }
+ }
+ free_Ticket(&t);
+ }
+ printf("Auth time: %s\n", printable_time_long(cred->times.authtime));
+ if(cred->times.authtime != cred->times.starttime)
+ printf("Start time: %s\n", printable_time_long(cred->times.starttime));
+ printf("End time: %s", printable_time_long(cred->times.endtime));
+ if(sec > cred->times.endtime)
+ printf(" (expired)");
+ printf("\n");
+ if(cred->flags.b.renewable)
+ printf("Renew till: %s\n",
+ printable_time_long(cred->times.renew_till));
+ printf("Ticket flags: ");
+#define PRINT_FLAG2(f, s) if(cred->flags.b.f) { if(!first_flag) printf(", "); printf("%s", #s); first_flag = 0; }
+#define PRINT_FLAG(f) PRINT_FLAG2(f, f)
+ first_flag = 1;
+ PRINT_FLAG(forwardable);
+ PRINT_FLAG(forwarded);
+ PRINT_FLAG(proxiable);
+ PRINT_FLAG(proxy);
+ PRINT_FLAG2(may_postdate, may-postdate);
+ PRINT_FLAG(postdated);
+ PRINT_FLAG(invalid);
+ PRINT_FLAG(renewable);
+ PRINT_FLAG(initial);
+ PRINT_FLAG2(pre_authent, pre-authenticated);
+ PRINT_FLAG2(hw_authent, hw-authenticated);
+ PRINT_FLAG2(transited_policy_checked, transited-policy-checked);
+ PRINT_FLAG2(ok_as_delegate, ok-as-delegate);
+ PRINT_FLAG(anonymous);
+ printf("\n");
+ printf("Addresses: ");
+ for(j = 0; j < cred->addresses.len; j++){
+ char buf[128];
+ size_t len;
+ if(j) printf(", ");
+ ret = krb5_print_address(&cred->addresses.val[j],
+ buf, sizeof(buf), &len);
+
+ if(ret == 0)
+ printf("%s", buf);
+ }
+ printf("\n\n");
+}
+
+/*
+ * Print all tickets in `ccache' on stdout, verbosily iff do_verbose.
+ */
+
+static void
+print_tickets (krb5_context context,
+ krb5_ccache ccache,
+ krb5_principal principal,
+ int do_verbose)
+{
+ krb5_error_code ret;
+ char *str;
+ krb5_cc_cursor cursor;
+ krb5_creds creds;
+
+ ret = krb5_unparse_name (context, principal, &str);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_unparse_name");
+
+ printf ("%17s: %s:%s\n",
+ "Credentials cache",
+ krb5_cc_get_type(context, ccache),
+ krb5_cc_get_name(context, ccache));
+ printf ("%17s: %s\n", "Principal", str);
+ free (str);
+
+ if(do_verbose)
+ printf ("%17s: %d\n", "Cache version",
+ krb5_cc_get_version(context, ccache));
+
+ if (do_verbose && context->kdc_sec_offset) {
+ char buf[BUFSIZ];
+ int val;
+ int sig;
+
+ val = context->kdc_sec_offset;
+ sig = 1;
+ if (val < 0) {
+ sig = -1;
+ val = -val;
+ }
+
+ unparse_time (val, buf, sizeof(buf));
+
+ printf ("%17s: %s%s\n", "KDC time offset",
+ sig == -1 ? "-" : "", buf);
+ }
+
+ printf("\n");
+
+ ret = krb5_cc_start_seq_get (context, ccache, &cursor);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_cc_start_seq_get");
+
+ if(!do_verbose)
+ printf(" %-15s %-15s %s\n", "Issued", "Expires", "Principal");
+
+ while (krb5_cc_next_cred (context,
+ ccache,
+ &creds,
+ &cursor) == 0) {
+ if(do_verbose){
+ print_cred_verbose(context, &creds);
+ }else{
+ print_cred(context, &creds);
+ }
+ krb5_free_creds_contents (context, &creds);
+ }
+ ret = krb5_cc_end_seq_get (context, ccache, &cursor);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_end_seq_get");
+}
+
+/*
+ * Check if there's a tgt for the realm of `principal' and ccache and
+ * if so return 0, else 1
+ */
+
+static int
+check_for_tgt (krb5_context context,
+ krb5_ccache ccache,
+ krb5_principal principal)
+{
+ krb5_error_code ret;
+ krb5_creds pattern;
+ krb5_creds creds;
+ krb5_realm *client_realm;
+ int expired;
+
+ client_realm = krb5_princ_realm (context, principal);
+
+ ret = krb5_make_principal (context, &pattern.server,
+ *client_realm, KRB5_TGS_NAME, *client_realm,
+ NULL);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_make_principal");
+
+ ret = krb5_cc_retrieve_cred (context, ccache, 0, &pattern, &creds);
+ expired = time(NULL) > creds.times.endtime;
+ krb5_free_principal (context, pattern.server);
+ krb5_free_creds_contents (context, &creds);
+ if (ret) {
+ if (ret == KRB5_CC_END)
+ return 1;
+ krb5_err (context, 1, ret, "krb5_cc_retrieve_cred");
+ }
+ return expired;
+}
+
+#ifdef KRB4
+/*
+ * Print a list of all AFS tokens
+ */
+
+static void
+display_tokens(int do_verbose)
+{
+ u_int32_t i;
+ unsigned char t[128];
+ struct ViceIoctl parms;
+
+ parms.in = (void *)&i;
+ parms.in_size = sizeof(i);
+ parms.out = (void *)t;
+ parms.out_size = sizeof(t);
+
+ for (i = 0; k_pioctl(NULL, VIOCGETTOK, &parms, 0) == 0; i++) {
+ int32_t size_secret_tok, size_public_tok;
+ unsigned char *cell;
+ struct ClearToken ct;
+ unsigned char *r = t;
+ struct timeval tv;
+ char buf1[20], buf2[20];
+
+ memcpy(&size_secret_tok, r, sizeof(size_secret_tok));
+ /* dont bother about the secret token */
+ r += size_secret_tok + sizeof(size_secret_tok);
+ memcpy(&size_public_tok, r, sizeof(size_public_tok));
+ r += sizeof(size_public_tok);
+ memcpy(&ct, r, size_public_tok);
+ r += size_public_tok;
+ /* there is a int32_t with length of cellname, but we dont read it */
+ r += sizeof(int32_t);
+ cell = r;
+
+ gettimeofday (&tv, NULL);
+ strlcpy (buf1, printable_time(ct.BeginTimestamp),
+ sizeof(buf1));
+ if (do_verbose || tv.tv_sec < ct.EndTimestamp)
+ strlcpy (buf2, printable_time(ct.EndTimestamp),
+ sizeof(buf2));
+ else
+ strlcpy (buf2, ">>> Expired <<<", sizeof(buf2));
+
+ printf("%s %s ", buf1, buf2);
+
+ if ((ct.EndTimestamp - ct.BeginTimestamp) & 1)
+ printf("User's (AFS ID %d) tokens for %s", ct.ViceId, cell);
+ else
+ printf("Tokens for %s", cell);
+ if (do_verbose)
+ printf(" (%d)", ct.AuthHandle);
+ putchar('\n');
+ }
+}
+#endif
+
+static int version_flag = 0;
+static int help_flag = 0;
+static int do_verbose = 0;
+static int do_test = 0;
+#ifdef KRB4
+static int do_tokens = 0;
+#endif
+static char *cred_cache;
+
+static struct getargs args[] = {
+ { "cache", 'c', arg_string, &cred_cache,
+ "credentials cache to list", "cache" },
+ { "test", 't', arg_flag, &do_test,
+ "test for having tickets", NULL },
+#ifdef KRB4
+ { "tokens", 'T', arg_flag, &do_tokens,
+ "display AFS tokens", NULL },
+#endif
+ { "verbose", 'v', arg_flag, &do_verbose,
+ "Verbose output", NULL },
+ { "version", 0, arg_flag, &version_flag,
+ "print version", NULL },
+ { "help", 0, arg_flag, &help_flag,
+ NULL, NULL}
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "");
+ exit (ret);
+}
+
+int
+main (int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache ccache;
+ krb5_principal principal;
+ int optind = 0;
+ int exit_status = 0;
+
+ set_progname (argv[0]);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage (1);
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_init_context");
+
+ if(cred_cache) {
+ ret = krb5_cc_resolve(context, cred_cache, &ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "%s", cred_cache);
+ } else {
+ ret = krb5_cc_default (context, &ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_resolve");
+ }
+
+ ret = krb5_cc_get_principal (context, ccache, &principal);
+ if (ret) {
+ if(ret == ENOENT) {
+ if (do_test)
+ return 1;
+ else
+ krb5_errx(context, 1, "No ticket file: %s",
+ krb5_cc_get_name(context, ccache));
+ } else
+ krb5_err (context, 1, ret, "krb5_cc_get_principal");
+ }
+ if (do_test)
+ exit_status = check_for_tgt (context, ccache, principal);
+ else
+ print_tickets (context, ccache, principal, do_verbose);
+
+ ret = krb5_cc_close (context, ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_close");
+
+ krb5_free_principal (context, principal);
+ krb5_free_context (context);
+
+#ifdef KRB4
+ if (!do_test && do_tokens && k_hasafs ())
+ display_tokens (do_verbose);
+#endif
+
+ return exit_status;
+}
diff --git a/crypto/heimdal/kuser/kuser_locl.h b/crypto/heimdal/kuser/kuser_locl.h
new file mode 100644
index 000000000000..2010150f8dfa
--- /dev/null
+++ b/crypto/heimdal/kuser/kuser_locl.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: kuser_locl.h,v 1.12 1999/12/02 17:05:01 joda Exp $ */
+
+#ifndef __KUSER_LOCL_H__
+#define __KUSER_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <roken.h>
+#include <getarg.h>
+#include <parse_time.h>
+#include <err.h>
+#include <krb5.h>
+
+#ifdef KRB4
+#include <krb.h>
+#endif
+#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#include <kafs.h>
+
+#endif /* __KUSER_LOCL_H__ */
diff --git a/crypto/heimdal/kuser/kverify.c b/crypto/heimdal/kuser/kverify.c
new file mode 100644
index 000000000000..986d7c99f478
--- /dev/null
+++ b/crypto/heimdal/kuser/kverify.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kuser_locl.h"
+
+RCSID("$Id: kverify.c,v 1.3 1999/12/02 17:05:01 joda Exp $");
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ krb5_creds cred;
+ krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP};
+ krb5_get_init_creds_opt get_options;
+ krb5_verify_init_creds_opt verify_options;
+
+ krb5_init_context(&context);
+
+ krb5_get_init_creds_opt_init (&get_options);
+
+ krb5_get_init_creds_opt_set_preauth_list (&get_options,
+ pre_auth_types,
+ 1);
+
+ krb5_verify_init_creds_opt_init (&verify_options);
+
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ NULL,
+ NULL,
+ krb5_prompter_posix,
+ NULL,
+ 0,
+ NULL,
+ &get_options);
+ if (ret)
+ errx (1, "krb5_get_init_creds: %s", krb5_get_err_text(context, ret));
+
+ ret = krb5_verify_init_creds (context,
+ &cred,
+ NULL,
+ NULL,
+ NULL,
+ &verify_options);
+ if (ret)
+ errx (1, "krb5_verify_init_creds: %s",
+ krb5_get_err_text(context, ret));
+ krb5_free_creds_contents (context, &cred);
+ krb5_free_context (context);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/45/45_locl.h b/crypto/heimdal/lib/45/45_locl.h
new file mode 100644
index 000000000000..8104179d5bba
--- /dev/null
+++ b/crypto/heimdal/lib/45/45_locl.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifndef __45_LOCL_H__
+#define __45_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include <krb5.h>
+#include <krb.h>
+#include <prot.h>
+
+#endif /* __45_LOCL_H__ */
diff --git a/crypto/heimdal/lib/45/Makefile.am b/crypto/heimdal/lib/45/Makefile.am
new file mode 100644
index 000000000000..50d47fdb3929
--- /dev/null
+++ b/crypto/heimdal/lib/45/Makefile.am
@@ -0,0 +1,11 @@
+# $Id: Makefile.am,v 1.5 1999/03/20 13:58:17 joda Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+lib_LIBRARIES = @EXTRA_LIB45@
+
+EXTRA_LIBRARIES = lib45.a
+
+lib45_a_SOURCES = get_ad_tkt.c mk_req.c 45_locl.h
diff --git a/crypto/heimdal/lib/45/Makefile.in b/crypto/heimdal/lib/45/Makefile.in
new file mode 100644
index 000000000000..9b0c7fcd68c4
--- /dev/null
+++ b/crypto/heimdal/lib/45/Makefile.in
@@ -0,0 +1,636 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.5 1999/03/20 13:58:17 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+lib_LIBRARIES = @EXTRA_LIB45@
+
+EXTRA_LIBRARIES = lib45.a
+
+lib45_a_SOURCES = get_ad_tkt.c mk_req.c 45_locl.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(lib_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+lib45_a_LIBADD =
+lib45_a_OBJECTS = get_ad_tkt.$(OBJEXT) mk_req.$(OBJEXT)
+AR = ar
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(lib45_a_SOURCES)
+OBJECTS = $(lib45_a_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/45/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLIBRARIES:
+
+clean-libLIBRARIES:
+ -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
+
+distclean-libLIBRARIES:
+
+maintainer-clean-libLIBRARIES:
+
+install-libLIBRARIES: $(lib_LIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+ @$(POST_INSTALL)
+ @list='$(lib_LIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \
+ $(RANLIB) $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LIBRARIES)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+lib45.a: $(lib45_a_OBJECTS) $(lib45_a_DEPENDENCIES)
+ -rm -f lib45.a
+ $(AR) cru lib45.a $(lib45_a_OBJECTS) $(lib45_a_LIBADD)
+ $(RANLIB) lib45.a
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/45
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLIBRARIES
+uninstall: uninstall-am
+all-am: Makefile $(LIBRARIES) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLIBRARIES clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLIBRARIES distclean-libLIBRARIES \
+clean-libLIBRARIES maintainer-clean-libLIBRARIES uninstall-libLIBRARIES \
+install-libLIBRARIES mostlyclean-compile distclean-compile \
+clean-compile maintainer-clean-compile mostlyclean-libtool \
+distclean-libtool clean-libtool maintainer-clean-libtool tags \
+mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \
+distdir info-am info dvi-am dvi check-local check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-local install-data-am install-data install-am install \
+uninstall-am uninstall all-local all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/45/get_ad_tkt.c b/crypto/heimdal/lib/45/get_ad_tkt.c
new file mode 100644
index 000000000000..36196066f540
--- /dev/null
+++ b/crypto/heimdal/lib/45/get_ad_tkt.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "45_locl.h"
+
+RCSID("$Id: get_ad_tkt.c,v 1.3 1999/12/02 17:05:01 joda Exp $");
+
+/* get an additional version 4 ticket via the 524 protocol */
+
+#ifndef NEVERDATE
+#define NEVERDATE ((unsigned long)0x7fffffffL)
+#endif
+
+int
+get_ad_tkt(char *service, char *sinstance, char *realm, int lifetime)
+{
+ krb5_error_code ret;
+ int code;
+ krb5_context context;
+ krb5_ccache id;
+ krb5_creds in_creds, *out_creds;
+ CREDENTIALS cred;
+ time_t now;
+ char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
+
+ ret = krb5_init_context(&context);
+ if(ret)
+ return KFAILURE;
+ ret = krb5_cc_default(context, &id);
+ if(ret){
+ krb5_free_context(context);
+ return KFAILURE;
+ }
+ memset(&in_creds, 0, sizeof(in_creds));
+ now = time(NULL);
+ in_creds.times.endtime = krb_life_to_time(time(NULL), lifetime);
+ if(in_creds.times.endtime == NEVERDATE)
+ in_creds.times.endtime = 0;
+ ret = krb5_cc_get_principal(context, id, &in_creds.client);
+ if(ret){
+ krb5_cc_close(context, id);
+ krb5_free_context(context);
+ return KFAILURE;
+ }
+ ret = krb5_524_conv_principal(context, in_creds.client,
+ pname, pinst, prealm);
+ if(ret){
+ krb5_free_principal(context, in_creds.client);
+ krb5_cc_close(context, id);
+ krb5_free_context(context);
+ return KFAILURE;
+ }
+ ret = krb5_425_conv_principal(context, service, sinstance, realm,
+ &in_creds.server);
+ if(ret){
+ krb5_free_principal(context, in_creds.client);
+ krb5_cc_close(context, id);
+ krb5_free_context(context);
+ return KFAILURE;
+ }
+ ret = krb5_get_credentials(context,
+ 0,
+ id,
+ &in_creds,
+ &out_creds);
+ krb5_free_principal(context, in_creds.client);
+ krb5_free_principal(context, in_creds.server);
+ if(ret){
+ krb5_cc_close(context, id);
+ krb5_free_context(context);
+ return KFAILURE;
+ }
+ ret = krb524_convert_creds_kdc(context, id, out_creds, &cred);
+ krb5_cc_close(context, id);
+ krb5_free_context(context);
+ krb5_free_creds(context, out_creds);
+ if(ret)
+ return KFAILURE;
+ code = save_credentials(cred.service, cred.instance, cred.realm,
+ cred.session, cred.lifetime, cred.kvno,
+ &cred.ticket_st, now);
+ if(code == NO_TKT_FIL)
+ code = tf_setup(&cred, pname, pinst);
+ memset(&cred.session, 0, sizeof(cred.session));
+ return code;
+}
diff --git a/crypto/heimdal/lib/45/mk_req.c b/crypto/heimdal/lib/45/mk_req.c
new file mode 100644
index 000000000000..7074ebf97b4e
--- /dev/null
+++ b/crypto/heimdal/lib/45/mk_req.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* implementation of krb_mk_req that uses 524 protocol */
+
+#include "45_locl.h"
+
+RCSID("$Id: mk_req.c,v 1.2 1999/12/02 17:05:01 joda Exp $");
+
+static int lifetime = 255;
+
+static void
+build_request(KTEXT req, char *name, char *inst, char *realm,
+ u_int32_t checksum)
+{
+ struct timeval tv;
+ krb5_storage *sp;
+ krb5_data data;
+ sp = krb5_storage_emem();
+ krb5_store_stringz(sp, name);
+ krb5_store_stringz(sp, inst);
+ krb5_store_stringz(sp, realm);
+ krb5_store_int32(sp, checksum);
+ gettimeofday(&tv, NULL);
+ krb5_store_int8(sp, tv.tv_usec / 5000);
+ krb5_store_int32(sp, tv.tv_sec);
+ krb5_storage_to_data(sp, &data);
+ krb5_storage_free(sp);
+ memcpy(req->dat, data.data, data.length);
+ req->length = (data.length + 7) & ~7;
+ krb5_data_free(&data);
+}
+
+int
+krb_mk_req(KTEXT authent, char *service, char *instance, char *realm,
+ int32_t checksum)
+{
+ CREDENTIALS cr;
+ KTEXT_ST req;
+ krb5_storage *sp;
+ int code;
+ char *myrealm;
+ krb5_data a;
+
+ code = krb_get_cred(service, instance, realm, &cr);
+ if(code || time(NULL) > krb_life_to_time(cr.issue_date, cr.lifetime)){
+ code = get_ad_tkt(service, instance, realm, lifetime);
+ if(code == KSUCCESS)
+ code = krb_get_cred(service, instance, realm, &cr);
+ }
+
+ if(code)
+ return code;
+
+ /* XXX get user realm */
+ myrealm = realm;
+
+ sp = krb5_storage_emem();
+
+ krb5_store_int8(sp, KRB_PROT_VERSION);
+ krb5_store_int8(sp, AUTH_MSG_APPL_REQUEST);
+
+ krb5_store_int8(sp, cr.kvno);
+ krb5_store_stringz(sp, realm);
+ krb5_store_int8(sp, cr.ticket_st.length);
+
+ build_request(&req, cr.pname, cr.pinst, myrealm, checksum);
+ encrypt_ktext(&req, &cr.session, DES_ENCRYPT);
+
+ krb5_store_int8(sp, req.length);
+
+ sp->store(sp, cr.ticket_st.dat, cr.ticket_st.length);
+ sp->store(sp, req.dat, req.length);
+ krb5_storage_to_data(sp, &a);
+ krb5_storage_free(sp);
+ memcpy(authent->dat, a.data, a.length);
+ authent->length = a.length;
+ krb5_data_free(&a);
+
+ memset(&cr, 0, sizeof(cr));
+ memset(&req, 0, sizeof(req));
+
+ return KSUCCESS;
+}
+
+/*
+ * krb_set_lifetime sets the default lifetime for additional tickets
+ * obtained via krb_mk_req().
+ *
+ * It returns the previous value of the default lifetime.
+ */
+
+int
+krb_set_lifetime(int newval)
+{
+ int olife = lifetime;
+
+ lifetime = newval;
+ return(olife);
+}
diff --git a/crypto/heimdal/lib/Makefile.am b/crypto/heimdal/lib/Makefile.am
new file mode 100644
index 000000000000..c600c22ecdc4
--- /dev/null
+++ b/crypto/heimdal/lib/Makefile.am
@@ -0,0 +1,13 @@
+# $Id: Makefile.am,v 1.16 1999/04/01 15:03:37 joda Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+if KRB4
+dir_45 = 45
+endif
+if OTP
+dir_otp = otp
+endif
+
+SUBDIRS = roken editline com_err sl asn1 des krb5 \
+ kafs hdb kadm5 gssapi auth $(dir_45) $(dir_otp)
diff --git a/crypto/heimdal/lib/Makefile.in b/crypto/heimdal/lib/Makefile.in
new file mode 100644
index 000000000000..4c8aa71cf274
--- /dev/null
+++ b/crypto/heimdal/lib/Makefile.in
@@ -0,0 +1,604 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.16 1999/04/01 15:03:37 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+@KRB4_TRUE@dir_45 = 45
+@OTP_TRUE@dir_otp = otp
+
+SUBDIRS = roken editline com_err sl asn1 des krb5 kafs hdb kadm5 gssapi auth $(dir_45) $(dir_otp)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/config.h
+CONFIG_CLEAN_FILES =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+DIST_SUBDIRS = roken editline com_err sl asn1 des krb5 kafs hdb kadm5 \
+gssapi auth 45 otp
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .et .h .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(DIST_SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-recursive
+
+install-data-am: install-data-local
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile all-local
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+
+.PHONY: install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/asn1/Makefile.am b/crypto/heimdal/lib/asn1/Makefile.am
new file mode 100644
index 000000000000..97fb2bbd6ef5
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/Makefile.am
@@ -0,0 +1,107 @@
+# $Id: Makefile.am,v 1.54 1999/12/21 17:03:42 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+YFLAGS = -d
+
+lib_LTLIBRARIES = libasn1.la
+libasn1_la_LDFLAGS = -version-info 1:4:0
+
+BUILT_SOURCES = \
+ $(gen_files:.x=.c) \
+ asn1_err.h \
+ asn1_err.c
+
+gen_files = \
+ asn1_APOptions.x \
+ asn1_AP_REP.x \
+ asn1_AP_REQ.x \
+ asn1_AS_REP.x \
+ asn1_AS_REQ.x \
+ asn1_Authenticator.x \
+ asn1_AuthorizationData.x \
+ asn1_Checksum.x \
+ asn1_EncAPRepPart.x \
+ asn1_EncASRepPart.x \
+ asn1_EncKDCRepPart.x \
+ asn1_EncKrbCredPart.x \
+ asn1_EncKrbPrivPart.x \
+ asn1_EncTGSRepPart.x \
+ asn1_EncTicketPart.x \
+ asn1_EncryptedData.x \
+ asn1_EncryptionKey.x \
+ asn1_ETYPE_INFO.x \
+ asn1_ETYPE_INFO_ENTRY.x \
+ asn1_HostAddress.x \
+ asn1_HostAddresses.x \
+ asn1_KDCOptions.x \
+ asn1_KDC_REP.x \
+ asn1_KDC_REQ.x \
+ asn1_KDC_REQ_BODY.x \
+ asn1_KRB_CRED.x \
+ asn1_KRB_ERROR.x \
+ asn1_KRB_PRIV.x \
+ asn1_KRB_SAFE.x \
+ asn1_KRB_SAFE_BODY.x \
+ asn1_KerberosTime.x \
+ asn1_KrbCredInfo.x \
+ asn1_LastReq.x \
+ asn1_METHOD_DATA.x \
+ asn1_PA_DATA.x \
+ asn1_PA_ENC_TS_ENC.x \
+ asn1_Principal.x \
+ asn1_PrincipalName.x \
+ asn1_Realm.x \
+ asn1_TGS_REP.x \
+ asn1_TGS_REQ.x \
+ asn1_Ticket.x \
+ asn1_TicketFlags.x \
+ asn1_TransitedEncoding.x
+
+
+noinst_PROGRAMS = asn1_compile asn1_print
+check_PROGRAMS = check-der
+TESTS = check-der
+
+asn1_compile_SOURCES = parse.y lex.l main.c hash.c symbol.c gen.c \
+ gen_encode.c gen_decode.c gen_free.c gen_length.c gen_copy.c \
+ gen_glue.c
+
+libasn1_la_SOURCES = \
+ der_get.c \
+ der_put.c \
+ der_free.c \
+ der_length.c \
+ der_copy.c \
+ timegm.c \
+ $(BUILT_SOURCES)
+
+asn1_compile_LDADD = \
+ $(LIB_roken) $(LEXLIB)
+
+check_der_LDADD = \
+ libasn1.la \
+ ../com_err/libcom_err.la \
+ $(LIB_roken)
+
+asn1_print_LDADD = $(check_der_LDADD)
+
+TESTS = check-der
+
+CLEANFILES = lex.c parse.c parse.h asn1.h $(BUILT_SOURCES) \
+ $(gen_files) asn1_files
+
+include_HEADERS = asn1.h asn1_err.h der.h
+
+$(asn1_compile_OBJECTS): parse.h
+
+$(gen_files) asn1.h: asn1_files
+
+asn1_files: asn1_compile$(EXEEXT) $(srcdir)/k5.asn1
+ ./asn1_compile$(EXEEXT) $(srcdir)/k5.asn1
+
+$(libasn1_la_OBJECTS): asn1.h asn1_err.h
+
+$(asn1_print_OBJECTS): asn1.h
+
+EXTRA_DIST = asn1_err.et
diff --git a/crypto/heimdal/lib/asn1/Makefile.in b/crypto/heimdal/lib/asn1/Makefile.in
new file mode 100644
index 000000000000..25acf1a3f901
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/Makefile.in
@@ -0,0 +1,794 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.54 1999/12/21 17:03:42 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+YFLAGS = -d
+
+lib_LTLIBRARIES = libasn1.la
+libasn1_la_LDFLAGS = -version-info 1:4:0
+
+BUILT_SOURCES = $(gen_files:.x=.c) asn1_err.h asn1_err.c
+
+
+gen_files = asn1_APOptions.x asn1_AP_REP.x asn1_AP_REQ.x asn1_AS_REP.x asn1_AS_REQ.x asn1_Authenticator.x asn1_AuthorizationData.x asn1_Checksum.x asn1_EncAPRepPart.x asn1_EncASRepPart.x asn1_EncKDCRepPart.x asn1_EncKrbCredPart.x asn1_EncKrbPrivPart.x asn1_EncTGSRepPart.x asn1_EncTicketPart.x asn1_EncryptedData.x asn1_EncryptionKey.x asn1_ETYPE_INFO.x asn1_ETYPE_INFO_ENTRY.x asn1_HostAddress.x asn1_HostAddresses.x asn1_KDCOptions.x asn1_KDC_REP.x asn1_KDC_REQ.x asn1_KDC_REQ_BODY.x asn1_KRB_CRED.x asn1_KRB_ERROR.x asn1_KRB_PRIV.x asn1_KRB_SAFE.x asn1_KRB_SAFE_BODY.x asn1_KerberosTime.x asn1_KrbCredInfo.x asn1_LastReq.x asn1_METHOD_DATA.x asn1_PA_DATA.x asn1_PA_ENC_TS_ENC.x asn1_Principal.x asn1_PrincipalName.x asn1_Realm.x asn1_TGS_REP.x asn1_TGS_REQ.x asn1_Ticket.x asn1_TicketFlags.x asn1_TransitedEncoding.x
+
+
+noinst_PROGRAMS = asn1_compile asn1_print
+check_PROGRAMS = check-der
+
+TESTS = check-der
+
+asn1_compile_SOURCES = parse.y lex.l main.c hash.c symbol.c gen.c gen_encode.c gen_decode.c gen_free.c gen_length.c gen_copy.c gen_glue.c
+
+
+libasn1_la_SOURCES = der_get.c der_put.c der_free.c der_length.c der_copy.c timegm.c $(BUILT_SOURCES)
+
+
+asn1_compile_LDADD = $(LIB_roken) $(LEXLIB)
+
+
+check_der_LDADD = libasn1.la ../com_err/libcom_err.la $(LIB_roken)
+
+
+asn1_print_LDADD = $(check_der_LDADD)
+
+CLEANFILES = lex.c parse.c parse.h asn1.h $(BUILT_SOURCES) $(gen_files) asn1_files
+
+
+include_HEADERS = asn1.h asn1_err.h der.h
+
+EXTRA_DIST = asn1_err.et
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libasn1_la_LIBADD =
+libasn1_la_OBJECTS = der_get.lo der_put.lo der_free.lo der_length.lo \
+der_copy.lo timegm.lo asn1_APOptions.lo asn1_AP_REP.lo asn1_AP_REQ.lo \
+asn1_AS_REP.lo asn1_AS_REQ.lo asn1_Authenticator.lo \
+asn1_AuthorizationData.lo asn1_Checksum.lo asn1_EncAPRepPart.lo \
+asn1_EncASRepPart.lo asn1_EncKDCRepPart.lo asn1_EncKrbCredPart.lo \
+asn1_EncKrbPrivPart.lo asn1_EncTGSRepPart.lo asn1_EncTicketPart.lo \
+asn1_EncryptedData.lo asn1_EncryptionKey.lo asn1_ETYPE_INFO.lo \
+asn1_ETYPE_INFO_ENTRY.lo asn1_HostAddress.lo asn1_HostAddresses.lo \
+asn1_KDCOptions.lo asn1_KDC_REP.lo asn1_KDC_REQ.lo asn1_KDC_REQ_BODY.lo \
+asn1_KRB_CRED.lo asn1_KRB_ERROR.lo asn1_KRB_PRIV.lo asn1_KRB_SAFE.lo \
+asn1_KRB_SAFE_BODY.lo asn1_KerberosTime.lo asn1_KrbCredInfo.lo \
+asn1_LastReq.lo asn1_METHOD_DATA.lo asn1_PA_DATA.lo \
+asn1_PA_ENC_TS_ENC.lo asn1_Principal.lo asn1_PrincipalName.lo \
+asn1_Realm.lo asn1_TGS_REP.lo asn1_TGS_REQ.lo asn1_Ticket.lo \
+asn1_TicketFlags.lo asn1_TransitedEncoding.lo asn1_err.lo
+check_PROGRAMS = check-der$(EXEEXT)
+noinst_PROGRAMS = asn1_compile$(EXEEXT) asn1_print$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+check_der_SOURCES = check-der.c
+check_der_OBJECTS = check-der.$(OBJEXT)
+check_der_DEPENDENCIES = libasn1.la ../com_err/libcom_err.la
+check_der_LDFLAGS =
+asn1_compile_OBJECTS = parse.$(OBJEXT) lex.$(OBJEXT) main.$(OBJEXT) \
+hash.$(OBJEXT) symbol.$(OBJEXT) gen.$(OBJEXT) gen_encode.$(OBJEXT) \
+gen_decode.$(OBJEXT) gen_free.$(OBJEXT) gen_length.$(OBJEXT) \
+gen_copy.$(OBJEXT) gen_glue.$(OBJEXT)
+asn1_compile_DEPENDENCIES =
+asn1_compile_LDFLAGS =
+asn1_print_SOURCES = asn1_print.c
+asn1_print_OBJECTS = asn1_print.$(OBJEXT)
+asn1_print_DEPENDENCIES = libasn1.la ../com_err/libcom_err.la
+asn1_print_LDFLAGS =
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(include_HEADERS)
+
+DIST_COMMON = Makefile.am Makefile.in lex.c parse.c
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libasn1_la_SOURCES) check-der.c $(asn1_compile_SOURCES) asn1_print.c
+OBJECTS = $(libasn1_la_OBJECTS) check-der.$(OBJEXT) $(asn1_compile_OBJECTS) asn1_print.$(OBJEXT)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .l .lo .o .obj .s .x .y
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/asn1/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libasn1.la: $(libasn1_la_OBJECTS) $(libasn1_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libasn1_la_LDFLAGS) $(libasn1_la_OBJECTS) $(libasn1_la_LIBADD) $(LIBS)
+
+mostlyclean-checkPROGRAMS:
+
+clean-checkPROGRAMS:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+
+distclean-checkPROGRAMS:
+
+maintainer-clean-checkPROGRAMS:
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+check-der$(EXEEXT): $(check_der_OBJECTS) $(check_der_DEPENDENCIES)
+ @rm -f check-der$(EXEEXT)
+ $(LINK) $(check_der_LDFLAGS) $(check_der_OBJECTS) $(check_der_LDADD) $(LIBS)
+
+asn1_compile$(EXEEXT): $(asn1_compile_OBJECTS) $(asn1_compile_DEPENDENCIES)
+ @rm -f asn1_compile$(EXEEXT)
+ $(LINK) $(asn1_compile_LDFLAGS) $(asn1_compile_OBJECTS) $(asn1_compile_LDADD) $(LIBS)
+
+asn1_print$(EXEEXT): $(asn1_print_OBJECTS) $(asn1_print_DEPENDENCIES)
+ @rm -f asn1_print$(EXEEXT)
+ $(LINK) $(asn1_print_LDFLAGS) $(asn1_print_OBJECTS) $(asn1_print_LDADD) $(LIBS)
+.l.c:
+ $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@
+.y.c:
+ $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c
+ if test -f y.tab.h; then \
+ if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
+ else :; fi
+parse.h: parse.c
+
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/asn1
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+check-TESTS: $(TESTS)
+ @failed=0; all=0; \
+ srcdir=$(srcdir); export srcdir; \
+ for tst in $(TESTS); do \
+ if test -f $$tst; then dir=.; \
+ else dir="$(srcdir)"; fi; \
+ if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \
+ all=`expr $$all + 1`; \
+ echo "PASS: $$tst"; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-includeHEADERS install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ -test -z "lexlparsehparsec$(BUILT_SOURCES)" || rm -f lexl parseh parsec $(BUILT_SOURCES)
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-checkPROGRAMS \
+ mostlyclean-noinstPROGRAMS mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \
+ clean-checkPROGRAMS clean-noinstPROGRAMS clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-checkPROGRAMS \
+ distclean-noinstPROGRAMS distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-checkPROGRAMS \
+ maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool mostlyclean-checkPROGRAMS \
+distclean-checkPROGRAMS clean-checkPROGRAMS \
+maintainer-clean-checkPROGRAMS mostlyclean-noinstPROGRAMS \
+distclean-noinstPROGRAMS clean-noinstPROGRAMS \
+maintainer-clean-noinstPROGRAMS uninstall-includeHEADERS \
+install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir check-TESTS info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-local install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+$(asn1_compile_OBJECTS): parse.h
+
+$(gen_files) asn1.h: asn1_files
+
+asn1_files: asn1_compile$(EXEEXT) $(srcdir)/k5.asn1
+ ./asn1_compile$(EXEEXT) $(srcdir)/k5.asn1
+
+$(libasn1_la_OBJECTS): asn1.h asn1_err.h
+
+$(asn1_print_OBJECTS): asn1.h
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/asn1/asn1_err.et b/crypto/heimdal/lib/asn1/asn1_err.et
new file mode 100644
index 000000000000..8f1f272cccbd
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/asn1_err.et
@@ -0,0 +1,20 @@
+#
+# Error messages for the asn.1 library
+#
+# This might look like a com_err file, but is not
+#
+id "$Id: asn1_err.et,v 1.5 1998/02/16 16:17:17 joda Exp $"
+
+error_table asn1
+prefix ASN1
+error_code BAD_TIMEFORMAT, "ASN.1 failed call to system time library"
+error_code MISSING_FIELD, "ASN.1 structure is missing a required field"
+error_code MISPLACED_FIELD, "ASN.1 unexpected field number"
+error_code TYPE_MISMATCH, "ASN.1 type numbers are inconsistent"
+error_code OVERFLOW, "ASN.1 value too large"
+error_code OVERRUN, "ASN.1 encoding ended unexpectedly"
+error_code BAD_ID, "ASN.1 identifier doesn't match expected value"
+error_code BAD_LENGTH, "ASN.1 length doesn't match expected value"
+error_code BAD_FORMAT, "ASN.1 badly-formatted encoding"
+error_code PARSE_ERROR, "ASN.1 parse error"
+end
diff --git a/crypto/heimdal/lib/asn1/asn1_print.c b/crypto/heimdal/lib/asn1/asn1_print.c
new file mode 100644
index 000000000000..92e64193aefc
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/asn1_print.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "der_locl.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <getarg.h>
+#include <err.h>
+
+RCSID("$Id: asn1_print.c,v 1.5 1999/12/02 17:05:01 joda Exp $");
+
+static struct et_list *et_list;
+
+const char *class_names[] = {
+ "UNIV", /* 0 */
+ "APPL", /* 1 */
+ "CONTEXT", /* 2 */
+ "PRIVATE" /* 3 */
+};
+
+const char *type_names[] = {
+ "PRIM", /* 0 */
+ "CONS" /* 1 */
+};
+
+const char *tag_names[] = {
+ NULL, /* 0 */
+ NULL, /* 1 */
+ "Integer", /* 2 */
+ "BitString", /* 3 */
+ "OctetString", /* 4 */
+ "Null", /* 5 */
+ "ObjectID", /* 6 */
+ NULL, /* 7 */
+ NULL, /* 8 */
+ NULL, /* 9 */
+ NULL, /* 10 */
+ NULL, /* 11 */
+ NULL, /* 12 */
+ NULL, /* 13 */
+ NULL, /* 14 */
+ NULL, /* 15 */
+ "Sequence", /* 16 */
+ "Set", /* 17 */
+ NULL, /* 18 */
+ "PrintableString", /* 19 */
+ NULL, /* 20 */
+ NULL, /* 21 */
+ "IA5String", /* 22 */
+ "UTCTime", /* 23 */
+ "GeneralizedTime", /* 24 */
+ NULL, /* 25 */
+ "VisibleString", /* 26 */
+ "GeneralString" /* 27 */
+};
+
+static int
+loop (unsigned char *buf, size_t len, int indent)
+{
+ while (len > 0) {
+ int ret;
+ Der_class class;
+ Der_type type;
+ int tag;
+ size_t sz;
+ size_t length;
+ int i;
+
+ ret = der_get_tag (buf, len, &class, &type, &tag, &sz);
+ if (ret)
+ errx (1, "der_get_tag: %s", com_right (et_list, ret));
+ buf += sz;
+ len -= sz;
+ for (i = 0; i < indent; ++i)
+ printf (" ");
+ printf ("%s %s ", class_names[class], type_names[type]);
+ if (tag_names[tag])
+ printf ("%s = ", tag_names[tag]);
+ else
+ printf ("tag %d = ", tag);
+ ret = der_get_length (buf, len, &length, &sz);
+ if (ret)
+ errx (1, "der_get_tag: %s", com_right (et_list, ret));
+ buf += sz;
+ len -= sz;
+
+ if (class == CONTEXT) {
+ printf ("[%d]\n", tag);
+ loop (buf, length, indent);
+ } else if (class == UNIV) {
+ switch (tag) {
+ case UT_Sequence :
+ printf ("{\n");
+ loop (buf, length, indent + 2);
+ for (i = 0; i < indent; ++i)
+ printf (" ");
+ printf ("}\n");
+ break;
+ case UT_Integer : {
+ int val;
+
+ ret = der_get_int (buf, length, &val, NULL);
+ if (ret)
+ errx (1, "der_get_int: %s", com_right (et_list, ret));
+ printf ("integer %d\n", val);
+ break;
+ }
+ case UT_OctetString : {
+ octet_string str;
+ int i;
+ unsigned char *uc;
+
+ ret = der_get_octet_string (buf, length, &str, NULL);
+ if (ret)
+ errx (1, "der_get_octet_string: %s",
+ com_right (et_list, ret));
+ printf ("(length %d), ", length);
+ uc = (unsigned char *)str.data;
+ for (i = 0; i < 16; ++i)
+ printf ("%02x", uc[i]);
+ printf ("\n");
+ free (str.data);
+ break;
+ }
+ case UT_GeneralizedTime :
+ case UT_GeneralString : {
+ general_string str;
+
+ ret = der_get_general_string (buf, length, &str, NULL);
+ if (ret)
+ errx (1, "der_get_general_string: %s",
+ com_right (et_list, ret));
+ printf ("\"%s\"\n", str);
+ free (str);
+ break;
+ }
+ default :
+ printf ("%d bytes\n", length);
+ break;
+ }
+ }
+ buf += length;
+ len -= length;
+ }
+ return 0;
+}
+
+static int
+doit (const char *filename)
+{
+ int fd = open (filename, O_RDONLY);
+ struct stat sb;
+ unsigned char *buf;
+ size_t len;
+ int ret;
+
+ if(fd < 0)
+ err (1, "opening %s for read", filename);
+ if (fstat (fd, &sb) < 0)
+ err (1, "stat %s", filename);
+ len = sb.st_size;
+ buf = malloc (len);
+ if (buf == NULL)
+ err (1, "malloc %u", len);
+ if (read (fd, buf, len) != len)
+ errx (1, "read failed");
+ close (fd);
+ ret = loop (buf, len, 0);
+ free (buf);
+ return ret;
+}
+
+
+static int version_flag;
+static int help_flag;
+struct getargs args[] = {
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int code)
+{
+ arg_printusage(args, num_args, NULL, "dump-file");
+ exit(code);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+
+ set_progname (argv[0]);
+ initialize_asn1_error_table_r (&et_list);
+ if(getarg(args, num_args, argc, argv, &optind))
+ usage(1);
+ if(help_flag)
+ usage(0);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+ argv += optind;
+ argc -= optind;
+ if (argc != 1)
+ usage (1);
+ return doit (argv[0]);
+}
diff --git a/crypto/heimdal/lib/asn1/check-der.c b/crypto/heimdal/lib/asn1/check-der.c
new file mode 100644
index 000000000000..a2f1217e40a7
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/check-der.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <err.h>
+#include <roken.h>
+
+#include <libasn1.h>
+
+RCSID("$Id: check-der.c,v 1.7 1999/12/02 17:05:01 joda Exp $");
+
+static void
+print_bytes (unsigned const char *buf, size_t len)
+{
+ int i;
+
+ for (i = 0; i < len; ++i)
+ printf ("%02x ", buf[i]);
+}
+
+struct test_case {
+ void *val;
+ int byte_len;
+ const unsigned char *bytes;
+ char *name;
+};
+
+static int
+generic_test (const struct test_case *tests,
+ unsigned ntests,
+ size_t data_size,
+ int (*encode)(unsigned char *, size_t, void *, size_t *),
+ int (*length)(void *),
+ int (*decode)(unsigned char *, size_t, void *, size_t *),
+ int (*cmp)(void *a, void *b))
+{
+ unsigned char buf[4711];
+ int i;
+ int failures = 0;
+ void *val = malloc (data_size);
+
+ if (data_size != 0 && val == NULL)
+ err (1, "malloc");
+
+ for (i = 0; i < ntests; ++i) {
+ int ret;
+ size_t sz, consumed_sz, length_sz;
+ unsigned char *beg;
+
+ ret = (*encode) (buf + sizeof(buf) - 1, sizeof(buf),
+ tests[i].val, &sz);
+ beg = buf + sizeof(buf) - sz;
+ if (ret != 0) {
+ printf ("encoding of %s failed\n", tests[i].name);
+ ++failures;
+ }
+ if (sz != tests[i].byte_len) {
+ printf ("encoding of %s has wrong len (%lu != %lu)\n",
+ tests[i].name,
+ (unsigned long)sz, (unsigned long)tests[i].byte_len);
+ ++failures;
+ }
+
+ length_sz = (*length) (tests[i].val);
+ if (sz != length_sz) {
+ printf ("length for %s is bad (%lu != %lu)\n",
+ tests[i].name, (unsigned long)length_sz, (unsigned long)sz);
+ ++failures;
+ }
+
+ if (memcmp (beg, tests[i].bytes, tests[i].byte_len) != 0) {
+ printf ("encoding of %s has bad bytes:\n"
+ "correct: ", tests[i].name);
+ print_bytes (tests[i].bytes, tests[i].byte_len);
+ printf ("\nactual: ");
+ print_bytes (beg, sz);
+ printf ("\n");
+ ++failures;
+ }
+ ret = (*decode) (beg, sz, val, &consumed_sz);
+ if (ret != 0) {
+ printf ("decoding of %s failed\n", tests[i].name);
+ ++failures;
+ }
+ if (sz != consumed_sz) {
+ printf ("different length decoding %s (%ld != %ld)\n",
+ tests[i].name,
+ (unsigned long)sz, (unsigned long)consumed_sz);
+ ++failures;
+ }
+ if ((*cmp)(val, tests[i].val) != 0) {
+ printf ("%s: comparison failed\n", tests[i].name);
+ ++failures;
+ }
+ }
+ free (val);
+ return failures;
+}
+
+static int
+cmp_integer (void *a, void *b)
+{
+ int *ia = (int *)a;
+ int *ib = (int *)b;
+
+ return *ib - *ia;
+}
+
+static int
+test_integer (void)
+{
+ struct test_case tests[] = {
+ {NULL, 3, "\x02\x01\x00"},
+ {NULL, 3, "\x02\x01\x7f"},
+ {NULL, 4, "\x02\x02\x00\x80"},
+ {NULL, 4, "\x02\x02\x01\x00"},
+ {NULL, 3, "\x02\x01\x80"},
+ {NULL, 4, "\x02\x02\xff\x7f"},
+ {NULL, 3, "\x02\x01\xff"},
+ {NULL, 4, "\x02\x02\xff\x01"},
+ {NULL, 4, "\x02\x02\x00\xff"},
+ {NULL, 6, "\x02\x04\x80\x00\x00\x00"},
+ {NULL, 6, "\x02\x04\x7f\xff\xff\xff"}
+ };
+
+ int values[] = {0, 127, 128, 256, -128, -129, -1, -255, 255,
+ 0x80000000, 0x7fffffff};
+ int i;
+ int ntests = sizeof(tests) / sizeof(*tests);
+
+ for (i = 0; i < ntests; ++i) {
+ tests[i].val = &values[i];
+ asprintf (&tests[i].name, "integer %d", values[i]);
+ }
+
+ return generic_test (tests, ntests, sizeof(int),
+ (int (*)(unsigned char *, size_t,
+ void *, size_t *))encode_integer,
+ (int (*)(void *))length_integer,
+ (int (*)(unsigned char *, size_t,
+ void *, size_t *))decode_integer,
+ cmp_integer);
+}
+
+static int
+cmp_octet_string (void *a, void *b)
+{
+ octet_string *oa = (octet_string *)a;
+ octet_string *ob = (octet_string *)b;
+
+ if (oa->length != ob->length)
+ return ob->length - oa->length;
+
+ return (memcmp (oa->data, ob->data, oa->length));
+}
+
+static int
+test_octet_string (void)
+{
+ octet_string s1 = {8, "\x01\x23\x45\x67\x89\xab\xcd\xef"};
+
+ struct test_case tests[] = {
+ {NULL, 10, "\x04\x08\x01\x23\x45\x67\x89\xab\xcd\xef"}
+ };
+ int ntests = sizeof(tests) / sizeof(*tests);
+
+ tests[0].val = &s1;
+ asprintf (&tests[0].name, "a octet string");
+
+ return generic_test (tests, ntests, sizeof(octet_string),
+ (int (*)(unsigned char *, size_t,
+ void *, size_t *))encode_octet_string,
+ (int (*)(void *))length_octet_string,
+ (int (*)(unsigned char *, size_t,
+ void *, size_t *))decode_octet_string,
+ cmp_octet_string);
+}
+
+static int
+cmp_general_string (void *a, void *b)
+{
+ unsigned char **sa = (unsigned char **)a;
+ unsigned char **sb = (unsigned char **)b;
+
+ return strcmp (*sa, *sb);
+}
+
+static int
+test_general_string (void)
+{
+ unsigned char *s1 = "Test User 1";
+
+ struct test_case tests[] = {
+ {NULL, 13, "\x1b\x0b\x54\x65\x73\x74\x20\x55\x73\x65\x72\x20\x31"}
+ };
+ int ntests = sizeof(tests) / sizeof(*tests);
+
+ tests[0].val = &s1;
+ asprintf (&tests[0].name, "the string \"%s\"", s1);
+
+ return generic_test (tests, ntests, sizeof(unsigned char *),
+ (int (*)(unsigned char *, size_t,
+ void *, size_t *))encode_general_string,
+ (int (*)(void *))length_general_string,
+ (int (*)(unsigned char *, size_t,
+ void *, size_t *))decode_general_string,
+ cmp_general_string);
+}
+
+static int
+cmp_generalized_time (void *a, void *b)
+{
+ time_t *ta = (time_t *)a;
+ time_t *tb = (time_t *)b;
+
+ return *tb - *ta;
+}
+
+static int
+test_generalized_time (void)
+{
+ struct test_case tests[] = {
+ {NULL, 17, "\x18\x0f""19700101000000Z"},
+ {NULL, 17, "\x18\x0f""19851106210627Z"}
+ };
+ time_t values[] = {0, 500159187};
+ int i;
+ int ntests = sizeof(tests) / sizeof(*tests);
+
+ for (i = 0; i < ntests; ++i) {
+ tests[i].val = &values[i];
+ asprintf (&tests[i].name, "time %d", (int)values[i]);
+ }
+
+ return generic_test (tests, ntests, sizeof(time_t),
+ (int (*)(unsigned char *, size_t,
+ void *, size_t *))encode_generalized_time,
+ (int (*)(void *))length_generalized_time,
+ (int (*)(unsigned char *, size_t,
+ void *, size_t *))decode_generalized_time,
+ cmp_generalized_time);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0;
+
+ ret += test_integer ();
+ ret += test_octet_string ();
+ ret += test_general_string ();
+ ret += test_generalized_time ();
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/asn1/der.h b/crypto/heimdal/lib/asn1/der.h
new file mode 100644
index 000000000000..37158af401dc
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/der.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: der.h,v 1.18 1999/12/02 17:05:01 joda Exp $ */
+
+#ifndef __DER_H__
+#define __DER_H__
+
+#include <time.h>
+
+typedef enum {UNIV = 0, APPL = 1, CONTEXT = 2 , PRIVATE = 3} Der_class;
+
+typedef enum {PRIM = 0, CONS = 1} Der_type;
+
+/* Universal tags */
+
+enum {
+ UT_Integer = 2,
+ UT_BitString = 3,
+ UT_OctetString = 4,
+ UT_Null = 5,
+ UT_ObjID = 6,
+ UT_Sequence = 16,
+ UT_Set = 17,
+ UT_PrintableString = 19,
+ UT_IA5String = 22,
+ UT_UTCTime = 23,
+ UT_GeneralizedTime = 24,
+ UT_VisibleString = 26,
+ UT_GeneralString = 27
+};
+
+#define ASN1_INDEFINITE 0xdce0deed
+
+#ifndef HAVE_TIMEGM
+time_t timegm (struct tm *);
+#endif
+
+void time2generalizedtime (time_t t, octet_string *s);
+
+int der_get_int (const unsigned char *p, size_t len, int *ret, size_t *size);
+int der_get_length (const unsigned char *p, size_t len,
+ size_t *val, size_t *size);
+int der_get_general_string (const unsigned char *p, size_t len,
+ general_string *str, size_t *size);
+int der_get_octet_string (const unsigned char *p, size_t len,
+ octet_string *data, size_t *size);
+int der_get_tag (const unsigned char *p, size_t len,
+ Der_class *class, Der_type *type,
+ int *tag, size_t *size);
+
+int der_match_tag (const unsigned char *p, size_t len,
+ Der_class class, Der_type type,
+ int tag, size_t *size);
+int der_match_tag_and_length (const unsigned char *p, size_t len,
+ Der_class class, Der_type type, int tag,
+ size_t *length_ret, size_t *size);
+
+int decode_integer (const unsigned char*, size_t, int*, size_t*);
+int decode_general_string (const unsigned char*, size_t,
+ general_string*, size_t*);
+int decode_octet_string (const unsigned char*, size_t, octet_string*, size_t*);
+int decode_generalized_time (const unsigned char*, size_t, time_t*, size_t*);
+
+int der_put_int (unsigned char *p, size_t len, int val, size_t*);
+int der_put_length (unsigned char *p, size_t len, size_t val, size_t*);
+int der_put_general_string (unsigned char *p, size_t len,
+ const general_string *str, size_t*);
+int der_put_octet_string (unsigned char *p, size_t len,
+ const octet_string *data, size_t*);
+int der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
+ int tag, size_t*);
+int der_put_length_and_tag (unsigned char*, size_t, size_t,
+ Der_class, Der_type, int, size_t*);
+
+int encode_integer (unsigned char *p, size_t len,
+ const int *data, size_t*);
+int encode_general_string (unsigned char *p, size_t len,
+ const general_string *data, size_t*);
+int encode_octet_string (unsigned char *p, size_t len,
+ const octet_string *k, size_t*);
+int encode_generalized_time (unsigned char *p, size_t len,
+ const time_t *t, size_t*);
+
+void free_integer (int *num);
+void free_general_string (general_string *str);
+void free_octet_string (octet_string *k);
+void free_generalized_time (time_t *t);
+
+size_t length_len (size_t len);
+size_t length_integer (const int *data);
+size_t length_general_string (const general_string *data);
+size_t length_octet_string (const octet_string *k);
+size_t length_generalized_time (const time_t *t);
+
+int copy_general_string (const general_string *from, general_string *to);
+int copy_octet_string (const octet_string *from, octet_string *to);
+
+int fix_dce(size_t reallen, size_t *len);
+
+#endif /* __DER_H__ */
+
diff --git a/crypto/heimdal/lib/asn1/der_copy.c b/crypto/heimdal/lib/asn1/der_copy.c
new file mode 100644
index 000000000000..83c244629be0
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/der_copy.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "der_locl.h"
+
+RCSID("$Id: der_copy.c,v 1.8 1999/12/02 17:05:01 joda Exp $");
+
+int
+copy_general_string (const general_string *from, general_string *to)
+{
+ *to = malloc(strlen(*from) + 1);
+ if(*to == NULL)
+ return ENOMEM;
+ strcpy(*to, *from);
+ return 0;
+}
+
+int
+copy_octet_string (const octet_string *from, octet_string *to)
+{
+ to->length = from->length;
+ to->data = malloc(to->length);
+ if(to->length != 0 && to->data == NULL)
+ return ENOMEM;
+ memcpy(to->data, from->data, to->length);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/asn1/der_free.c b/crypto/heimdal/lib/asn1/der_free.c
new file mode 100644
index 000000000000..7191e4e90c31
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/der_free.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "der_locl.h"
+
+RCSID("$Id: der_free.c,v 1.7 1999/12/02 17:05:01 joda Exp $");
+
+void
+free_general_string (general_string *str)
+{
+ free(*str);
+}
+
+void
+free_octet_string (octet_string *k)
+{
+ free(k->data);
+}
diff --git a/crypto/heimdal/lib/asn1/der_get.c b/crypto/heimdal/lib/asn1/der_get.c
new file mode 100644
index 000000000000..9f0616bcef6d
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/der_get.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "der_locl.h"
+
+RCSID("$Id: der_get.c,v 1.27 1999/12/02 17:05:01 joda Exp $");
+
+#include <version.h>
+
+/*
+ * All decoding functions take a pointer `p' to first position in
+ * which to read, from the left, `len' which means the maximum number
+ * of characters we are able to read, `ret' were the value will be
+ * returned and `size' where the number of used bytes is stored.
+ * Either 0 or an error code is returned.
+ */
+
+static int
+der_get_unsigned (const unsigned char *p, size_t len,
+ unsigned *ret, size_t *size)
+{
+ unsigned val = 0;
+ size_t oldlen = len;
+
+ while (len--)
+ val = val * 256 + *p++;
+ *ret = val;
+ if(size) *size = oldlen;
+ return 0;
+}
+
+int
+der_get_int (const unsigned char *p, size_t len,
+ int *ret, size_t *size)
+{
+ int val = 0;
+ size_t oldlen = len;
+
+ if (len--)
+ val = (signed char)*p++;
+ while (len--)
+ val = val * 256 + *p++;
+ *ret = val;
+ if(size) *size = oldlen;
+ return 0;
+}
+
+int
+der_get_length (const unsigned char *p, size_t len,
+ size_t *val, size_t *size)
+{
+ size_t v;
+
+ if (len <= 0)
+ return ASN1_OVERRUN;
+ --len;
+ v = *p++;
+ if (v < 128) {
+ *val = v;
+ if(size) *size = 1;
+ } else {
+ int e;
+ size_t l;
+ unsigned tmp;
+
+ if(v == 0x80){
+ *val = ASN1_INDEFINITE;
+ if(size) *size = 1;
+ return 0;
+ }
+ v &= 0x7F;
+ if (len < v)
+ return ASN1_OVERRUN;
+ e = der_get_unsigned (p, v, &tmp, &l);
+ if(e) return e;
+ *val = tmp;
+ if(size) *size = l + 1;
+ }
+ return 0;
+}
+
+int
+der_get_general_string (const unsigned char *p, size_t len,
+ general_string *str, size_t *size)
+{
+ char *s;
+
+ s = malloc (len + 1);
+ if (s == NULL)
+ return ENOMEM;
+ memcpy (s, p, len);
+ s[len] = '\0';
+ *str = s;
+ if(size) *size = len;
+ return 0;
+}
+
+int
+der_get_octet_string (const unsigned char *p, size_t len,
+ octet_string *data, size_t *size)
+{
+ data->length = len;
+ data->data = malloc(len);
+ if (data->data == NULL && data->length != 0)
+ return ENOMEM;
+ memcpy (data->data, p, len);
+ if(size) *size = len;
+ return 0;
+}
+
+int
+der_get_tag (const unsigned char *p, size_t len,
+ Der_class *class, Der_type *type,
+ int *tag, size_t *size)
+{
+ if (len < 1)
+ return ASN1_OVERRUN;
+ *class = (Der_class)(((*p) >> 6) & 0x03);
+ *type = (Der_type)(((*p) >> 5) & 0x01);
+ *tag = (*p) & 0x1F;
+ if(size) *size = 1;
+ return 0;
+}
+
+int
+der_match_tag (const unsigned char *p, size_t len,
+ Der_class class, Der_type type,
+ int tag, size_t *size)
+{
+ size_t l;
+ Der_class thisclass;
+ Der_type thistype;
+ int thistag;
+ int e;
+
+ e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
+ if (e) return e;
+ if (class != thisclass || type != thistype)
+ return ASN1_BAD_ID;
+ if(tag > thistag)
+ return ASN1_MISPLACED_FIELD;
+ if(tag < thistag)
+ return ASN1_MISSING_FIELD;
+ if(size) *size = l;
+ return 0;
+}
+
+int
+der_match_tag_and_length (const unsigned char *p, size_t len,
+ Der_class class, Der_type type, int tag,
+ size_t *length_ret, size_t *size)
+{
+ size_t l, ret = 0;
+ int e;
+
+ e = der_match_tag (p, len, class, type, tag, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ e = der_get_length (p, len, length_ret, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ if(size) *size = ret;
+ return 0;
+}
+
+int
+decode_integer (const unsigned char *p, size_t len,
+ int *num, size_t *size)
+{
+ size_t ret = 0;
+ size_t l, reallen;
+ int e;
+
+ e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ e = der_get_length (p, len, &reallen, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ e = der_get_int (p, reallen, num, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ if(size) *size = ret;
+ return 0;
+}
+
+int
+decode_general_string (const unsigned char *p, size_t len,
+ general_string *str, size_t *size)
+{
+ size_t ret = 0;
+ size_t l;
+ int e;
+ size_t slen;
+
+ e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+
+ e = der_get_length (p, len, &slen, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ if (len < slen)
+ return ASN1_OVERRUN;
+
+ e = der_get_general_string (p, slen, str, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ if(size) *size = ret;
+ return 0;
+}
+
+int
+decode_octet_string (const unsigned char *p, size_t len,
+ octet_string *k, size_t *size)
+{
+ size_t ret = 0;
+ size_t l;
+ int e;
+ size_t slen;
+
+ e = der_match_tag (p, len, UNIV, PRIM, UT_OctetString, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+
+ e = der_get_length (p, len, &slen, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ if (len < slen)
+ return ASN1_OVERRUN;
+
+ e = der_get_octet_string (p, slen, k, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ if(size) *size = ret;
+ return 0;
+}
+
+static void
+generalizedtime2time (const char *s, time_t *t)
+{
+ struct tm tm;
+
+ memset(&tm, 0, sizeof(tm));
+ sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
+ &tm.tm_min, &tm.tm_sec);
+ tm.tm_year -= 1900;
+ tm.tm_mon -= 1;
+ *t = timegm (&tm);
+}
+
+int
+decode_generalized_time (const unsigned char *p, size_t len,
+ time_t *t, size_t *size)
+{
+ octet_string k;
+ char *times;
+ size_t ret = 0;
+ size_t l;
+ int e;
+ size_t slen;
+
+ e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+
+ e = der_get_length (p, len, &slen, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ if (len < slen)
+ return ASN1_OVERRUN;
+ e = der_get_octet_string (p, slen, &k, &l);
+ if (e) return e;
+ p += l;
+ len -= l;
+ ret += l;
+ times = realloc(k.data, k.length + 1);
+ if (times == NULL){
+ free(k.data);
+ return ENOMEM;
+ }
+ times[k.length] = 0;
+ generalizedtime2time (times, t);
+ free (times);
+ if(size) *size = ret;
+ return 0;
+}
+
+
+int
+fix_dce(size_t reallen, size_t *len)
+{
+ if(reallen == ASN1_INDEFINITE)
+ return 1;
+ if(*len < reallen)
+ return -1;
+ *len = reallen;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/asn1/der_length.c b/crypto/heimdal/lib/asn1/der_length.c
new file mode 100644
index 000000000000..5db95bae37cb
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/der_length.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "der_locl.h"
+
+RCSID("$Id: der_length.c,v 1.10 1999/12/02 17:05:01 joda Exp $");
+
+static size_t
+length_unsigned (unsigned val)
+{
+ size_t ret = 0;
+
+ do {
+ ++ret;
+ val /= 256;
+ } while (val);
+ return ret;
+}
+
+static size_t
+length_int (int val)
+{
+ size_t ret = 0;
+
+ if (val == 0)
+ return 1;
+ while (val > 255 || val < -255) {
+ ++ret;
+ val /= 256;
+ }
+ if (val != 0) {
+ ++ret;
+ if ((signed char)val != val)
+ ++ret;
+ val /= 256;
+ }
+ return ret;
+}
+
+size_t
+length_len (size_t len)
+{
+ if (len < 128)
+ return 1;
+ else
+ return length_unsigned (len) + 1;
+}
+
+size_t
+length_integer (const int *data)
+{
+ size_t len = length_int (*data);
+
+ return 1 + length_len(len) + len;
+}
+
+size_t
+length_general_string (const general_string *data)
+{
+ char *str = *data;
+ size_t len = strlen(str);
+ return 1 + length_len(len) + len;
+}
+
+size_t
+length_octet_string (const octet_string *k)
+{
+ return 1 + length_len(k->length) + k->length;
+}
+
+size_t
+length_generalized_time (const time_t *t)
+{
+ octet_string k;
+ size_t ret;
+
+ time2generalizedtime (*t, &k);
+ ret = 1 + length_len(k.length) + k.length;
+ free (k.data);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/asn1/der_locl.h b/crypto/heimdal/lib/asn1/der_locl.h
new file mode 100644
index 000000000000..6eeb42d40b33
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/der_locl.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: der_locl.h,v 1.3 1999/12/02 17:05:02 joda Exp $ */
+
+#ifndef __DER_LOCL_H__
+#define __DER_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+#include <time.h>
+#include <errno.h>
+#include <roken.h>
+
+#include <libasn1.h>
+
+#endif /* __DER_LOCL_H__ */
diff --git a/crypto/heimdal/lib/asn1/der_put.c b/crypto/heimdal/lib/asn1/der_put.c
new file mode 100644
index 000000000000..ce2165461d4d
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/der_put.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "der_locl.h"
+
+RCSID("$Id: der_put.c,v 1.22 1999/12/02 17:05:02 joda Exp $");
+
+/*
+ * All encoding functions take a pointer `p' to first position in
+ * which to write, from the right, `len' which means the maximum
+ * number of characters we are able to write and return an int
+ * indicating how many actually got written, or <0 in case of errors.
+ */
+
+static int
+der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
+{
+ unsigned char *base = p;
+
+ if (val) {
+ while (len > 0 && val) {
+ *p-- = val % 256;
+ val /= 256;
+ --len;
+ }
+ if (val != 0)
+ return ASN1_OVERFLOW;
+ else {
+ *size = base - p;
+ return 0;
+ }
+ } else if (len < 1)
+ return ASN1_OVERFLOW;
+ else {
+ *p = 0;
+ *size = 1;
+ return 0;
+ }
+}
+
+int
+der_put_int (unsigned char *p, size_t len, int val, size_t *size)
+{
+ unsigned char *base = p;
+
+ if(val >= 0) {
+ do {
+ if(len < 1)
+ return ASN1_OVERFLOW;
+ *p-- = val % 256;
+ len--;
+ val /= 256;
+ } while(val);
+ if(p[1] >= 128) {
+ if(len < 1)
+ return ASN1_OVERFLOW;
+ *p-- = 0;
+ len--;
+ }
+ } else {
+ val = ~val;
+ do {
+ if(len < 1)
+ return ASN1_OVERFLOW;
+ *p-- = ~(val % 256);
+ len--;
+ val /= 256;
+ } while(val);
+ if(p[1] < 128) {
+ if(len < 1)
+ return ASN1_OVERFLOW;
+ *p-- = 0xff;
+ len--;
+ }
+ }
+ *size = base - p;
+ return 0;
+}
+
+
+int
+der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
+{
+ if (val < 128) {
+ if (len < 1)
+ return ASN1_OVERFLOW;
+ else {
+ *p = val;
+ *size = 1;
+ return 0;
+ }
+ } else {
+ size_t l;
+ int e;
+
+ e = der_put_unsigned (p, len - 1, val, &l);
+ if (e)
+ return e;
+ p -= l;
+ *p = 0x80 | l;
+ *size = l + 1;
+ return 0;
+ }
+}
+
+int
+der_put_general_string (unsigned char *p, size_t len,
+ const general_string *str, size_t *size)
+{
+ size_t slen = strlen(*str);
+
+ if (len < slen)
+ return ASN1_OVERFLOW;
+ p -= slen;
+ len -= slen;
+ memcpy (p+1, *str, slen);
+ *size = slen;
+ return 0;
+}
+
+int
+der_put_octet_string (unsigned char *p, size_t len,
+ const octet_string *data, size_t *size)
+{
+ if (len < data->length)
+ return ASN1_OVERFLOW;
+ p -= data->length;
+ len -= data->length;
+ memcpy (p+1, data->data, data->length);
+ *size = data->length;
+ return 0;
+}
+
+int
+der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
+ int tag, size_t *size)
+{
+ if (len < 1)
+ return ASN1_OVERFLOW;
+ *p = (class << 6) | (type << 5) | tag; /* XXX */
+ *size = 1;
+ return 0;
+}
+
+int
+der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
+ Der_class class, Der_type type, int tag, size_t *size)
+{
+ size_t ret = 0;
+ size_t l;
+ int e;
+
+ e = der_put_length (p, len, len_val, &l);
+ if(e)
+ return e;
+ p -= l;
+ len -= l;
+ ret += l;
+ e = der_put_tag (p, len, class, type, tag, &l);
+ if(e)
+ return e;
+ p -= l;
+ len -= l;
+ ret += l;
+ *size = ret;
+ return 0;
+}
+
+int
+encode_integer (unsigned char *p, size_t len, const int *data, size_t *size)
+{
+ int num = *data;
+ size_t ret = 0;
+ size_t l;
+ int e;
+
+ e = der_put_int (p, len, num, &l);
+ if(e)
+ return e;
+ p -= l;
+ len -= l;
+ ret += l;
+ e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Integer, &l);
+ if (e)
+ return e;
+ p -= l;
+ len -= l;
+ ret += l;
+ *size = ret;
+ return 0;
+}
+
+int
+encode_general_string (unsigned char *p, size_t len,
+ const general_string *data, size_t *size)
+{
+ size_t ret = 0;
+ size_t l;
+ int e;
+
+ e = der_put_general_string (p, len, data, &l);
+ if (e)
+ return e;
+ p -= l;
+ len -= l;
+ ret += l;
+ e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_GeneralString, &l);
+ if (e)
+ return e;
+ p -= l;
+ len -= l;
+ ret += l;
+ *size = ret;
+ return 0;
+}
+
+int
+encode_octet_string (unsigned char *p, size_t len,
+ const octet_string *k, size_t *size)
+{
+ size_t ret = 0;
+ size_t l;
+ int e;
+
+ e = der_put_octet_string (p, len, k, &l);
+ if (e)
+ return e;
+ p -= l;
+ len -= l;
+ ret += l;
+ e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_OctetString, &l);
+ if (e)
+ return e;
+ p -= l;
+ len -= l;
+ ret += l;
+ *size = ret;
+ return 0;
+}
+
+void
+time2generalizedtime (time_t t, octet_string *s)
+{
+ struct tm *tm;
+
+ s->data = malloc(16);
+ s->length = 15;
+ tm = gmtime (&t);
+ sprintf (s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900,
+ tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
+ tm->tm_sec);
+}
+
+int
+encode_generalized_time (unsigned char *p, size_t len,
+ const time_t *t, size_t *size)
+{
+ size_t ret = 0;
+ size_t l;
+ octet_string k;
+ int e;
+
+ time2generalizedtime (*t, &k);
+ e = der_put_octet_string (p, len, &k, &l);
+ free (k.data);
+ if (e)
+ return e;
+ p -= l;
+ len -= l;
+ ret += l;
+ e = der_put_length_and_tag (p, len, k.length, UNIV, PRIM,
+ UT_GeneralizedTime, &l);
+ if (e)
+ return e;
+ p -= l;
+ len -= l;
+ ret += l;
+ *size = ret;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/asn1/gen.c b/crypto/heimdal/lib/asn1/gen.c
new file mode 100644
index 000000000000..bca45168951e
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/gen.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gen_locl.h"
+
+RCSID("$Id: gen.c,v 1.41 1999/12/02 17:05:02 joda Exp $");
+
+FILE *headerfile, *codefile, *logfile;
+
+#define STEM "asn1"
+
+static char *orig_filename;
+static char header[1024];
+static char headerbase[1024] = STEM;
+
+void
+init_generate (char *filename, char *base)
+{
+ orig_filename = filename;
+ if(base)
+ strcpy(headerbase, base);
+ sprintf(header, "%s.h", headerbase);
+ headerfile = fopen (header, "w");
+ if (headerfile == NULL)
+ err (1, "open %s", header);
+ fprintf (headerfile,
+ "/* Generated from %s */\n"
+ "/* Do not edit */\n\n",
+ filename);
+ fprintf (headerfile,
+ "#ifndef __%s_h__\n"
+ "#define __%s_h__\n\n", headerbase, headerbase);
+ fprintf (headerfile,
+ "#include <stddef.h>\n"
+ "#include <time.h>\n\n");
+#ifndef HAVE_TIMEGM
+ fprintf (headerfile, "time_t timegm (struct tm*);\n\n");
+#endif
+ fprintf (headerfile,
+ "#ifndef __asn1_common_definitions__\n"
+ "#define __asn1_common_definitions__\n\n");
+ fprintf (headerfile,
+ "typedef struct octet_string {\n"
+ " size_t length;\n"
+ " void *data;\n"
+ "} octet_string;\n\n");
+ fprintf (headerfile,
+#if 0
+ "typedef struct general_string {\n"
+ " size_t length;\n"
+ " char *data;\n"
+ "} general_string;\n\n"
+#else
+ "typedef char *general_string;\n\n"
+#endif
+ );
+ fprintf (headerfile, "#endif\n\n");
+ logfile = fopen(STEM "_files", "w");
+ if (logfile == NULL)
+ err (1, "open " STEM "_files");
+}
+
+void
+close_generate ()
+{
+ fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase);
+
+ fclose (headerfile);
+ fprintf (logfile, "\n");
+ fclose (logfile);
+}
+
+void
+generate_constant (const Symbol *s)
+{
+ fprintf (headerfile, "enum { %s = %d };\n\n",
+ s->gen_name, s->constant);
+}
+
+static void
+space(int level)
+{
+ while(level-- > 0)
+ fprintf(headerfile, " ");
+}
+
+static void
+define_asn1 (int level, Type *t)
+{
+ switch (t->type) {
+ case TType:
+ space(level);
+ fprintf (headerfile, "%s", t->symbol->name);
+ break;
+ case TInteger:
+ space(level);
+ fprintf (headerfile, "INTEGER");
+ break;
+ case TOctetString:
+ space(level);
+ fprintf (headerfile, "OCTET STRING");
+ break;
+ case TBitString: {
+ Member *m;
+ Type i;
+ int tag = -1;
+
+ i.type = TInteger;
+ space(level);
+ fprintf (headerfile, "BIT STRING {\n");
+ for (m = t->members; m && m->val != tag; m = m->next) {
+ if (tag == -1)
+ tag = m->val;
+ space(level + 1);
+ fprintf (headerfile, "%s(%d)%s\n", m->name, m->val,
+ m->next->val == tag?"":",");
+
+ }
+ space(level);
+ fprintf (headerfile, "}");
+ break;
+ }
+ case TSequence: {
+ Member *m;
+ int tag;
+ int max_width = 0;
+
+ space(level);
+ fprintf (headerfile, "SEQUENCE {\n");
+ for (m = t->members, tag = -1; m && m->val != tag; m = m->next) {
+ if (tag == -1)
+ tag = m->val;
+ if(strlen(m->name) + (m->val > 9) > max_width)
+ max_width = strlen(m->name) + (m->val > 9);
+ }
+ max_width += 3 + 2;
+ if(max_width < 16) max_width = 16;
+ for (m = t->members, tag = -1 ; m && m->val != tag; m = m->next) {
+ int width;
+ if (tag == -1)
+ tag = m->val;
+ space(level + 1);
+ fprintf(headerfile, "%s[%d]", m->name, m->val);
+ width = max_width - strlen(m->name) - 3 - (m->val > 9) - 2;
+ fprintf(headerfile, "%*s", width, "");
+ define_asn1(level + 1, m->type);
+ if(m->optional)
+ fprintf(headerfile, " OPTIONAL");
+ if(m->next->val != tag)
+ fprintf (headerfile, ",");
+ fprintf (headerfile, "\n");
+ }
+ space(level);
+ fprintf (headerfile, "}");
+ break;
+ }
+ case TSequenceOf: {
+ space(level);
+ fprintf (headerfile, "SEQUENCE OF ");
+ define_asn1 (0, t->subtype);
+ break;
+ }
+ case TGeneralizedTime:
+ space(level);
+ fprintf (headerfile, "GeneralizedTime");
+ break;
+ case TGeneralString:
+ space(level);
+ fprintf (headerfile, "GeneralString");
+ break;
+ case TApplication:
+ fprintf (headerfile, "[APPLICATION %d] ", t->application);
+ define_asn1 (level, t->subtype);
+ break;
+ default:
+ abort ();
+ }
+}
+
+static void
+define_type (int level, char *name, Type *t, int typedefp)
+{
+ switch (t->type) {
+ case TType:
+ space(level);
+ fprintf (headerfile, "%s %s;\n", t->symbol->gen_name, name);
+ break;
+ case TInteger:
+ space(level);
+ fprintf (headerfile, "int %s;\n", name);
+ break;
+ case TUInteger:
+ space(level);
+ fprintf (headerfile, "unsigned int %s;\n", name);
+ break;
+ case TOctetString:
+ space(level);
+ fprintf (headerfile, "octet_string %s;\n", name);
+ break;
+ case TBitString: {
+ Member *m;
+ Type i;
+ int tag = -1;
+
+ i.type = TUInteger;
+ space(level);
+ fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
+ for (m = t->members; m && m->val != tag; m = m->next) {
+ char *n;
+
+ asprintf (&n, "%s:1", m->gen_name);
+ define_type (level + 1, n, &i, FALSE);
+ free (n);
+ if (tag == -1)
+ tag = m->val;
+ }
+ space(level);
+ fprintf (headerfile, "} %s;\n\n", name);
+ break;
+ }
+ case TSequence: {
+ Member *m;
+ int tag = -1;
+
+ space(level);
+ fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
+ for (m = t->members; m && m->val != tag; m = m->next) {
+ if (m->optional) {
+ char *n;
+
+ asprintf (&n, "*%s", m->gen_name);
+ define_type (level + 1, n, m->type, FALSE);
+ free (n);
+ } else
+ define_type (level + 1, m->gen_name, m->type, FALSE);
+ if (tag == -1)
+ tag = m->val;
+ }
+ space(level);
+ fprintf (headerfile, "} %s;\n", name);
+ break;
+ }
+ case TSequenceOf: {
+ Type i;
+
+ i.type = TUInteger;
+ i.application = 0;
+
+ space(level);
+ fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
+ define_type (level + 1, "len", &i, FALSE);
+ define_type (level + 1, "*val", t->subtype, FALSE);
+ space(level);
+ fprintf (headerfile, "} %s;\n", name);
+ break;
+ }
+ case TGeneralizedTime:
+ space(level);
+ fprintf (headerfile, "time_t %s;\n", name);
+ break;
+ case TGeneralString:
+ space(level);
+ fprintf (headerfile, "general_string %s;\n", name);
+ break;
+ case TApplication:
+ define_type (level, name, t->subtype, FALSE);
+ break;
+ default:
+ abort ();
+ }
+}
+
+static void
+generate_type_header (const Symbol *s)
+{
+ fprintf (headerfile, "/*\n");
+ fprintf (headerfile, "%s ::= ", s->name);
+ define_asn1 (0, s->type);
+ fprintf (headerfile, "\n*/\n\n");
+
+ fprintf (headerfile, "typedef ");
+ define_type (0, s->gen_name, s->type, TRUE);
+
+ fprintf (headerfile, "\n");
+}
+
+
+void
+generate_type (const Symbol *s)
+{
+ char *filename;
+
+ asprintf (&filename, "%s_%s.x", STEM, s->gen_name);
+ codefile = fopen (filename, "w");
+ if (codefile == NULL)
+ err (1, "fopen %s", filename);
+ fprintf(logfile, "%s ", filename);
+ free(filename);
+ fprintf (codefile,
+ "/* Generated from %s */\n"
+ "/* Do not edit */\n\n"
+ "#include \"libasn1.h\"\n\n"
+#if 0
+ "#include <stdio.h>\n"
+ "#include <stdlib.h>\n"
+ "#include <time.h>\n"
+ "#include <" STEM ".h>\n\n"
+ "#include <asn1_err.h>\n"
+ "#include <der.h>\n"
+#endif
+ ,orig_filename);
+ generate_type_header (s);
+ generate_type_encode (s);
+ generate_type_decode (s);
+ generate_type_free (s);
+ generate_type_length (s);
+ generate_type_copy (s);
+ generate_glue (s);
+ fprintf(headerfile, "\n\n");
+ fclose(codefile);
+}
diff --git a/crypto/heimdal/lib/asn1/gen.h b/crypto/heimdal/lib/asn1/gen.h
new file mode 100644
index 000000000000..369b6e392acd
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/gen.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: gen.h,v 1.4 1999/12/02 17:05:02 joda Exp $ */
+
+#include <stdio.h>
+#include "symbol.h"
+
diff --git a/crypto/heimdal/lib/asn1/gen_copy.c b/crypto/heimdal/lib/asn1/gen_copy.c
new file mode 100644
index 000000000000..f9aa4894c887
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/gen_copy.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gen_locl.h"
+
+RCSID("$Id: gen_copy.c,v 1.10 1999/12/02 17:05:02 joda Exp $");
+
+static void
+copy_primitive (const char *typename, const char *from, const char *to)
+{
+ fprintf (codefile, "if(copy_%s(%s, %s)) return ENOMEM;\n",
+ typename, from, to);
+}
+
+static void
+copy_type (const char *from, const char *to, const Type *t)
+{
+ switch (t->type) {
+ case TType:
+#if 0
+ copy_type (from, to, t->symbol->type);
+#endif
+ fprintf (codefile, "if(copy_%s(%s, %s)) return ENOMEM;\n",
+ t->symbol->gen_name, from, to);
+ break;
+ case TInteger:
+ fprintf(codefile, "*(%s) = *(%s);\n", to, from);
+ break;
+ case TOctetString:
+ copy_primitive ("octet_string", from, to);
+ break;
+ case TBitString: {
+ fprintf(codefile, "*(%s) = *(%s);\n", to, from);
+ break;
+ }
+ case TSequence: {
+ Member *m;
+ int tag = -1;
+
+ if (t->members == NULL)
+ break;
+
+ for (m = t->members; m && tag != m->val; m = m->next) {
+ char *f;
+ char *t;
+
+ asprintf (&f, "%s(%s)->%s",
+ m->optional ? "" : "&", from, m->gen_name);
+ asprintf (&t, "%s(%s)->%s",
+ m->optional ? "" : "&", to, m->gen_name);
+ if(m->optional){
+ fprintf(codefile, "if(%s) {\n", f);
+ fprintf(codefile, "%s = malloc(sizeof(*%s));\n", t, t);
+ fprintf(codefile, "if(%s == NULL) return ENOMEM;\n", t);
+ }
+ copy_type (f, t, m->type);
+ if(m->optional){
+ fprintf(codefile, "}else\n");
+ fprintf(codefile, "%s = NULL;\n", t);
+ }
+ if (tag == -1)
+ tag = m->val;
+ free (f);
+ free (t);
+ }
+ break;
+ }
+ case TSequenceOf: {
+ char *f;
+ char *T;
+
+ fprintf (codefile, "if(((%s)->val = "
+ "malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n",
+ to, from, to, from);
+ fprintf (codefile, "return ENOMEM;\n");
+ fprintf(codefile,
+ "for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
+ to, to, from, to);
+ asprintf(&f, "&(%s)->val[(%s)->len]", from, to);
+ asprintf(&T, "&(%s)->val[(%s)->len]", to, to);
+ copy_type(f, T, t->subtype);
+ fprintf(codefile, "}\n");
+ free(f);
+ free(T);
+ break;
+ }
+ case TGeneralizedTime:
+ fprintf(codefile, "*(%s) = *(%s);\n", to, from);
+ break;
+ case TGeneralString:
+ copy_primitive ("general_string", from, to);
+ break;
+ case TApplication:
+ copy_type (from, to, t->subtype);
+ break;
+ default :
+ abort ();
+ }
+}
+
+void
+generate_type_copy (const Symbol *s)
+{
+ fprintf (headerfile,
+ "int copy_%s (const %s *, %s *);\n",
+ s->gen_name, s->gen_name, s->gen_name);
+
+ fprintf (codefile, "int\n"
+ "copy_%s(const %s *from, %s *to)\n"
+ "{\n",
+ s->gen_name, s->gen_name, s->gen_name);
+
+ copy_type ("from", "to", s->type);
+ fprintf (codefile, "return 0;\n}\n\n");
+}
+
diff --git a/crypto/heimdal/lib/asn1/gen_decode.c b/crypto/heimdal/lib/asn1/gen_decode.c
new file mode 100644
index 000000000000..078ac44527a2
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/gen_decode.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gen_locl.h"
+
+RCSID("$Id: gen_decode.c,v 1.11 1999/12/02 17:05:02 joda Exp $");
+
+static void
+decode_primitive (const char *typename, const char *name)
+{
+ fprintf (codefile,
+ "e = decode_%s(p, len, %s, &l);\n"
+ "FORW;\n",
+ typename,
+ name);
+}
+
+static void
+decode_type (const char *name, const Type *t)
+{
+ switch (t->type) {
+ case TType:
+#if 0
+ decode_type (name, t->symbol->type);
+#endif
+ fprintf (codefile,
+ "e = decode_%s(p, len, %s, &l);\n"
+ "FORW;\n",
+ t->symbol->gen_name, name);
+ break;
+ case TInteger:
+ decode_primitive ("integer", name);
+ break;
+ case TOctetString:
+ decode_primitive ("octet_string", name);
+ break;
+ case TBitString: {
+ Member *m;
+ int tag = -1;
+ int pos;
+
+ fprintf (codefile,
+ "e = der_match_tag_and_length (p, len, UNIV, PRIM, UT_BitString,"
+ "&reallen, &l);\n"
+ "FORW;\n"
+ "if(len < reallen)\n"
+ "return ASN1_OVERRUN;\n"
+ "p++;\n"
+ "len--;\n"
+ "reallen--;\n"
+ "ret++;\n");
+ pos = 0;
+ for (m = t->members; m && tag != m->val; m = m->next) {
+ while (m->val / 8 > pos / 8) {
+ fprintf (codefile,
+ "p++; len--; reallen--; ret++;\n");
+ pos += 8;
+ }
+ fprintf (codefile,
+ "%s->%s = (*p >> %d) & 1;\n",
+ name, m->gen_name, 7 - m->val % 8);
+ if (tag == -1)
+ tag = m->val;
+ }
+ fprintf (codefile,
+ "p += reallen; len -= reallen; ret += reallen;\n");
+ break;
+ }
+ case TSequence: {
+ Member *m;
+ int tag = -1;
+
+ if (t->members == NULL)
+ break;
+
+ fprintf (codefile,
+ "e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
+ "&reallen, &l);\n"
+ "FORW;\n"
+ "{\n"
+ "int dce_fix;\n"
+ "if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
+ "return ASN1_BAD_FORMAT;\n");
+
+ for (m = t->members; m && tag != m->val; m = m->next) {
+ char *s;
+
+ asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
+ if (0 && m->type->type == TType){
+ if(m->optional)
+ fprintf (codefile,
+ "%s = malloc(sizeof(*%s));\n", s, s);
+ fprintf (codefile,
+ "e = decode_seq_%s(p, len, %d, %d, %s, &l);\n",
+ m->type->symbol->gen_name,
+ m->val,
+ m->optional,
+ s);
+ if(m->optional)
+ fprintf (codefile,
+ "if (e == ASN1_MISSING_FIELD) {\n"
+ "free(%s);\n"
+ "%s = NULL;\n"
+ "e = l = 0;\n"
+ "}\n",
+ s, s);
+
+ fprintf (codefile, "FORW;\n");
+
+ }else{
+ fprintf (codefile, "{\n"
+ "size_t newlen, oldlen;\n\n"
+ "e = der_match_tag (p, len, CONTEXT, CONS, %d, &l);\n",
+ m->val);
+ fprintf (codefile,
+ "if (e)\n");
+ if(m->optional)
+ /* XXX should look at e */
+ fprintf (codefile,
+ "%s = NULL;\n", s);
+ else
+ fprintf (codefile,
+ "return e;\n");
+ fprintf (codefile,
+ "else {\n");
+ fprintf (codefile,
+ "p += l;\n"
+ "len -= l;\n"
+ "ret += l;\n"
+ "e = der_get_length (p, len, &newlen, &l);\n"
+ "FORW;\n"
+ "{\n"
+
+ "int dce_fix;\n"
+ "oldlen = len;\n"
+ "if((dce_fix = fix_dce(newlen, &len)) < 0)"
+ "return ASN1_BAD_FORMAT;\n");
+ if (m->optional)
+ fprintf (codefile,
+ "%s = malloc(sizeof(*%s));\n",
+ s, s);
+ decode_type (s, m->type);
+ fprintf (codefile,
+ "if(dce_fix){\n"
+ "e = der_match_tag_and_length (p, len, "
+ "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
+ "FORW;\n"
+ "}else \n"
+ "len = oldlen - newlen;\n"
+ "}\n"
+ "}\n");
+ fprintf (codefile,
+ "}\n");
+ }
+ if (tag == -1)
+ tag = m->val;
+ free (s);
+ }
+ fprintf(codefile,
+ "if(dce_fix){\n"
+ "e = der_match_tag_and_length (p, len, "
+ "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
+ "FORW;\n"
+ "}\n"
+ "}\n");
+
+ break;
+ }
+ case TSequenceOf: {
+ char *n;
+
+ fprintf (codefile,
+ "e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
+ "&reallen, &l);\n"
+ "FORW;\n"
+ "if(len < reallen)\n"
+ "return ASN1_OVERRUN;\n"
+ "len = reallen;\n");
+
+ fprintf (codefile,
+ "{\n"
+ "size_t origlen = len;\n"
+ "int oldret = ret;\n"
+ "ret = 0;\n"
+ "(%s)->len = 0;\n"
+ "(%s)->val = NULL;\n"
+ "while(ret < origlen) {\n"
+ "(%s)->len++;\n"
+ "(%s)->val = realloc((%s)->val, sizeof(*((%s)->val)) * (%s)->len);\n",
+ name, name, name, name, name, name, name);
+ asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
+ decode_type (n, t->subtype);
+ fprintf (codefile,
+ "len = origlen - ret;\n"
+ "}\n"
+ "ret += oldret;\n"
+ "}\n");
+ free (n);
+ break;
+ }
+ case TGeneralizedTime:
+ decode_primitive ("generalized_time", name);
+ break;
+ case TGeneralString:
+ decode_primitive ("general_string", name);
+ break;
+ case TApplication:
+ fprintf (codefile,
+ "e = der_match_tag_and_length (p, len, APPL, CONS, %d, "
+ "&reallen, &l);\n"
+ "FORW;\n"
+ "{\n"
+ "int dce_fix;\n"
+ "if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
+ "return ASN1_BAD_FORMAT;\n",
+ t->application);
+ decode_type (name, t->subtype);
+ fprintf(codefile,
+ "if(dce_fix){\n"
+ "e = der_match_tag_and_length (p, len, "
+ "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
+ "FORW;\n"
+ "}\n"
+ "}\n");
+
+ break;
+ default :
+ abort ();
+ }
+}
+
+void
+generate_type_decode (const Symbol *s)
+{
+ fprintf (headerfile,
+ "int "
+ "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
+ s->gen_name, s->gen_name);
+
+ fprintf (codefile, "#define FORW "
+ "if(e) return e; "
+ "p += l; "
+ "len -= l; "
+ "ret += l\n\n");
+
+
+ fprintf (codefile, "int\n"
+ "decode_%s(const unsigned char *p,"
+ " size_t len, %s *data, size_t *size)\n"
+ "{\n",
+ s->gen_name, s->gen_name);
+
+ switch (s->type->type) {
+ case TInteger:
+ fprintf (codefile, "return decode_integer (p, len, data, size);\n");
+ break;
+ case TOctetString:
+ fprintf (codefile, "return decode_octet_string (p, len, data, size);\n");
+ break;
+ case TGeneralizedTime:
+ fprintf (codefile, "return decode_generalized_time (p, len, data, size);\n");
+ break;
+ case TGeneralString:
+ fprintf (codefile, "return decode_general_string (p, len, data, size);\n");
+ break;
+ case TBitString:
+ case TSequence:
+ case TSequenceOf:
+ case TApplication:
+ case TType:
+ fprintf (codefile,
+ "size_t ret = 0, reallen;\n"
+ "size_t l;\n"
+ "int i, e;\n\n");
+ fprintf(codefile, "i = 0;\n"); /* hack to avoid `unused variable' */
+
+ decode_type ("data", s->type);
+ fprintf (codefile,
+ "if(size) *size = ret;\n"
+ "return 0;\n");
+ break;
+ default:
+ abort ();
+ }
+ fprintf (codefile, "}\n\n");
+}
+
+void
+generate_seq_type_decode (const Symbol *s)
+{
+ fprintf (headerfile,
+ "int decode_seq_%s(const unsigned char *, size_t, int, int, "
+ "%s *, size_t *);\n",
+ s->gen_name, s->gen_name);
+
+ fprintf (codefile, "int\n"
+ "decode_seq_%s(const unsigned char *p, size_t len, int tag, "
+ "int optional, %s *data, size_t *size)\n"
+ "{\n",
+ s->gen_name, s->gen_name);
+
+ fprintf (codefile,
+ "size_t newlen, oldlen;\n"
+ "size_t l, ret = 0;\n"
+ "int e;\n"
+ "int dce_fix;\n");
+
+ fprintf (codefile,
+ "e = der_match_tag(p, len, CONTEXT, CONS, tag, &l);\n"
+ "if (e)\n"
+ "return e;\n");
+ fprintf (codefile,
+ "p += l;\n"
+ "len -= l;\n"
+ "ret += l;\n"
+ "e = der_get_length(p, len, &newlen, &l);\n"
+ "if (e)\n"
+ "return e;\n"
+ "p += l;\n"
+ "len -= l;\n"
+ "ret += l;\n"
+ "oldlen = len;\n"
+ "if ((dce_fix = fix_dce(newlen, &len)) < 0)\n"
+ "return ASN1_BAD_FORMAT;\n"
+ "e = decode_%s(p, len, data, &l);\n"
+ "if (e)\n"
+ "return e;\n"
+ "p += l;\n"
+ "len -= l;\n"
+ "ret += l;\n"
+ "if (dce_fix) {\n"
+ "size_t reallen;\n\n"
+ "e = der_match_tag_and_length(p, len, "
+ "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
+ "if (e)\n"
+ "return e;\n"
+ "ret += l;\n"
+ "}\n",
+ s->gen_name);
+ fprintf (codefile,
+ "if(size) *size = ret;\n"
+ "return 0;\n");
+
+ fprintf (codefile, "}\n\n");
+}
diff --git a/crypto/heimdal/lib/asn1/gen_encode.c b/crypto/heimdal/lib/asn1/gen_encode.c
new file mode 100644
index 000000000000..9e9b293437b8
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/gen_encode.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gen_locl.h"
+
+RCSID("$Id: gen_encode.c,v 1.9 1999/12/02 17:05:02 joda Exp $");
+
+static void
+encode_primitive (const char *typename, const char *name)
+{
+ fprintf (codefile,
+ "e = encode_%s(p, len, %s, &l);\n"
+ "BACK;\n",
+ typename,
+ name);
+}
+
+static void
+encode_type (const char *name, const Type *t)
+{
+ switch (t->type) {
+ case TType:
+#if 0
+ encode_type (name, t->symbol->type);
+#endif
+ fprintf (codefile,
+ "e = encode_%s(p, len, %s, &l);\n"
+ "BACK;\n",
+ t->symbol->gen_name, name);
+ break;
+ case TInteger:
+ encode_primitive ("integer", name);
+ break;
+ case TOctetString:
+ encode_primitive ("octet_string", name);
+ break;
+ case TBitString: {
+ Member *m;
+ int pos;
+ int rest;
+ int tag = -1;
+
+ if (t->members == NULL)
+ break;
+
+ fprintf (codefile, "{\n"
+ "unsigned char c = 0;\n");
+ pos = t->members->prev->val;
+ /* fix for buggy MIT (and OSF?) code */
+ if (pos > 31)
+ abort ();
+ /*
+ * It seems that if we do not always set pos to 31 here, the MIT
+ * code will do the wrong thing.
+ *
+ * I hate ASN.1 (and DER), but I hate it even more when everybody
+ * has to screw it up differently.
+ */
+ pos = 31;
+ rest = 7 - (pos % 8);
+
+ for (m = t->members->prev; m && tag != m->val; m = m->prev) {
+ while (m->val / 8 < pos / 8) {
+ fprintf (codefile,
+ "*p-- = c; len--; ret++;\n"
+ "c = 0;\n");
+ pos -= 8;
+ }
+ fprintf (codefile,
+ "if(%s->%s) c |= 1<<%d;\n", name, m->gen_name,
+ 7 - m->val % 8);
+
+ if (tag == -1)
+ tag = m->val;
+ }
+
+ fprintf (codefile,
+ "*p-- = c;\n"
+ "*p-- = %d;\n"
+ "len -= 2;\n"
+ "ret += 2;\n"
+ "}\n\n"
+ "e = der_put_length_and_tag (p, len, ret, UNIV, PRIM,"
+ "UT_BitString, &l);\n"
+ "BACK;\n",
+ rest);
+ break;
+ }
+ case TSequence: {
+ Member *m;
+ int tag = -1;
+
+ if (t->members == NULL)
+ break;
+
+ for (m = t->members->prev; m && tag != m->val; m = m->prev) {
+ char *s;
+
+ asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
+ if (m->optional)
+ fprintf (codefile,
+ "if(%s)\n",
+ s);
+#if 1
+ fprintf (codefile, "{\n"
+ "int oldret = ret;\n"
+ "ret = 0;\n");
+#endif
+ encode_type (s, m->type);
+ fprintf (codefile,
+ "e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, "
+ "%d, &l);\n"
+ "BACK;\n",
+ m->val);
+#if 1
+ fprintf (codefile,
+ "ret += oldret;\n"
+ "}\n");
+#endif
+ if (tag == -1)
+ tag = m->val;
+ free (s);
+ }
+ fprintf (codefile,
+ "e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n"
+ "BACK;\n");
+ break;
+ }
+ case TSequenceOf: {
+ char *n;
+
+ fprintf (codefile,
+ "for(i = (%s)->len - 1; i >= 0; --i) {\n"
+#if 1
+ "int oldret = ret;\n"
+ "ret = 0;\n",
+#else
+ ,
+#endif
+ name);
+ asprintf (&n, "&(%s)->val[i]", name);
+ encode_type (n, t->subtype);
+ fprintf (codefile,
+#if 1
+ "ret += oldret;\n"
+#endif
+ "}\n"
+ "e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n"
+ "BACK;\n");
+ free (n);
+ break;
+ }
+ case TGeneralizedTime:
+ encode_primitive ("generalized_time", name);
+ break;
+ case TGeneralString:
+ encode_primitive ("general_string", name);
+ break;
+ case TApplication:
+ encode_type (name, t->subtype);
+ fprintf (codefile,
+ "e = der_put_length_and_tag (p, len, ret, APPL, CONS, %d, &l);\n"
+ "BACK;\n",
+ t->application);
+ break;
+ default:
+ abort ();
+ }
+}
+
+void
+generate_type_encode (const Symbol *s)
+{
+ fprintf (headerfile,
+ "int "
+ "encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
+ s->gen_name, s->gen_name);
+
+ fprintf (codefile, "#define BACK if (e) return e; p -= l; len -= l; ret += l\n\n");
+
+
+ fprintf (codefile, "int\n"
+ "encode_%s(unsigned char *p, size_t len,"
+ " const %s *data, size_t *size)\n"
+ "{\n",
+ s->gen_name, s->gen_name);
+
+ switch (s->type->type) {
+ case TInteger:
+ fprintf (codefile, "return encode_integer (p, len, data, size);\n");
+ break;
+ case TOctetString:
+ fprintf (codefile, "return encode_octet_string (p, len, data, size);\n");
+ break;
+ case TGeneralizedTime:
+ fprintf (codefile, "return encode_generalized_time (p, len, data, size);\n");
+ break;
+ case TGeneralString:
+ fprintf (codefile, "return encode_general_string (p, len, data, size);\n");
+ break;
+ case TBitString:
+ case TSequence:
+ case TSequenceOf:
+ case TApplication:
+ case TType:
+ fprintf (codefile,
+ "size_t ret = 0;\n"
+ "size_t l;\n"
+ "int i, e;\n\n");
+ fprintf(codefile, "i = 0;\n"); /* hack to avoid `unused variable' */
+
+ encode_type ("data", s->type);
+ fprintf (codefile, "*size = ret;\n"
+ "return 0;\n");
+ break;
+ default:
+ abort ();
+ }
+ fprintf (codefile, "}\n\n");
+}
diff --git a/crypto/heimdal/lib/asn1/gen_free.c b/crypto/heimdal/lib/asn1/gen_free.c
new file mode 100644
index 000000000000..0f6078bed1de
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/gen_free.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gen_locl.h"
+
+RCSID("$Id: gen_free.c,v 1.7 1999/12/02 17:05:02 joda Exp $");
+
+static void
+free_primitive (const char *typename, const char *name)
+{
+ fprintf (codefile, "free_%s(%s);\n", typename, name);
+}
+
+static void
+free_type (const char *name, const Type *t)
+{
+ switch (t->type) {
+ case TType:
+#if 0
+ free_type (name, t->symbol->type);
+#endif
+ fprintf (codefile, "free_%s(%s);\n", t->symbol->gen_name, name);
+ break;
+ case TInteger:
+ break;
+ case TOctetString:
+ free_primitive ("octet_string", name);
+ break;
+ case TBitString: {
+ break;
+ }
+ case TSequence: {
+ Member *m;
+ int tag = -1;
+
+ if (t->members == NULL)
+ break;
+
+ for (m = t->members; m && tag != m->val; m = m->next) {
+ char *s;
+
+ asprintf (&s, "%s(%s)->%s",
+ m->optional ? "" : "&", name, m->gen_name);
+ if(m->optional)
+ fprintf(codefile, "if(%s) {\n", s);
+ free_type (s, m->type);
+ if(m->optional)
+ fprintf(codefile,
+ "free(%s);\n"
+ "}\n",s);
+ if (tag == -1)
+ tag = m->val;
+ free (s);
+ }
+ break;
+ }
+ case TSequenceOf: {
+ char *n;
+
+ fprintf (codefile, "while((%s)->len){\n", name);
+ asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
+ free_type(n, t->subtype);
+ fprintf(codefile,
+ "(%s)->len--;\n"
+ "}\n",
+ name);
+ fprintf(codefile,
+ "free((%s)->val);\n", name);
+ free(n);
+ break;
+ }
+ case TGeneralizedTime:
+ break;
+ case TGeneralString:
+ free_primitive ("general_string", name);
+ break;
+ case TApplication:
+ free_type (name, t->subtype);
+ break;
+ default :
+ abort ();
+ }
+}
+
+void
+generate_type_free (const Symbol *s)
+{
+ fprintf (headerfile,
+ "void free_%s (%s *);\n",
+ s->gen_name, s->gen_name);
+
+ fprintf (codefile, "void\n"
+ "free_%s(%s *data)\n"
+ "{\n",
+ s->gen_name, s->gen_name);
+
+ free_type ("data", s->type);
+ fprintf (codefile, "}\n\n");
+}
+
diff --git a/crypto/heimdal/lib/asn1/gen_glue.c b/crypto/heimdal/lib/asn1/gen_glue.c
new file mode 100644
index 000000000000..2f6280ad6c28
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/gen_glue.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gen_locl.h"
+
+RCSID("$Id: gen_glue.c,v 1.7 1999/12/02 17:05:02 joda Exp $");
+
+static void
+generate_2int (const Symbol *s)
+{
+ Type *t = s->type;
+ Member *m;
+ int tag = -1;
+
+ fprintf (headerfile,
+ "unsigned %s2int(%s);\n",
+ s->gen_name, s->gen_name);
+
+ fprintf (codefile,
+ "unsigned %s2int(%s f)\n"
+ "{\n"
+ "unsigned r = 0;\n",
+ s->gen_name, s->gen_name);
+
+ for (m = t->members; m && m->val != tag; m = m->next) {
+ fprintf (codefile, "if(f.%s) r |= (1U << %d);\n",
+ m->gen_name, m->val);
+
+ if (tag == -1)
+ tag = m->val;
+ }
+ fprintf (codefile, "return r;\n"
+ "}\n\n");
+}
+
+static void
+generate_int2 (const Symbol *s)
+{
+ Type *t = s->type;
+ Member *m;
+ int tag = -1;
+
+ fprintf (headerfile,
+ "%s int2%s(unsigned);\n",
+ s->gen_name, s->gen_name);
+
+ fprintf (codefile,
+ "%s int2%s(unsigned n)\n"
+ "{\n"
+ "\t%s flags;\n\n",
+ s->gen_name, s->gen_name, s->gen_name);
+
+ for (m = t->members; m && m->val != tag; m = m->next) {
+ fprintf (codefile, "\tflags.%s = (n >> %d) & 1;\n",
+ m->gen_name, m->val);
+
+ if (tag == -1)
+ tag = m->val;
+ }
+ fprintf (codefile, "\treturn flags;\n"
+ "}\n\n");
+}
+
+/*
+ * This depends on the bit string being declared in increasing order
+ */
+
+static void
+generate_units (const Symbol *s)
+{
+ Type *t = s->type;
+ Member *m;
+ int tag = -1;
+
+ fprintf (headerfile,
+ "extern struct units %s_units[];",
+ s->gen_name);
+
+ fprintf (codefile,
+ "struct units %s_units[] = {\n",
+ s->gen_name);
+
+ if(t->members)
+ for (m = t->members->prev; m && m->val != tag; m = m->prev) {
+ fprintf (codefile,
+ "\t{\"%s\",\t1U << %d},\n", m->gen_name, m->val);
+
+ if (tag == -1)
+ tag = m->val;
+ }
+
+ fprintf (codefile,
+ "\t{NULL,\t0}\n"
+ "};\n\n");
+}
+
+void
+generate_glue (const Symbol *s)
+{
+ switch(s->type->type) {
+ case TBitString :
+ generate_2int (s);
+ generate_int2 (s);
+ generate_units (s);
+ break;
+ default :
+ break;
+ }
+}
diff --git a/crypto/heimdal/lib/asn1/gen_length.c b/crypto/heimdal/lib/asn1/gen_length.c
new file mode 100644
index 000000000000..1c3566d0f3c0
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/gen_length.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gen_locl.h"
+
+RCSID("$Id: gen_length.c,v 1.7 1999/12/02 17:05:02 joda Exp $");
+
+static void
+length_primitive (const char *typename,
+ const char *name,
+ const char *variable)
+{
+ fprintf (codefile, "%s += length_%s(%s);\n", variable, typename, name);
+}
+
+static void
+length_type (const char *name, const Type *t, const char *variable)
+{
+ switch (t->type) {
+ case TType:
+#if 0
+ length_type (name, t->symbol->type);
+#endif
+ fprintf (codefile, "%s += length_%s(%s);\n",
+ variable, t->symbol->gen_name, name);
+ break;
+ case TInteger:
+ length_primitive ("integer", name, variable);
+ break;
+ case TOctetString:
+ length_primitive ("octet_string", name, variable);
+ break;
+ case TBitString: {
+ /*
+ * XXX - Hope this is correct
+ * look at TBitString case in `encode_type'
+ */
+ fprintf (codefile, "%s += 7;\n", variable);
+ break;
+ }
+ case TSequence: {
+ Member *m;
+ int tag = -1;
+
+ if (t->members == NULL)
+ break;
+
+ for (m = t->members; m && tag != m->val; m = m->next) {
+ char *s;
+
+ asprintf (&s, "%s(%s)->%s",
+ m->optional ? "" : "&", name, m->gen_name);
+ if (m->optional)
+ fprintf (codefile, "if(%s)", s);
+ fprintf (codefile, "{\n"
+ "int oldret = %s;\n"
+ "%s = 0;\n", variable, variable);
+ length_type (s, m->type, "ret");
+ fprintf (codefile, "%s += 1 + length_len(%s) + oldret;\n",
+ variable, variable);
+ fprintf (codefile, "}\n");
+ if (tag == -1)
+ tag = m->val;
+ free (s);
+ }
+ fprintf (codefile,
+ "%s += 1 + length_len(%s);\n", variable, variable);
+ break;
+ }
+ case TSequenceOf: {
+ char *n;
+
+ fprintf (codefile,
+ "{\n"
+ "int oldret = %s;\n"
+ "int i;\n"
+ "%s = 0;\n",
+ variable, variable);
+
+ fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
+ asprintf (&n, "&(%s)->val[i]", name);
+ length_type(n, t->subtype, variable);
+ fprintf (codefile, "}\n");
+
+ fprintf (codefile,
+ "%s += 1 + length_len(%s) + oldret;\n"
+ "}\n", variable, variable);
+ free(n);
+ break;
+ }
+ case TGeneralizedTime:
+ length_primitive ("generalized_time", name, variable);
+ break;
+ case TGeneralString:
+ length_primitive ("general_string", name, variable);
+ break;
+ case TApplication:
+ length_type (name, t->subtype, variable);
+ fprintf (codefile, "ret += 1 + length_len (ret);\n");
+ break;
+ default :
+ abort ();
+ }
+}
+
+void
+generate_type_length (const Symbol *s)
+{
+ fprintf (headerfile,
+ "size_t length_%s(const %s *);\n",
+ s->gen_name, s->gen_name);
+
+ fprintf (codefile,
+ "size_t\n"
+ "length_%s(const %s *data)\n"
+ "{\n"
+ "size_t ret = 0;\n",
+ s->gen_name, s->gen_name);
+
+ length_type ("data", s->type, "ret");
+ fprintf (codefile, "return ret;\n}\n\n");
+}
+
diff --git a/crypto/heimdal/lib/asn1/gen_locl.h b/crypto/heimdal/lib/asn1/gen_locl.h
new file mode 100644
index 000000000000..7ee37aee22dd
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/gen_locl.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: gen_locl.h,v 1.6 1999/12/02 17:05:02 joda Exp $ */
+
+#ifndef __GEN_LOCL_H__
+#define __GEN_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+#include <time.h>
+#include <errno.h>
+#include <err.h>
+#include <roken.h>
+#include "hash.h"
+#include "symbol.h"
+
+void generate_type (const Symbol *);
+void generate_constant (const Symbol *);
+void generate_type_encode (const Symbol *s);
+void generate_type_decode (const Symbol *s);
+void generate_seq_type_decode (const Symbol *s);
+void generate_type_free (const Symbol *s);
+void generate_type_length (const Symbol *s);
+void generate_type_copy (const Symbol *s);
+void generate_type_maybe (const Symbol *s);
+void generate_glue (const Symbol *s);
+
+void init_generate (char *filename, char *basename);
+void close_generate(void);
+int yyparse(void);
+
+extern FILE *headerfile, *codefile, *logfile;
+
+#endif /* __GEN_LOCL_H__ */
diff --git a/crypto/heimdal/lib/asn1/hash.c b/crypto/heimdal/lib/asn1/hash.c
new file mode 100644
index 000000000000..a8d3eb39f972
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/hash.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*
+ * Hash table functions
+ */
+
+#include "gen_locl.h"
+
+RCSID("$Id: hash.c,v 1.8 1999/12/02 17:05:02 joda Exp $");
+
+static Hashentry *_search(Hashtab * htab, /* The hash table */
+ void *ptr); /* And key */
+
+Hashtab *
+hashtabnew(int sz,
+ int (*cmp) (void *, void *),
+ unsigned (*hash) (void *))
+{
+ Hashtab *htab;
+ int i;
+
+ assert(sz > 0);
+
+ htab = (Hashtab *) malloc(sizeof(Hashtab) + (sz - 1) * sizeof(Hashentry *));
+ for (i = 0; i < sz; ++i)
+ htab->tab[i] = NULL;
+
+ if (htab == NULL) {
+ return NULL;
+ } else {
+ htab->cmp = cmp;
+ htab->hash = hash;
+ htab->sz = sz;
+ return htab;
+ }
+}
+
+/* Intern search function */
+
+static Hashentry *
+_search(Hashtab * htab, void *ptr)
+{
+ Hashentry *hptr;
+
+ assert(htab && ptr);
+
+ for (hptr = htab->tab[(*htab->hash) (ptr) % htab->sz];
+ hptr;
+ hptr = hptr->next)
+ if ((*htab->cmp) (ptr, hptr->ptr) == 0)
+ break;
+ return hptr;
+}
+
+/* Search for element in hash table */
+
+void *
+hashtabsearch(Hashtab * htab, void *ptr)
+{
+ Hashentry *tmp;
+
+ tmp = _search(htab, ptr);
+ return tmp ? tmp->ptr : tmp;
+}
+
+/* add element to hash table */
+/* if already there, set new value */
+/* !NULL if succesful */
+
+void *
+hashtabadd(Hashtab * htab, void *ptr)
+{
+ Hashentry *h = _search(htab, ptr);
+ Hashentry **tabptr;
+
+ assert(htab && ptr);
+
+ if (h)
+ free((void *) h->ptr);
+ else {
+ h = (Hashentry *) malloc(sizeof(Hashentry));
+ if (h == NULL) {
+ return NULL;
+ }
+ tabptr = &htab->tab[(*htab->hash) (ptr) % htab->sz];
+ h->next = *tabptr;
+ *tabptr = h;
+ h->prev = tabptr;
+ if (h->next)
+ h->next->prev = &h->next;
+ }
+ h->ptr = ptr;
+ return h;
+}
+
+/* delete element with key key. Iff freep, free Hashentry->ptr */
+
+int
+_hashtabdel(Hashtab * htab, void *ptr, int freep)
+{
+ Hashentry *h;
+
+ assert(htab && ptr);
+
+ h = _search(htab, ptr);
+ if (h) {
+ if (freep)
+ free(h->ptr);
+ if ((*(h->prev) = h->next))
+ h->next->prev = h->prev;
+ free(h);
+ return 0;
+ } else
+ return -1;
+}
+
+/* Do something for each element */
+
+void
+hashtabforeach(Hashtab * htab, int (*func) (void *ptr, void *arg),
+ void *arg)
+{
+ Hashentry **h, *g;
+
+ assert(htab);
+
+ for (h = htab->tab; h < &htab->tab[htab->sz]; ++h)
+ for (g = *h; g; g = g->next)
+ if ((*func) (g->ptr, arg))
+ return;
+}
+
+/* standard hash-functions for strings */
+
+unsigned
+hashadd(const char *s)
+{ /* Standard hash function */
+ unsigned i;
+
+ assert(s);
+
+ for (i = 0; *s; ++s)
+ i += *s;
+ return i;
+}
+
+unsigned
+hashcaseadd(const char *s)
+{ /* Standard hash function */
+ unsigned i;
+
+ assert(s);
+
+ for (i = 0; *s; ++s)
+ i += toupper(*s);
+ return i;
+}
+
+#define TWELVE (sizeof(unsigned))
+#define SEVENTYFIVE (6*sizeof(unsigned))
+#define HIGH_BITS (~((unsigned)(~0) >> TWELVE))
+
+unsigned
+hashjpw(const char *ss)
+{ /* another hash function */
+ unsigned h = 0;
+ unsigned g;
+ const unsigned char *s = (const unsigned char *)ss;
+
+ for (; *s; ++s) {
+ h = (h << TWELVE) + *s;
+ if ((g = h & HIGH_BITS))
+ h = (h ^ (g >> SEVENTYFIVE)) & ~HIGH_BITS;
+ }
+ return h;
+}
diff --git a/crypto/heimdal/lib/asn1/hash.h b/crypto/heimdal/lib/asn1/hash.h
new file mode 100644
index 000000000000..b54e10234a74
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/hash.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*
+ * hash.h. Header file for hash table functions
+ */
+
+/* $Id: hash.h,v 1.3 1999/12/02 17:05:02 joda Exp $ */
+
+struct hashentry { /* Entry in bucket */
+ struct hashentry **prev;
+ struct hashentry *next;
+ void *ptr;
+};
+
+typedef struct hashentry Hashentry;
+
+struct hashtab { /* Hash table */
+ int (*cmp)(void *, void *); /* Compare function */
+ unsigned (*hash)(void *); /* hash function */
+ int sz; /* Size */
+ Hashentry *tab[1]; /* The table */
+};
+
+typedef struct hashtab Hashtab;
+
+/* prototypes */
+
+Hashtab *hashtabnew(int sz,
+ int (*cmp)(void *, void *),
+ unsigned (*hash)(void *)); /* Make new hash table */
+
+void *hashtabsearch(Hashtab *htab, /* The hash table */
+ void *ptr); /* The key */
+
+
+void *hashtabadd(Hashtab *htab, /* The hash table */
+ void *ptr); /* The element */
+
+int _hashtabdel(Hashtab *htab, /* The table */
+ void *ptr, /* Key */
+ int freep); /* Free data part? */
+
+void hashtabforeach(Hashtab *htab,
+ int (*func)(void *ptr, void *arg),
+ void *arg);
+
+unsigned hashadd(const char *s); /* Standard hash function */
+unsigned hashcaseadd(const char *s); /* Standard hash function */
+unsigned hashjpw(const char *s); /* another hash function */
+
+/* macros */
+
+ /* Don't free space */
+#define hashtabdel(htab,key) _hashtabdel(htab,key,FALSE)
+
+#define hashtabfree(htab,key) _hashtabdel(htab,key,TRUE) /* Do! */
diff --git a/crypto/heimdal/lib/asn1/k5.asn1 b/crypto/heimdal/lib/asn1/k5.asn1
new file mode 100644
index 000000000000..a7f41992280a
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/k5.asn1
@@ -0,0 +1,385 @@
+KERBEROS5 DEFINITIONS ::=
+BEGIN
+
+nt-unknown INTEGER ::= 0 -- Name type not known
+nt-principal INTEGER ::= 1 -- Just the name of the principal as in
+nt-srv-inst INTEGER ::= 2 -- Service and other unique instance (krbtgt)
+nt-srv-hst INTEGER ::= 3 -- Service with host name as instance
+nt-srv-xhst INTEGER ::= 4 -- Service with host as remaining components
+nt-uid INTEGER ::= 5 -- Unique ID
+
+Realm ::= GeneralString
+PrincipalName ::= SEQUENCE {
+ name-type[0] INTEGER,
+ name-string[1] SEQUENCE OF GeneralString
+}
+
+-- this is not part of RFC1510
+Principal ::= SEQUENCE {
+ name[0] PrincipalName,
+ realm[1] Realm
+}
+
+HostAddress ::= SEQUENCE {
+ addr-type[0] INTEGER,
+ address[1] OCTET STRING
+}
+
+-- This is from RFC1510.
+--
+-- HostAddresses ::= SEQUENCE OF SEQUENCE {
+-- addr-type[0] INTEGER,
+-- address[1] OCTET STRING
+-- }
+
+-- This seems much better.
+HostAddresses ::= SEQUENCE OF HostAddress
+
+
+KerberosTime ::= GeneralizedTime -- Specifying UTC time zone (Z)
+
+AuthorizationData ::= SEQUENCE OF SEQUENCE {
+ ad-type[0] INTEGER,
+ ad-data[1] OCTET STRING
+}
+
+APOptions ::= BIT STRING {
+ reserved(0),
+ use-session-key(1),
+ mutual-required(2)
+}
+
+TicketFlags ::= BIT STRING {
+ reserved(0),
+ forwardable(1),
+ forwarded(2),
+ proxiable(3),
+ proxy(4),
+ may-postdate(5),
+ postdated(6),
+ invalid(7),
+ renewable(8),
+ initial(9),
+ pre-authent(10),
+ hw-authent(11),
+ transited-policy-checked(12),
+ ok-as-delegate(13),
+ anonymous(14)
+}
+
+KDCOptions ::= BIT STRING {
+ reserved(0),
+ forwardable(1),
+ forwarded(2),
+ proxiable(3),
+ proxy(4),
+ allow-postdate(5),
+ postdated(6),
+ unused7(7),
+ renewable(8),
+ unused9(9),
+ unused10(10),
+ unused11(11),
+ request-anonymous(14),
+ disable-transited-check(26),
+ renewable-ok(27),
+ enc-tkt-in-skey(28),
+ renew(30),
+ validate(31)
+}
+
+
+LastReq ::= SEQUENCE OF SEQUENCE {
+ lr-type[0] INTEGER,
+ lr-value[1] KerberosTime
+}
+
+EncryptedData ::= SEQUENCE {
+ etype[0] INTEGER, -- EncryptionType
+ kvno[1] INTEGER OPTIONAL,
+ cipher[2] OCTET STRING -- ciphertext
+}
+
+EncryptionKey ::= SEQUENCE {
+ keytype[0] INTEGER,
+ keyvalue[1] OCTET STRING
+}
+
+-- encoded Transited field
+TransitedEncoding ::= SEQUENCE {
+ tr-type[0] INTEGER, -- must be registered
+ contents[1] OCTET STRING
+}
+
+Ticket ::= [APPLICATION 1] SEQUENCE {
+ tkt-vno[0] INTEGER,
+ realm[1] Realm,
+ sname[2] PrincipalName,
+ enc-part[3] EncryptedData
+}
+-- Encrypted part of ticket
+EncTicketPart ::= [APPLICATION 3] SEQUENCE {
+ flags[0] TicketFlags,
+ key[1] EncryptionKey,
+ crealm[2] Realm,
+ cname[3] PrincipalName,
+ transited[4] TransitedEncoding,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ caddr[9] HostAddresses OPTIONAL,
+ authorization-data[10] AuthorizationData OPTIONAL
+}
+
+Checksum ::= SEQUENCE {
+ cksumtype[0] INTEGER,
+ checksum[1] OCTET STRING
+}
+
+Authenticator ::= [APPLICATION 2] SEQUENCE {
+ authenticator-vno[0] INTEGER,
+ crealm[1] Realm,
+ cname[2] PrincipalName,
+ cksum[3] Checksum OPTIONAL,
+ cusec[4] INTEGER,
+ ctime[5] KerberosTime,
+ subkey[6] EncryptionKey OPTIONAL,
+ seq-number[7] INTEGER OPTIONAL,
+ authorization-data[8] AuthorizationData OPTIONAL
+ }
+
+PA-DATA ::= SEQUENCE {
+ -- might be encoded AP-REQ
+ padata-type[1] INTEGER,
+ padata-value[2] OCTET STRING
+}
+
+ETYPE-INFO-ENTRY ::= SEQUENCE {
+ etype[0] INTEGER,
+ salt[1] OCTET STRING OPTIONAL,
+ salttype[2] INTEGER OPTIONAL
+}
+
+ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY
+
+METHOD-DATA ::= SEQUENCE OF PA-DATA
+
+KDC-REQ-BODY ::= SEQUENCE {
+ kdc-options[0] KDCOptions,
+ cname[1] PrincipalName OPTIONAL, -- Used only in AS-REQ
+ realm[2] Realm, -- Server's realm
+ -- Also client's in AS-REQ
+ sname[3] PrincipalName OPTIONAL,
+ from[4] KerberosTime OPTIONAL,
+ till[5] KerberosTime OPTIONAL,
+ rtime[6] KerberosTime OPTIONAL,
+ nonce[7] INTEGER,
+ etype[8] SEQUENCE OF INTEGER, -- EncryptionType,
+ -- in preference order
+ addresses[9] HostAddresses OPTIONAL,
+ enc-authorization-data[10] EncryptedData OPTIONAL,
+ -- Encrypted AuthorizationData encoding
+ additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
+}
+
+KDC-REQ ::= SEQUENCE {
+ pvno[1] INTEGER,
+ msg-type[2] INTEGER,
+ padata[3] METHOD-DATA OPTIONAL,
+ req-body[4] KDC-REQ-BODY
+}
+
+AS-REQ ::= [APPLICATION 10] KDC-REQ
+TGS-REQ ::= [APPLICATION 12] KDC-REQ
+
+-- padata-type ::= PA-ENC-TIMESTAMP
+-- padata-value ::= EncryptedData - PA-ENC-TS-ENC
+
+PA-ENC-TS-ENC ::= SEQUENCE {
+ patimestamp[0] KerberosTime, -- client's time
+ pausec[1] INTEGER OPTIONAL
+}
+
+KDC-REP ::= SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ padata[2] METHOD-DATA OPTIONAL,
+ crealm[3] Realm,
+ cname[4] PrincipalName,
+ ticket[5] Ticket,
+ enc-part[6] EncryptedData
+}
+
+AS-REP ::= [APPLICATION 11] KDC-REP
+TGS-REP ::= [APPLICATION 13] KDC-REP
+
+EncKDCRepPart ::= SEQUENCE {
+ key[0] EncryptionKey,
+ last-req[1] LastReq,
+ nonce[2] INTEGER,
+ key-expiration[3] KerberosTime OPTIONAL,
+ flags[4] TicketFlags,
+ authtime[5] KerberosTime,
+ starttime[6] KerberosTime OPTIONAL,
+ endtime[7] KerberosTime,
+ renew-till[8] KerberosTime OPTIONAL,
+ srealm[9] Realm,
+ sname[10] PrincipalName,
+ caddr[11] HostAddresses OPTIONAL
+}
+
+EncASRepPart ::= [APPLICATION 25] EncKDCRepPart
+EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
+
+AP-REQ ::= [APPLICATION 14] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ap-options[2] APOptions,
+ ticket[3] Ticket,
+ authenticator[4] EncryptedData
+}
+
+AP-REP ::= [APPLICATION 15] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[2] EncryptedData
+}
+
+EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
+ ctime[0] KerberosTime,
+ cusec[1] INTEGER,
+ subkey[2] EncryptionKey OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL
+}
+
+KRB-SAFE-BODY ::= SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+}
+
+KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ safe-body[2] KRB-SAFE-BODY,
+ cksum[3] Checksum
+}
+
+KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ enc-part[3] EncryptedData
+}
+EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
+ user-data[0] OCTET STRING,
+ timestamp[1] KerberosTime OPTIONAL,
+ usec[2] INTEGER OPTIONAL,
+ seq-number[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL, -- sender's addr
+ r-address[5] HostAddress OPTIONAL -- recip's addr
+}
+
+KRB-CRED ::= [APPLICATION 22] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER, -- KRB_CRED
+ tickets[2] SEQUENCE OF Ticket,
+ enc-part[3] EncryptedData
+}
+
+KrbCredInfo ::= SEQUENCE {
+ key[0] EncryptionKey,
+ prealm[1] Realm OPTIONAL,
+ pname[2] PrincipalName OPTIONAL,
+ flags[3] TicketFlags OPTIONAL,
+ authtime[4] KerberosTime OPTIONAL,
+ starttime[5] KerberosTime OPTIONAL,
+ endtime[6] KerberosTime OPTIONAL,
+ renew-till[7] KerberosTime OPTIONAL,
+ srealm[8] Realm OPTIONAL,
+ sname[9] PrincipalName OPTIONAL,
+ caddr[10] HostAddresses OPTIONAL
+}
+
+EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
+ ticket-info[0] SEQUENCE OF KrbCredInfo,
+ nonce[1] INTEGER OPTIONAL,
+ timestamp[2] KerberosTime OPTIONAL,
+ usec[3] INTEGER OPTIONAL,
+ s-address[4] HostAddress OPTIONAL,
+ r-address[5] HostAddress OPTIONAL
+}
+
+KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
+ pvno[0] INTEGER,
+ msg-type[1] INTEGER,
+ ctime[2] KerberosTime OPTIONAL,
+ cusec[3] INTEGER OPTIONAL,
+ stime[4] KerberosTime,
+ susec[5] INTEGER,
+ error-code[6] INTEGER,
+ crealm[7] Realm OPTIONAL,
+ cname[8] PrincipalName OPTIONAL,
+ realm[9] Realm, -- Correct realm
+ sname[10] PrincipalName, -- Correct name
+ e-text[11] GeneralString OPTIONAL,
+ e-data[12] OCTET STRING OPTIONAL
+}
+
+pvno INTEGER ::= 5 -- current Kerberos protocol version number
+
+-- message types
+
+krb-as-req INTEGER ::= 10 -- Request for initial authentication
+krb-as-rep INTEGER ::= 11 -- Response to KRB_AS_REQ request
+krb-tgs-req INTEGER ::= 12 -- Request for authentication based on TGT
+krb-tgs-rep INTEGER ::= 13 -- Response to KRB_TGS_REQ request
+krb-ap-req INTEGER ::= 14 -- application request to server
+krb-ap-rep INTEGER ::= 15 -- Response to KRB_AP_REQ_MUTUAL
+krb-safe INTEGER ::= 20 -- Safe (checksummed) application message
+krb-priv INTEGER ::= 21 -- Private (encrypted) application message
+krb-cred INTEGER ::= 22 -- Private (encrypted) message to forward credentials
+krb-error INTEGER ::= 30 -- Error response
+
+-- pa-data types
+
+pa-tgs-req INTEGER ::= 1
+pa-enc-timestamp INTEGER ::= 2
+pa-pw-salt INTEGER ::= 3
+pa-enc-unix-time INTEGER ::= 5
+pa-sandia-secureid INTEGER ::= 6
+pa-sesame INTEGER ::= 7
+pa-osf-dce INTEGER ::= 8
+pa-cybersafe-secureid INTEGER ::= 9
+pa-afs3-salt INTEGER ::= 10
+pa-etype-info INTEGER ::= 11
+sam-challenge INTEGER ::= 12 -- (sam/otp)
+sam-response INTEGER ::= 13 -- (sam/otp)
+pa-pk-as-req INTEGER ::= 14 -- (pkinit)
+pa-pk-as-rep INTEGER ::= 15 -- (pkinit)
+pa-pk-as-sign INTEGER ::= 16 -- (pkinit)
+pa-pk-key-req INTEGER ::= 17 -- (pkinit)
+pa-pk-key-rep INTEGER ::= 18 -- (pkinit)
+-- checksumtypes
+
+CRC32 INTEGER ::= 1
+rsa-md4 INTEGER ::= 2
+rsa-md4-des INTEGER ::= 3
+des-mac INTEGER ::= 4
+des-mac-k INTEGER ::= 5
+rsa-md4-des-k INTEGER ::= 6
+rsa-md5 INTEGER ::= 7
+rsa-md5-des INTEGER ::= 8
+rsa-md5-des3 INTEGER ::= 9
+hmac-sha1-des3 INTEGER ::= 12
+
+-- transited encodings
+
+DOMAIN-X500-COMPRESS INTEGER ::= 1
+
+END
+
+-- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1
diff --git a/crypto/heimdal/lib/asn1/lex.h b/crypto/heimdal/lib/asn1/lex.h
new file mode 100644
index 000000000000..66d708c3ccd2
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/lex.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: lex.h,v 1.3 1999/12/02 17:05:02 joda Exp $ */
+
+void error_message (char *, ...);
diff --git a/crypto/heimdal/lib/asn1/lex.l b/crypto/heimdal/lib/asn1/lex.l
new file mode 100644
index 000000000000..b3fbf713b19a
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/lex.l
@@ -0,0 +1,102 @@
+%{
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: lex.l,v 1.10 1999/12/02 17:05:02 joda Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include "symbol.h"
+#include "parse.h"
+
+void error_message(char *, ...);
+
+static unsigned lineno = 1;
+
+/* ","|"{"|"}"|"("|")"|"["|"]"|"|" { return *yytext; } */
+%}
+
+
+%%
+INTEGER { return INTEGER; }
+SEQUENCE { return SEQUENCE; }
+OF { return OF; }
+OCTET { return OCTET; }
+STRING { return STRING; }
+GeneralizedTime { return GeneralizedTime; }
+GeneralString { return GeneralString; }
+BIT { return BIT; }
+APPLICATION { return APPLICATION; }
+OPTIONAL { return OPTIONAL; }
+BEGIN { return TBEGIN; }
+END { return END; }
+DEFINITIONS { return DEFINITIONS; }
+EXTERNAL { return EXTERNAL; }
+[,{}()|] { return *yytext; }
+"[" { return *yytext; }
+"]" { return *yytext; }
+::= { return EEQUAL; }
+--[^\n]*\n { ; }
+-?[0-9]+ { yylval.constant = atoi(yytext); return CONSTANT; }
+[A-Za-z][-A-Za-z0-9_]* { yylval.name = strdup (yytext); return IDENTIFIER; }
+[ \t] ;
+\n { lineno++; }
+. { error_message("Ignoring char(%c)\n", *yytext); }
+%%
+
+#ifndef yywrap /* XXX */
+int
+yywrap ()
+{
+ return 1;
+}
+#endif
+
+void
+error_message (char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ fprintf (stderr, ":%d: ", lineno);
+ vfprintf (stderr, format, args);
+ va_end (args);
+}
diff --git a/crypto/heimdal/lib/asn1/libasn1.h b/crypto/heimdal/lib/asn1/libasn1.h
new file mode 100644
index 000000000000..90eda60cedac
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/libasn1.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: libasn1.h,v 1.7 1999/12/02 17:05:02 joda Exp $ */
+
+#ifndef __LIBASN1_H__
+#define __LIBASN1_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include "asn1.h"
+#include "der.h"
+#include "asn1_err.h"
+#include <parse_units.h>
+
+#endif /* __LIBASN1_H__ */
diff --git a/crypto/heimdal/lib/asn1/main.c b/crypto/heimdal/lib/asn1/main.c
new file mode 100644
index 000000000000..538af5aa167f
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/main.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gen_locl.h"
+#include <getarg.h>
+
+RCSID("$Id: main.c,v 1.10 1999/12/02 17:05:02 joda Exp $");
+
+extern FILE *yyin;
+
+int version_flag;
+int help_flag;
+struct getargs args[] = {
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int code)
+{
+ arg_printusage(args, num_args, NULL, "[asn1-file [name]]");
+ exit(code);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ char *file;
+ char *name = NULL;
+ int optind = 0;
+
+ set_progname(argv[0]);
+ if(getarg(args, num_args, argc, argv, &optind))
+ usage(1);
+ if(help_flag)
+ usage(0);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+ if (argc == optind) {
+ file = "stdin";
+ name = "stdin";
+ yyin = stdin;
+ } else {
+ file = argv[optind];
+ yyin = fopen (file, "r");
+ if (yyin == NULL)
+ err (1, "open %s", file);
+ name = argv[optind + 1];
+ }
+
+ init_generate (file, name);
+ initsym ();
+ ret = yyparse ();
+ close_generate ();
+ return ret;
+}
diff --git a/crypto/heimdal/lib/asn1/parse.y b/crypto/heimdal/lib/asn1/parse.y
new file mode 100644
index 000000000000..f9e82b50fd49
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/parse.y
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: parse.y,v 1.12 1999/12/02 17:05:02 joda Exp $ */
+
+%{
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "symbol.h"
+#include "lex.h"
+#include "gen_locl.h"
+
+RCSID("$Id: parse.y,v 1.12 1999/12/02 17:05:02 joda Exp $");
+
+static Type *new_type (Typetype t);
+void yyerror (char *);
+int yylex(void);
+
+static void append (Member *l, Member *r);
+
+%}
+
+%union {
+ int constant;
+ char *name;
+ Type *type;
+ Member *member;
+}
+
+%token INTEGER SEQUENCE OF OCTET STRING GeneralizedTime GeneralString
+%token BIT APPLICATION OPTIONAL EEQUAL TBEGIN END DEFINITIONS EXTERNAL
+%token <name> IDENTIFIER
+%token <constant> CONSTANT
+
+%type <constant> constant optional2
+%type <type> type
+%type <member> memberdecls memberdecl bitdecls bitdecl
+
+%start envelope
+
+%%
+
+envelope : IDENTIFIER DEFINITIONS EEQUAL TBEGIN specification END {}
+ ;
+
+specification :
+ | specification declaration
+ ;
+
+declaration : extern_decl
+ | type_decl
+ | constant_decl
+ ;
+
+extern_decl : IDENTIFIER EXTERNAL
+ {
+ Symbol *s = addsym($1);
+ s->stype = Stype;
+ }
+ ;
+
+type_decl : IDENTIFIER EEQUAL type
+ {
+ Symbol *s = addsym ($1);
+ s->stype = Stype;
+ s->type = $3;
+ generate_type (s);
+ }
+ ;
+
+constant_decl : IDENTIFIER type EEQUAL constant
+ {
+ Symbol *s = addsym ($1);
+ s->stype = SConstant;
+ s->constant = $4;
+ generate_constant (s);
+ }
+ ;
+
+type : INTEGER { $$ = new_type(TInteger); }
+ | OCTET STRING { $$ = new_type(TOctetString); }
+ | GeneralString { $$ = new_type(TGeneralString); }
+ | GeneralizedTime { $$ = new_type(TGeneralizedTime); }
+ | SEQUENCE OF type
+ {
+ $$ = new_type(TSequenceOf);
+ $$->subtype = $3;
+ }
+ | SEQUENCE '{' memberdecls '}'
+ {
+ $$ = new_type(TSequence);
+ $$->members = $3;
+ }
+ | BIT STRING '{' bitdecls '}'
+ {
+ $$ = new_type(TBitString);
+ $$->members = $4;
+ }
+ | IDENTIFIER
+ {
+ Symbol *s = addsym($1);
+ $$ = new_type(TType);
+ if(s->stype != Stype)
+ error_message ("%s is not a type\n", $1);
+ else
+ $$->symbol = s;
+ }
+ | '[' APPLICATION constant ']' type
+ {
+ $$ = new_type(TApplication);
+ $$->subtype = $5;
+ $$->application = $3;
+ }
+ ;
+
+memberdecls : { $$ = NULL; }
+ | memberdecl { $$ = $1; }
+ | memberdecls ',' memberdecl { $$ = $1; append($$, $3); }
+ ;
+
+memberdecl : IDENTIFIER '[' constant ']' type optional2
+ {
+ $$ = malloc(sizeof(*$$));
+ $$->name = $1;
+ $$->gen_name = strdup($1);
+ output_name ($$->gen_name);
+ $$->val = $3;
+ $$->optional = $6;
+ $$->type = $5;
+ $$->next = $$->prev = $$;
+ }
+ ;
+
+optional2 : { $$ = 0; }
+ | OPTIONAL { $$ = 1; }
+ ;
+
+bitdecls : { $$ = NULL; }
+ | bitdecl { $$ = $1; }
+ | bitdecls ',' bitdecl { $$ = $1; append($$, $3); }
+ ;
+
+bitdecl : IDENTIFIER '(' constant ')'
+ {
+ $$ = malloc(sizeof(*$$));
+ $$->name = $1;
+ $$->gen_name = strdup($1);
+ output_name ($$->gen_name);
+ $$->val = $3;
+ $$->optional = 0;
+ $$->type = NULL;
+ $$->prev = $$->next = $$;
+ }
+ ;
+
+constant : CONSTANT { $$ = $1; }
+ | IDENTIFIER {
+ Symbol *s = addsym($1);
+ if(s->stype != SConstant)
+ error_message ("%s is not a constant\n",
+ s->name);
+ else
+ $$ = s->constant;
+ }
+ ;
+%%
+
+void
+yyerror (char *s)
+{
+ error_message ("%s\n", s);
+}
+
+static Type *
+new_type (Typetype tt)
+{
+ Type *t = malloc(sizeof(*t));
+ if (t == NULL) {
+ error_message ("out of memory in malloc(%u)", sizeof(*t));
+ exit (1);
+ }
+ t->type = tt;
+ t->application = 0;
+ t->members = NULL;
+ t->subtype = NULL;
+ t->symbol = NULL;
+ return t;
+}
+
+static void
+append (Member *l, Member *r)
+{
+ l->prev->next = r;
+ r->prev = l->prev;
+ l->prev = r;
+ r->next = l;
+}
diff --git a/crypto/heimdal/lib/asn1/symbol.c b/crypto/heimdal/lib/asn1/symbol.c
new file mode 100644
index 000000000000..5e6e741c322e
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/symbol.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gen_locl.h"
+
+RCSID("$Id: symbol.c,v 1.8 1999/12/02 17:05:02 joda Exp $");
+
+static Hashtab *htab;
+
+static int
+cmp (void *a, void *b)
+{
+ Symbol *s1 = (Symbol *)a;
+ Symbol *s2 = (Symbol *)b;
+
+ return strcmp (s1->name, s2->name);
+}
+
+static unsigned
+hash (void *a)
+{
+ Symbol *s = (Symbol *)a;
+
+ return hashjpw (s->name);
+}
+
+void
+initsym ()
+{
+ htab = hashtabnew (101, cmp, hash);
+}
+
+
+void
+output_name (char *s)
+{
+ char *p;
+
+ for (p = s; *p; ++p)
+ if (*p == '-')
+ *p = '_';
+}
+
+Symbol*
+addsym (char *name)
+{
+ Symbol key, *s;
+
+ key.name = name;
+ s = (Symbol *)hashtabsearch (htab, (void *)&key);
+ if (s == NULL) {
+ s = (Symbol *)malloc (sizeof (*s));
+ s->name = name;
+ s->gen_name = strdup(name);
+ output_name (s->gen_name);
+ s->stype = SUndefined;
+ hashtabadd (htab, s);
+ }
+ return s;
+}
diff --git a/crypto/heimdal/lib/asn1/symbol.h b/crypto/heimdal/lib/asn1/symbol.h
new file mode 100644
index 000000000000..bc4707f126fe
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/symbol.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: symbol.h,v 1.5 1999/12/02 17:05:02 joda Exp $ */
+
+#ifndef _SYMBOL_H
+#define _SYMBOL_H
+
+enum typetype { TInteger, TOctetString, TBitString, TSequence, TSequenceOf,
+ TGeneralizedTime, TGeneralString, TApplication, TType,
+ TUInteger };
+
+typedef enum typetype Typetype;
+
+struct type;
+
+struct member {
+ char *name;
+ char *gen_name;
+ int val;
+ int optional;
+ struct type *type;
+ struct member *next, *prev;
+};
+
+typedef struct member Member;
+
+struct symbol;
+
+struct type {
+ Typetype type;
+ int application;
+ Member *members;
+ struct type *subtype;
+ struct symbol *symbol;
+};
+
+typedef struct type Type;
+
+struct symbol {
+ char *name;
+ char *gen_name;
+ enum { SUndefined, SConstant, Stype } stype;
+ int constant;
+ Type *type;
+};
+
+typedef struct symbol Symbol;
+
+void initsym (void);
+Symbol *addsym (char *);
+void output_name (char *);
+#endif
diff --git a/crypto/heimdal/lib/asn1/timegm.c b/crypto/heimdal/lib/asn1/timegm.c
new file mode 100644
index 000000000000..bdc997fa4460
--- /dev/null
+++ b/crypto/heimdal/lib/asn1/timegm.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "der_locl.h"
+
+RCSID("$Id: timegm.c,v 1.7 1999/12/02 17:05:02 joda Exp $");
+
+#ifndef HAVE_TIMEGM
+
+static int
+is_leap(unsigned y)
+{
+ y += 1900;
+ return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
+}
+
+time_t
+timegm (struct tm *tm)
+{
+ 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}};
+ time_t res = 0;
+ unsigned i;
+
+ for (i = 70; i < tm->tm_year; ++i)
+ res += is_leap(i) ? 366 : 365;
+
+ for (i = 0; i < tm->tm_mon; ++i)
+ res += ndays[is_leap(tm->tm_year)][i];
+ res += tm->tm_mday - 1;
+ res *= 24;
+ res += tm->tm_hour;
+ res *= 60;
+ res += tm->tm_min;
+ res *= 60;
+ res += tm->tm_sec;
+ return res;
+}
+
+#endif /* HAVE_TIMEGM */
diff --git a/crypto/heimdal/lib/auth/ChangeLog b/crypto/heimdal/lib/auth/ChangeLog
new file mode 100644
index 000000000000..9b1ebaf33527
--- /dev/null
+++ b/crypto/heimdal/lib/auth/ChangeLog
@@ -0,0 +1,74 @@
+1999-12-30 Assar Westerlund <assar@sics.se>
+
+ * sia/Makefile.am: try to link with shared libraries if we don't
+ find any static ones
+
+1999-12-20 Johan Danielsson <joda@pdc.kth.se>
+
+ * sia/sia.c: don't use string concatenation with TKT_ROOT
+
+1999-11-15 Assar Westerlund <assar@sics.se>
+
+ * */lib/Makefile.in: set LIBNAME. From Enrico Scholz
+ <Enrico.Scholz@informatik.tu-chemnitz.de>
+
+1999-10-17 Assar Westerlund <assar@sics.se>
+
+ * afskauthlib/verify.c (verify_krb5): need realm for v5 -> v4
+
+1999-10-03 Assar Westerlund <assar@sics.se>
+
+ * afskauthlib/verify.c (verify_krb5): update to new
+ krb524_convert_creds_kdc
+
+1999-09-28 Assar Westerlund <assar@sics.se>
+
+ * sia/sia.c (doauth): use krb5_get_local_realms and
+ krb5_verify_user_lrealm
+
+ * afskauthlib/verify.c (verify_krb5): remove krb5_kuserok. use
+ krb5_verify_user_lrealm
+
+1999-08-11 Johan Danielsson <joda@pdc.kth.se>
+
+ * afskauthlib/verify.c: make this compile w/o krb4
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * afskauthlib/verify.c: incorporate patches from Miroslav Ruda
+ <ruda@ics.muni.cz>
+
+Thu Apr 8 14:35:34 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * sia/sia.c: remove definition of KRB_VERIFY_USER (moved to
+ config.h)
+
+ * sia/Makefile.am: make it build w/o krb4
+
+ * afskauthlib/verify.c: add krb5 support
+
+ * afskauthlib/Makefile.am: build afskauthlib.so
+
+Wed Apr 7 14:06:22 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * sia/sia.c: make it compile w/o krb4
+
+ * sia/Makefile.am: make it compile w/o krb4
+
+Thu Apr 1 18:09:23 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * sia/sia_locl.h: POSIX_GETPWNAM_R is defined in config.h
+
+Sun Mar 21 14:08:30 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * sia/Makefile.in: add posix_getpw.c
+
+ * sia/Makefile.am: makefile for sia
+
+ * sia/posix_getpw.c: move from sia.c
+
+ * sia/sia_locl.h: merge with krb5 version
+
+ * sia/sia.c: merge with krb5 version
+
+ * sia/sia5.c: remove unused variables
diff --git a/crypto/heimdal/lib/auth/Makefile.am b/crypto/heimdal/lib/auth/Makefile.am
new file mode 100644
index 000000000000..0310dc36d6cc
--- /dev/null
+++ b/crypto/heimdal/lib/auth/Makefile.am
@@ -0,0 +1,6 @@
+# $Id: Makefile.am,v 1.2 1999/03/21 17:11:08 joda Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+SUBDIRS = @LIB_AUTH_SUBDIRS@
+DIST_SUBDIRS = afskauthlib pam sia
diff --git a/crypto/heimdal/lib/auth/Makefile.in b/crypto/heimdal/lib/auth/Makefile.in
new file mode 100644
index 000000000000..aab069e54158
--- /dev/null
+++ b/crypto/heimdal/lib/auth/Makefile.in
@@ -0,0 +1,599 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.2 1999/03/21 17:11:08 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+SUBDIRS = @LIB_AUTH_SUBDIRS@
+DIST_SUBDIRS = afskauthlib pam sia
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .et .h .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/auth/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/auth
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(DIST_SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-recursive
+
+install-data-am: install-data-local
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile all-local
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+
+.PHONY: install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/auth/afskauthlib/Makefile.am b/crypto/heimdal/lib/auth/afskauthlib/Makefile.am
new file mode 100644
index 000000000000..7dd6d5283fe9
--- /dev/null
+++ b/crypto/heimdal/lib/auth/afskauthlib/Makefile.am
@@ -0,0 +1,38 @@
+# $Id: Makefile.am,v 1.3 1999/04/08 12:35:33 joda Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+DEFS = @DEFS@
+
+foodir = $(libdir)
+foo_DATA = afskauthlib.so
+
+SUFFIXES += .c .o
+
+SRCS = verify.c
+OBJS = verify.o
+
+CLEANFILES = $(foo_DATA) $(OBJS) so_locations
+
+afskauthlib.so: $(OBJS)
+ $(LD) -shared -o $@ $(LDFLAGS) $(OBJS) $(L)
+
+.c.o:
+ $(COMPILE) -c $<
+
+if KRB4
+KAFS = $(top_builddir)/lib/kafs/.libs/libkafs.a
+endif
+
+L = \
+ $(KAFS) \
+ $(top_builddir)/lib/krb5/.libs/libkrb5.a \
+ $(top_builddir)/lib/asn1/.libs/libasn1.a \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/.libs/libdes.a \
+ $(top_builddir)/lib/roken/.libs/libroken.a \
+ -lc
+
+$(OBJS): $(top_builddir)/include/config.h
diff --git a/crypto/heimdal/lib/auth/afskauthlib/Makefile.in b/crypto/heimdal/lib/auth/afskauthlib/Makefile.in
new file mode 100644
index 000000000000..d3a404172cf2
--- /dev/null
+++ b/crypto/heimdal/lib/auth/afskauthlib/Makefile.in
@@ -0,0 +1,538 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.3 1999/04/08 12:35:33 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x .c .o
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+DEFS = @DEFS@
+
+foodir = $(libdir)
+foo_DATA = afskauthlib.so
+
+SRCS = verify.c
+OBJS = verify.o
+
+CLEANFILES = $(foo_DATA) $(OBJS) so_locations
+
+@KRB4_TRUE@KAFS = $(top_builddir)/lib/kafs/.libs/libkafs.a
+
+L = $(KAFS) $(top_builddir)/lib/krb5/.libs/libkrb5.a $(top_builddir)/lib/asn1/.libs/libasn1.a $(LIB_krb4) $(top_builddir)/lib/des/.libs/libdes.a $(top_builddir)/lib/roken/.libs/libroken.a -lc
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../../include/config.h
+CONFIG_CLEAN_FILES =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DATA = $(foo_DATA)
+
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .c .cat1 .cat3 .cat5 .cat8 .et .h .o .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/auth/afskauthlib/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+install-fooDATA: $(foo_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(foodir)
+ @list='$(foo_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(foodir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(foodir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(foodir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(foodir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-fooDATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(foo_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(foodir)/$$p; \
+ done
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/auth/afskauthlib
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-fooDATA install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-fooDATA
+uninstall: uninstall-am
+all-am: Makefile $(DATA) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(foodir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: uninstall-fooDATA install-fooDATA tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+afskauthlib.so: $(OBJS)
+ $(LD) -shared -o $@ $(LDFLAGS) $(OBJS) $(L)
+
+.c.o:
+ $(COMPILE) -c $<
+
+$(OBJS): $(top_builddir)/include/config.h
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/auth/afskauthlib/verify.c b/crypto/heimdal/lib/auth/afskauthlib/verify.c
new file mode 100644
index 000000000000..1c23119f9fc7
--- /dev/null
+++ b/crypto/heimdal/lib/auth/afskauthlib/verify.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 1995-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: verify.c,v 1.20 1999/12/02 16:58:37 joda Exp $");
+#endif
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#ifdef KRB5
+#include <krb5.h>
+#endif
+#ifdef KRB4
+#include <krb.h>
+#include <kafs.h>
+#endif
+#include <roken.h>
+
+#ifdef KRB5
+static char krb5ccname[128];
+#endif
+#ifdef KRB4
+static char krbtkfile[128];
+#endif
+
+/*
+ In some cases is afs_gettktstring called twice (once before
+ afs_verify and once after afs_verify).
+ In some cases (rlogin with access allowed via .rhosts)
+ afs_verify is not called!
+ So we can't rely on correct value in krbtkfile in some
+ cases!
+*/
+
+static int correct_tkfilename=0;
+static int pag_set=0;
+
+#ifdef KRB4
+static void
+set_krbtkfile(uid_t uid)
+{
+ snprintf (krbtkfile, sizeof(krbtkfile), "%s%d", TKT_ROOT, (unsigned)uid);
+ krb_set_tkt_string (krbtkfile);
+ correct_tkfilename = 1;
+}
+#endif
+
+/* XXX this has to be the default cache name, since the KRB5CCNAME
+ * environment variable isn't exported by login/xdm
+ */
+
+#ifdef KRB5
+static void
+set_krb5ccname(uid_t uid)
+{
+ snprintf (krb5ccname, sizeof(krb5ccname), "FILE:/tmp/krb5cc_%d", uid);
+#ifdef KRB4
+ snprintf (krbtkfile, sizeof(krbtkfile), "%s%d", TKT_ROOT, (unsigned)uid);
+#endif
+ correct_tkfilename = 1;
+}
+#endif
+
+static void
+set_spec_krbtkfile(void)
+{
+ int fd;
+#ifdef KRB4
+ snprintf (krbtkfile, sizeof(krbtkfile), "%s_XXXXXX", TKT_ROOT);
+ fd = mkstemp(krbtkfile);
+ close(fd);
+ unlink(krbtkfile);
+ krb_set_tkt_string (krbtkfile);
+#endif
+#ifdef KRB5
+ snprintf(krb5ccname, sizeof(krb5ccname),"FILE:/tmp/krb5cc_XXXXXX");
+ fd=mkstemp(krb5ccname+5);
+ close(fd);
+ unlink(krb5ccname+5);
+#endif
+}
+
+#ifdef KRB5
+static int
+verify_krb5(struct passwd *pwd,
+ char *password,
+ int32_t *exp,
+ int quiet)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ krb5_ccache ccache;
+ krb5_principal principal;
+
+ krb5_init_context(&context);
+
+ ret = krb5_parse_name (context, pwd->pw_name, &principal);
+ if (ret) {
+ syslog(LOG_AUTH|LOG_DEBUG, "krb5_parse_name: %s",
+ krb5_get_err_text(context, ret));
+ goto out;
+ }
+
+ set_krb5ccname(pwd->pw_uid);
+ ret = krb5_cc_resolve(context, krb5ccname, &ccache);
+ if(ret) {
+ syslog(LOG_AUTH|LOG_DEBUG, "krb5_cc_resolve: %s",
+ krb5_get_err_text(context, ret));
+ goto out;
+ }
+
+ ret = krb5_verify_user_lrealm(context,
+ principal,
+ ccache,
+ password,
+ TRUE,
+ NULL);
+ if(ret) {
+ syslog(LOG_AUTH|LOG_DEBUG, "krb5_verify_user: %s",
+ krb5_get_err_text(context, ret));
+ goto out;
+ }
+
+ if(chown(krb5_cc_get_name(context, ccache), pwd->pw_uid, pwd->pw_gid)) {
+ syslog(LOG_AUTH|LOG_DEBUG, "chown: %s",
+ krb5_get_err_text(context, errno));
+ goto out;
+ }
+
+#ifdef KRB4
+ if (krb5_config_get_bool(context, NULL,
+ "libdefaults",
+ "krb4_get_tickets",
+ NULL)) {
+ CREDENTIALS c;
+ krb5_creds mcred, cred;
+ krb5_realm realm;
+
+ krb5_get_default_realm(context, &realm);
+ krb5_make_principal(context, &mcred.server, realm,
+ "krbtgt",
+ realm,
+ NULL);
+ free (realm);
+ ret = krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
+ if(ret == 0) {
+ ret = krb524_convert_creds_kdc(context, ccache, &cred, &c);
+ if(ret)
+ krb5_warn(context, ret, "converting creds");
+ else {
+ set_krbtkfile(pwd->pw_uid);
+ tf_setup(&c, c.pname, c.pinst);
+ }
+ memset(&c, 0, sizeof(c));
+ krb5_free_creds_contents(context, &cred);
+ } else
+ syslog(LOG_AUTH|LOG_DEBUG, "krb5_cc_retrieve_cred: %s",
+ krb5_get_err_text(context, ret));
+
+ krb5_free_principal(context, mcred.server);
+ }
+ if (!pag_set && k_hasafs()) {
+ k_setpag();
+ pag_set = 1;
+ krb5_afslog_uid_home(context, ccache, NULL, NULL,
+ pwd->pw_uid, pwd->pw_dir);
+ }
+#endif
+out:
+ if(ret && !quiet)
+ printf ("%s\n", krb5_get_err_text (context, ret));
+ return ret;
+}
+#endif
+
+#ifdef KRB4
+static int
+verify_krb4(struct passwd *pwd,
+ char *password,
+ int32_t *exp,
+ int quiet)
+{
+ int ret = 1;
+ char lrealm[REALM_SZ];
+
+ if (krb_get_lrealm (lrealm, 1) != KFAILURE) {
+ set_krbtkfile(pwd->pw_uid);
+ ret = krb_verify_user (pwd->pw_name, "", lrealm, password,
+ KRB_VERIFY_SECURE, NULL);
+ if (ret == KSUCCESS) {
+ if (!pag_set && k_hasafs()) {
+ k_setpag ();
+ pag_set = 1;
+ krb_afslog_uid_home (0, 0, pwd->pw_uid, pwd->pw_dir);
+ }
+ } else if (!quiet)
+ printf ("%s\n", krb_get_err_text (ret));
+ }
+ return ret;
+}
+#endif
+
+int
+afs_verify(char *name,
+ char *password,
+ int32_t *exp,
+ int quiet)
+{
+ int ret = 1;
+ struct passwd *pwd = k_getpwnam (name);
+
+ if(pwd == NULL)
+ return 1;
+ if (ret)
+ ret = unix_verify_user (name, password);
+#ifdef KRB5
+ if (ret)
+ ret = verify_krb5(pwd, password, exp, quiet);
+#endif
+#ifdef KRB4
+ if(ret)
+ ret = verify_krb4(pwd, password, exp, quiet);
+#endif
+ return ret;
+}
+
+char *
+afs_gettktstring (void)
+{
+ char *ptr;
+ struct passwd *pwd;
+
+ if (!correct_tkfilename) {
+ ptr = getenv("LOGNAME");
+ if (ptr != NULL && ((pwd = getpwnam(ptr)) != NULL)) {
+ set_krb5ccname(pwd->pw_uid);
+#ifdef KRB4
+ set_krbtkfile(pwd->pw_uid);
+ if (!pag_set && k_hasafs()) {
+ k_setpag();
+ pag_set=1;
+ }
+#endif
+ } else {
+ set_spec_krbtkfile();
+ }
+ }
+#ifdef KRB5
+ setenv("KRB5CCNAME",krb5ccname,1);
+#endif
+#ifdef KRB4
+ setenv("KRBTKFILE",krbtkfile,1);
+ return krbtkfile;
+#else
+ return "";
+#endif
+}
diff --git a/crypto/heimdal/lib/auth/pam/Makefile.am b/crypto/heimdal/lib/auth/pam/Makefile.am
new file mode 100644
index 000000000000..abde2d9a4938
--- /dev/null
+++ b/crypto/heimdal/lib/auth/pam/Makefile.am
@@ -0,0 +1,3 @@
+# $Id: Makefile.am,v 1.2 1999/04/01 14:57:04 joda Exp $
+
+include $(top_srcdir)/Makefile.am.common
diff --git a/crypto/heimdal/lib/auth/pam/Makefile.in b/crypto/heimdal/lib/auth/pam/Makefile.in
new file mode 100644
index 000000000000..37f8d22f1dd3
--- /dev/null
+++ b/crypto/heimdal/lib/auth/pam/Makefile.in
@@ -0,0 +1,491 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.2 1999/04/01 14:57:04 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../../include/config.h
+CONFIG_CLEAN_FILES =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .et .h .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/auth/pam/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/auth/pam
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: tags distdir info-am info dvi-am dvi check-local check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-local install-data-am install-data install-am install \
+uninstall-am uninstall all-local all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/auth/pam/pam.c b/crypto/heimdal/lib/auth/pam/pam.c
new file mode 100644
index 000000000000..d919bf8f83b8
--- /dev/null
+++ b/crypto/heimdal/lib/auth/pam/pam.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* This code is extremely ugly, and would probably be better off
+ beeing completely rewritten */
+
+
+#ifdef HAVE_CONFIG_H
+#include<config.h>
+RCSID("$Id: pam.c,v 1.22 1999/12/02 16:58:37 joda Exp $");
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#define PAM_SM_AUTH
+#define PAM_SM_SESSION
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+
+#include <netinet/in.h>
+#include <krb.h>
+#include <kafs.h>
+
+static int
+cleanup(pam_handle_t *pamh, void *data, int error_code)
+{
+ if(error_code != PAM_SUCCESS)
+ dest_tkt();
+ free(data);
+ return PAM_SUCCESS;
+}
+
+static int
+doit(pam_handle_t *pamh, char *name, char *inst, char *pwd, char *tkt)
+{
+ char realm[REALM_SZ];
+ int ret;
+
+ pam_set_data(pamh, "KRBTKFILE", strdup(tkt), cleanup);
+ krb_set_tkt_string(tkt);
+
+ krb_get_lrealm(realm, 1);
+ ret = krb_verify_user(name, inst, realm, pwd, KRB_VERIFY_SECURE, NULL);
+ memset(pwd, 0, strlen(pwd));
+ switch(ret){
+ case KSUCCESS:
+ return PAM_SUCCESS;
+ case KDC_PR_UNKNOWN:
+ return PAM_USER_UNKNOWN;
+ case SKDC_CANT:
+ case SKDC_RETRY:
+ case RD_AP_TIME:
+ return PAM_AUTHINFO_UNAVAIL;
+ default:
+ return PAM_AUTH_ERR;
+ }
+}
+
+static int
+auth_login(pam_handle_t *pamh, int flags, char *user, struct pam_conv *conv)
+{
+ int ret;
+ struct pam_message msg, *pmsg;
+ struct pam_response *resp;
+ char prompt[128];
+
+ pmsg = &msg;
+ msg.msg_style = PAM_PROMPT_ECHO_OFF;
+ snprintf(prompt, sizeof(prompt), "%s's Password: ", user);
+ msg.msg = prompt;
+
+ ret = conv->conv(1, (const struct pam_message**)&pmsg,
+ &resp, conv->appdata_ptr);
+ if(ret != PAM_SUCCESS)
+ return ret;
+
+ {
+ char tkt[1024];
+ struct passwd *pw = getpwnam(user);
+
+ if(pw){
+ snprintf(tkt, sizeof(tkt),
+ "%s%u", TKT_ROOT, (unsigned)pw->pw_uid);
+ ret = doit(pamh, user, "", resp->resp, tkt);
+ if(ret == PAM_SUCCESS)
+ chown(tkt, pw->pw_uid, pw->pw_gid);
+ }else
+ ret = PAM_USER_UNKNOWN;
+ memset(resp->resp, 0, strlen(resp->resp));
+ free(resp->resp);
+ free(resp);
+ }
+ return ret;
+}
+
+static int
+auth_su(pam_handle_t *pamh, int flags, char *user, struct pam_conv *conv)
+{
+ int ret;
+ struct passwd *pw;
+ struct pam_message msg, *pmsg;
+ struct pam_response *resp;
+ char prompt[128];
+ krb_principal pr;
+
+ pr.realm[0] = 0;
+ ret = pam_get_user(pamh, &user, "login: ");
+ if(ret != PAM_SUCCESS)
+ return ret;
+
+ pw = getpwuid(getuid());
+ if(strcmp(user, "root") == 0){
+ strlcpy(pr.name, pw->pw_name, sizeof(pr.name));
+ strlcpy(pr.instance, "root", sizeof(pr.instance));
+ }else{
+ strlcpy(pr.name, user, sizeof(pr.name));
+ pr.instance[0] = 0;
+ }
+ pmsg = &msg;
+ msg.msg_style = PAM_PROMPT_ECHO_OFF;
+ snprintf(prompt, sizeof(prompt), "%s's Password: ", krb_unparse_name(&pr));
+ msg.msg = prompt;
+
+ ret = conv->conv(1, (const struct pam_message**)&pmsg,
+ &resp, conv->appdata_ptr);
+ if(ret != PAM_SUCCESS)
+ return ret;
+
+ {
+ char tkt[1024];
+
+ snprintf(tkt, sizeof(tkt),"%s_%s_to_%s",
+ TKT_ROOT, pw->pw_name, user);
+ ret = doit(pamh, pr.name, pr.instance, resp->resp, tkt);
+ if(ret == PAM_SUCCESS)
+ chown(tkt, pw->pw_uid, pw->pw_gid);
+ memset(resp->resp, 0, strlen(resp->resp));
+ free(resp->resp);
+ free(resp);
+ }
+ return ret;
+}
+
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ char *user;
+ int ret;
+ struct pam_conv *conv;
+ ret = pam_get_user(pamh, &user, "login: ");
+ if(ret != PAM_SUCCESS)
+ return ret;
+
+ ret = pam_get_item(pamh, PAM_CONV, (void*)&conv);
+ if(ret != PAM_SUCCESS)
+ return ret;
+
+
+ if(getuid() != geteuid())
+ return auth_su(pamh, flags, user, conv);
+ else
+ return auth_login(pamh, flags, user, conv);
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ char *tkt, *var;
+ void *user;
+ const char *homedir = NULL;
+
+ if(pam_get_item (pamh, PAM_USER, &user) == PAM_SUCCESS) {
+ struct passwd *pwd;
+
+ pwd = getpwnam ((char *)user);
+ if (pwd != NULL)
+ homedir = pwd->pw_dir;
+ }
+
+ pam_get_data(pamh, "KRBTKFILE", (const void**)&tkt);
+ var = malloc(strlen("KRBTKFILE=") + strlen(tkt) + 1);
+ strcpy(var, "KRBTKFILE=");
+ strcat(var, tkt);
+ putenv(var);
+ pam_putenv(pamh, var);
+ if(k_hasafs()){
+ k_setpag();
+ krb_afslog_home(0, 0, homedir);
+ }
+ return PAM_SUCCESS;
+}
+
+
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ dest_tkt();
+ if(k_hasafs())
+ k_unlog();
+ return PAM_SUCCESS;
+}
diff --git a/crypto/heimdal/lib/auth/pam/pam.conf.add b/crypto/heimdal/lib/auth/pam/pam.conf.add
new file mode 100644
index 000000000000..42497d2b44a0
--- /dev/null
+++ b/crypto/heimdal/lib/auth/pam/pam.conf.add
@@ -0,0 +1,76 @@
+To enable PAM in dtlogin and /bin/login under SunOS 5.6 apply this patch:
+
+--- /etc/pam.conf.DIST Mon Jul 20 15:37:46 1998
++++ /etc/pam.conf Tue Nov 30 18:47:22 1999
+@@ -4,12 +4,14 @@
+ #
+ # Authentication management
+ #
++login auth sufficient /usr/athena/lib/pam_krb4.so
+ login auth required /usr/lib/security/pam_unix.so.1
+ login auth required /usr/lib/security/pam_dial_auth.so.1
+ #
+ rlogin auth sufficient /usr/lib/security/pam_rhosts_auth.so.1
+ rlogin auth required /usr/lib/security/pam_unix.so.1
+ #
++dtlogin auth sufficient /usr/athena/lib/pam_krb4.so
+ dtlogin auth required /usr/lib/security/pam_unix.so.1
+ #
+ rsh auth required /usr/lib/security/pam_rhosts_auth.so.1
+@@ -24,6 +26,8 @@
+ #
+ # Session management
+ #
++dtlogin session required /usr/athena/lib/pam_krb4.so
++login session required /usr/athena/lib/pam_krb4.so
+ other session required /usr/lib/security/pam_unix.so.1
+ #
+ # Password management
+---------------------------------------------------------------------------
+To enable PAM in /bin/login and xdm under Red Hat 6.1 apply these patches:
+
+--- /etc/pam.d/login~ Thu Jul 8 00:14:02 1999
++++ /etc/pam.d/login Mon Aug 30 14:33:12 1999
+@@ -1,9 +1,12 @@
+ #%PAM-1.0
++# Updated to work with kerberos
++auth sufficient /lib/security/pam_krb4.so
+ auth required /lib/security/pam_securetty.so
+ auth required /lib/security/pam_pwdb.so shadow nullok
+ auth required /lib/security/pam_nologin.so
+ account required /lib/security/pam_pwdb.so
+ password required /lib/security/pam_cracklib.so
+ password required /lib/security/pam_pwdb.so nullok use_authtok shadow
++session required /lib/security/pam_krb4.so
+ session required /lib/security/pam_pwdb.so
+ session optional /lib/security/pam_console.so
+--- /etc/pam.d/xdm~ Mon Jun 14 17:39:05 1999
++++ /etc/pam.d/xdm Mon Aug 30 14:54:51 1999
+@@ -1,8 +1,10 @@
+ #%PAM-1.0
++auth sufficient /lib/security/pam_krb4.so
+ auth required /lib/security/pam_pwdb.so shadow nullok
+ auth required /lib/security/pam_nologin.so
+ account required /lib/security/pam_pwdb.so
+ password required /lib/security/pam_cracklib.so
+ password required /lib/security/pam_pwdb.so shadow nullok use_authtok
++session required /lib/security/pam_krb4.so
+ session required /lib/security/pam_pwdb.so
+ session optional /lib/security/pam_console.so
+--------------------------------------------------------------------------
+
+This stuff may work under some other system.
+
+# To get this to work, you will have to add entries to /etc/pam.conf
+#
+# To make login kerberos-aware, you might change pam.conf to look
+# like:
+
+# login authorization
+login auth sufficient /lib/security/pam_krb4.so
+login auth required /lib/security/pam_securetty.so
+login auth required /lib/security/pam_unix_auth.so
+login account required /lib/security/pam_unix_acct.so
+login password required /lib/security/pam_unix_passwd.so
+login session required /lib/security/pam_krb4.so
+login session required /lib/security/pam_unix_session.so
diff --git a/crypto/heimdal/lib/auth/sia/Makefile.am b/crypto/heimdal/lib/auth/sia/Makefile.am
new file mode 100644
index 000000000000..efba5c028f7f
--- /dev/null
+++ b/crypto/heimdal/lib/auth/sia/Makefile.am
@@ -0,0 +1,66 @@
+# $Id: Makefile.am,v 1.5 1999/12/30 03:47:03 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+WFLAGS += $(WFLAGS_NOIMPLICITINT)
+
+DEFS = @DEFS@
+
+## this is horribly ugly, but automake/libtool doesn't allow us to
+## unconditionally build shared libraries, and it does not allow us to
+## link with non-installed libraries
+
+if KRB4
+KAFS=$(top_builddir)/lib/kafs/.libs/libkafs.a
+KAFS_S=$(top_builddir)/lib/kafs/.libs/libkafs.so
+endif
+
+L = \
+ $(KAFS) \
+ $(top_builddir)/lib/krb5/.libs/libkrb5.a \
+ $(top_builddir)/lib/asn1/.libs/libasn1.a \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/.libs/libdes.a \
+ $(top_builddir)/lib/com_err/.libs/libcom_err.a \
+ $(top_builddir)/lib/roken/.libs/libroken.a \
+ $(LIB_getpwnam_r) \
+ -lc
+
+L_shared = \
+ $(KAFS_S) \
+ $(top_builddir)/lib/krb5/.libs/libkrb5.so \
+ $(top_builddir)/lib/asn1/.libs/libasn1.so \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/.libs/libdes.so \
+ $(top_builddir)/lib/com_err/.libs/libcom_err.so \
+ $(top_builddir)/lib/roken/.libs/libroken.so \
+ $(LIB_getpwnam_r) \
+ -lc
+
+EXTRA_DIST = sia.c krb5_matrix.conf krb5+c2_matrix.conf security.patch
+
+foodir = $(libdir)
+foo_DATA = libsia_krb5.so
+
+LDFLAGS = -rpath $(libdir) -hidden -exported_symbol siad_\*
+
+OBJS = sia.o posix_getpw.o
+
+libsia_krb5.so: $(OBJS)
+ if test -f $(top_builddir)/lib/krb5/.libs/libkrb5.a; then \
+ ld -shared -o $@ $(LDFLAGS) $(OBJS) $(L); \
+ elif test -f $(top_builddir)/lib/krb5/.libs/libkrb5.so; then \
+ ld -shared -o $@ $(LDFLAGS) $(OBJS) $(L_shared); \
+ else \
+ echo "missing libraries"; exit 1; \
+ fi
+ ostrip -x -z $@
+
+CLEANFILES = libsia_krb5.so $(OBJS) so_locations
+
+SUFFIXES += .c .o
+
+.c.o:
+ $(COMPILE) -c $<
diff --git a/crypto/heimdal/lib/auth/sia/Makefile.in b/crypto/heimdal/lib/auth/sia/Makefile.in
new file mode 100644
index 000000000000..fb36b4ec8282
--- /dev/null
+++ b/crypto/heimdal/lib/auth/sia/Makefile.in
@@ -0,0 +1,551 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.5 1999/12/30 03:47:03 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x .c .o
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+WFLAGS = @WFLAGS@ $(WFLAGS_NOIMPLICITINT)
+
+DEFS = @DEFS@
+
+@KRB4_TRUE@KAFS = $(top_builddir)/lib/kafs/.libs/libkafs.a
+@KRB4_TRUE@KAFS_S = $(top_builddir)/lib/kafs/.libs/libkafs.so
+
+L = $(KAFS) $(top_builddir)/lib/krb5/.libs/libkrb5.a $(top_builddir)/lib/asn1/.libs/libasn1.a $(LIB_krb4) $(top_builddir)/lib/des/.libs/libdes.a $(top_builddir)/lib/com_err/.libs/libcom_err.a $(top_builddir)/lib/roken/.libs/libroken.a $(LIB_getpwnam_r) -lc
+
+
+L_shared = $(KAFS_S) $(top_builddir)/lib/krb5/.libs/libkrb5.so $(top_builddir)/lib/asn1/.libs/libasn1.so $(LIB_krb4) $(top_builddir)/lib/des/.libs/libdes.so $(top_builddir)/lib/com_err/.libs/libcom_err.so $(top_builddir)/lib/roken/.libs/libroken.so $(LIB_getpwnam_r) -lc
+
+
+EXTRA_DIST = sia.c krb5_matrix.conf krb5+c2_matrix.conf security.patch
+
+foodir = $(libdir)
+foo_DATA = libsia_krb5.so
+
+LDFLAGS = -rpath $(libdir) -hidden -exported_symbol siad_\*
+
+OBJS = sia.o posix_getpw.o
+
+CLEANFILES = libsia_krb5.so $(OBJS) so_locations
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../../include/config.h
+CONFIG_CLEAN_FILES =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DATA = $(foo_DATA)
+
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .c .cat1 .cat3 .cat5 .cat8 .et .h .o .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/auth/sia/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+install-fooDATA: $(foo_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(foodir)
+ @list='$(foo_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(foodir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(foodir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(foodir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(foodir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-fooDATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(foo_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(foodir)/$$p; \
+ done
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/auth/sia
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-fooDATA install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-fooDATA
+uninstall: uninstall-am
+all-am: Makefile $(DATA) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(foodir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: uninstall-fooDATA install-fooDATA tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+libsia_krb5.so: $(OBJS)
+ if test -f $(top_builddir)/lib/krb5/.libs/libkrb5.a; then \
+ ld -shared -o $@ $(LDFLAGS) $(OBJS) $(L); \
+ elif test -f $(top_builddir)/lib/krb5/.libs/libkrb5.so; then \
+ ld -shared -o $@ $(LDFLAGS) $(OBJS) $(L_shared); \
+ else \
+ echo "missing libraries"; exit 1; \
+ fi
+ ostrip -x -z $@
+
+.c.o:
+ $(COMPILE) -c $<
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/auth/sia/krb4+c2_matrix.conf b/crypto/heimdal/lib/auth/sia/krb4+c2_matrix.conf
new file mode 100644
index 000000000000..4b90e0264a37
--- /dev/null
+++ b/crypto/heimdal/lib/auth/sia/krb4+c2_matrix.conf
@@ -0,0 +1,58 @@
+# Copyright (c) 1998 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 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.
+
+# $Id: krb4+c2_matrix.conf,v 1.4 1999/12/02 16:58:37 joda Exp $
+
+# sia matrix configuration file (Kerberos 4 + C2)
+
+siad_init=(KRB4,/usr/athena/lib/libsia_krb4.so)(BSD,libc.so)
+siad_chk_invoker=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_init=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_authent=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_estab=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_launch=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_suauthent=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_reauthent=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_chg_finger=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_chg_password=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_chg_shell=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_getpwent=(BSD,libc.so)
+siad_getpwuid=(BSD,libc.so)
+siad_getpwnam=(BSD,libc.so)
+siad_setpwent=(BSD,libc.so)
+siad_endpwent=(BSD,libc.so)
+siad_getgrent=(BSD,libc.so)
+siad_getgrgid=(BSD,libc.so)
+siad_getgrnam=(BSD,libc.so)
+siad_setgrent=(BSD,libc.so)
+siad_endgrent=(BSD,libc.so)
+siad_ses_release=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_chk_user=(KRB4,/usr/athena/lib/libsia_krb4.so)(OSFC2,/usr/shlib/libsecurity.so)
diff --git a/crypto/heimdal/lib/auth/sia/krb4_matrix.conf b/crypto/heimdal/lib/auth/sia/krb4_matrix.conf
new file mode 100644
index 000000000000..4f55a810ce71
--- /dev/null
+++ b/crypto/heimdal/lib/auth/sia/krb4_matrix.conf
@@ -0,0 +1,59 @@
+# Copyright (c) 1998 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 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.
+
+# $Id: krb4_matrix.conf,v 1.6 1999/12/02 16:58:37 joda Exp $
+
+# sia matrix configuration file (Kerberos 4 + BSD)
+
+siad_init=(KRB4,/usr/athena/lib/libsia_krb4.so)(BSD,libc.so)
+siad_chk_invoker=(BSD,libc.so)
+siad_ses_init=(KRB4,/usr/athena/lib/libsia_krb4.so)
+siad_ses_authent=(KRB4,/usr/athena/lib/libsia_krb4.so)(BSD,libc.so)
+siad_ses_estab=(BSD,libc.so)
+siad_ses_launch=(KRB4,/usr/athena/lib/libsia_krb4.so)(BSD,libc.so)
+siad_ses_suauthent=(KRB4,/usr/athena/lib/libsia_krb4.so)(BSD,libc.so)
+siad_ses_reauthent=(KRB4,/usr/athena/lib/libsia_krb4.so)(BSD,libc.so)
+siad_chg_finger=(BSD,libc.so)
+siad_chg_password=(KRB4,/usr/athena/lib/libsia_krb4.so)(BSD,libc.so)
+siad_chg_shell=(BSD,libc.so)
+siad_getpwent=(BSD,libc.so)
+siad_getpwuid=(BSD,libc.so)
+siad_getpwnam=(BSD,libc.so)
+siad_setpwent=(BSD,libc.so)
+siad_endpwent=(BSD,libc.so)
+siad_getgrent=(BSD,libc.so)
+siad_getgrgid=(BSD,libc.so)
+siad_getgrnam=(BSD,libc.so)
+siad_setgrent=(BSD,libc.so)
+siad_endgrent=(BSD,libc.so)
+siad_ses_release=(KRB4,/usr/athena/lib/libsia_krb4.so)(BSD,libc.so)
+siad_chk_user=(KRB4,/usr/athena/lib/libsia_krb4.so)(BSD,libc.so)
+
diff --git a/crypto/heimdal/lib/auth/sia/krb5+c2_matrix.conf b/crypto/heimdal/lib/auth/sia/krb5+c2_matrix.conf
new file mode 100644
index 000000000000..c2952e2db8f6
--- /dev/null
+++ b/crypto/heimdal/lib/auth/sia/krb5+c2_matrix.conf
@@ -0,0 +1,27 @@
+# $Id: krb5+c2_matrix.conf,v 1.2 1998/11/26 20:58:18 assar Exp $
+
+# sia matrix configuration file (Kerberos 5 + C2)
+
+siad_init=(KRB5,/usr/athena/lib/libsia_krb5.so)(BSD,libc.so)
+siad_chk_invoker=(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_init=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_authent=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_estab=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_launch=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_suauthent=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_ses_reauthent=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_chg_finger=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_chg_password=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_chg_shell=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_getpwent=(BSD,libc.so)
+siad_getpwuid=(BSD,libc.so)
+siad_getpwnam=(BSD,libc.so)
+siad_setpwent=(BSD,libc.so)
+siad_endpwent=(BSD,libc.so)
+siad_getgrent=(BSD,libc.so)
+siad_getgrgid=(BSD,libc.so)
+siad_getgrnam=(BSD,libc.so)
+siad_setgrent=(BSD,libc.so)
+siad_endgrent=(BSD,libc.so)
+siad_ses_release=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
+siad_chk_user=(KRB5,/usr/athena/lib/libsia_krb5.so)(OSFC2,/usr/shlib/libsecurity.so)
diff --git a/crypto/heimdal/lib/auth/sia/krb5_matrix.conf b/crypto/heimdal/lib/auth/sia/krb5_matrix.conf
new file mode 100644
index 000000000000..e49366aefc67
--- /dev/null
+++ b/crypto/heimdal/lib/auth/sia/krb5_matrix.conf
@@ -0,0 +1,27 @@
+# $Id: krb5_matrix.conf,v 1.1 1997/05/15 18:34:18 joda Exp $
+
+# sia matrix configuration file (Kerberos 5 + BSD)
+
+siad_init=(KRB5,/usr/athena/lib/libsia_krb5.so)(BSD,libc.so)
+siad_chk_invoker=(BSD,libc.so)
+siad_ses_init=(KRB5,/usr/athena/lib/libsia_krb5.so)
+siad_ses_authent=(KRB5,/usr/athena/lib/libsia_krb5.so)(BSD,libc.so)
+siad_ses_estab=(BSD,libc.so)
+siad_ses_launch=(KRB5,/usr/athena/lib/libsia_krb5.so)(BSD,libc.so)
+siad_ses_suauthent=(KRB5,/usr/athena/lib/libsia_krb5.so)(BSD,libc.so)
+siad_ses_reauthent=(BSD,libc.so)
+siad_chg_finger=(BSD,libc.so)
+siad_chg_password=(BSD,libc.so)
+siad_chg_shell=(BSD,libc.so)
+siad_getpwent=(BSD,libc.so)
+siad_getpwuid=(BSD,libc.so)
+siad_getpwnam=(BSD,libc.so)
+siad_setpwent=(BSD,libc.so)
+siad_endpwent=(BSD,libc.so)
+siad_getgrent=(BSD,libc.so)
+siad_getgrgid=(BSD,libc.so)
+siad_getgrnam=(BSD,libc.so)
+siad_setgrent=(BSD,libc.so)
+siad_endgrent=(BSD,libc.so)
+siad_ses_release=(KRB5,/usr/athena/lib/libsia_krb5.so)(BSD,libc.so)
+siad_chk_user=(BSD,libc.so)
diff --git a/crypto/heimdal/lib/auth/sia/posix_getpw.c b/crypto/heimdal/lib/auth/sia/posix_getpw.c
new file mode 100644
index 000000000000..c5961dcd2c5b
--- /dev/null
+++ b/crypto/heimdal/lib/auth/sia/posix_getpw.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "sia_locl.h"
+
+RCSID("$Id: posix_getpw.c,v 1.1 1999/03/21 17:07:02 joda Exp $");
+
+#ifndef POSIX_GETPWNAM_R
+/*
+ * These functions translate from the old Digital UNIX 3.x interface
+ * to POSIX.1c.
+ */
+
+int
+posix_getpwnam_r(const char *name, struct passwd *pwd,
+ char *buffer, int len, struct passwd **result)
+{
+ int ret = getpwnam_r(name, pwd, buffer, len);
+ if(ret == 0)
+ *result = pwd;
+ else{
+ *result = NULL;
+ ret = _Geterrno();
+ if(ret == 0){
+ ret = ERANGE;
+ _Seterrno(ret);
+ }
+ }
+ return ret;
+}
+
+int
+posix_getpwuid_r(uid_t uid, struct passwd *pwd,
+ char *buffer, int len, struct passwd **result)
+{
+ int ret = getpwuid_r(uid, pwd, buffer, len);
+ if(ret == 0)
+ *result = pwd;
+ else{
+ *result = NULL;
+ ret = _Geterrno();
+ if(ret == 0){
+ ret = ERANGE;
+ _Seterrno(ret);
+ }
+ }
+ return ret;
+}
+#endif /* POSIX_GETPWNAM_R */
diff --git a/crypto/heimdal/lib/auth/sia/security.patch b/crypto/heimdal/lib/auth/sia/security.patch
new file mode 100644
index 000000000000..c407876d6362
--- /dev/null
+++ b/crypto/heimdal/lib/auth/sia/security.patch
@@ -0,0 +1,11 @@
+--- /sbin/init.d/security~ Tue Aug 20 22:44:09 1996
++++ /sbin/init.d/security Fri Nov 1 14:52:56 1996
+@@ -49,7 +49,7 @@
+ SECURITY=BASE
+ fi
+ ;;
+- BASE)
++ BASE|KRB4)
+ ;;
+ *)
+ echo "security configuration set to default (BASE)."
diff --git a/crypto/heimdal/lib/auth/sia/sia.c b/crypto/heimdal/lib/auth/sia/sia.c
new file mode 100644
index 000000000000..01e2ac005037
--- /dev/null
+++ b/crypto/heimdal/lib/auth/sia/sia.c
@@ -0,0 +1,672 @@
+/*
+ * Copyright (c) 1995-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "sia_locl.h"
+
+RCSID("$Id: sia.c,v 1.33 1999/12/20 09:46:44 joda Exp $");
+
+int
+siad_init(void)
+{
+ return SIADSUCCESS;
+}
+
+int
+siad_chk_invoker(void)
+{
+ SIA_DEBUG(("DEBUG", "siad_chk_invoker"));
+ return SIADFAIL;
+}
+
+int
+siad_ses_init(SIAENTITY *entity, int pkgind)
+{
+ struct state *s = malloc(sizeof(*s));
+ SIA_DEBUG(("DEBUG", "siad_ses_init"));
+ if(s == NULL)
+ return SIADFAIL;
+ memset(s, 0, sizeof(*s));
+#ifdef SIA_KRB5
+ krb5_init_context(&s->context);
+#endif
+ entity->mech[pkgind] = (int*)s;
+ return SIADSUCCESS;
+}
+
+static int
+setup_name(SIAENTITY *e, prompt_t *p)
+{
+ SIA_DEBUG(("DEBUG", "setup_name"));
+ e->name = malloc(SIANAMEMIN + 1);
+ if(e->name == NULL){
+ SIA_DEBUG(("DEBUG", "failed to malloc %u bytes", SIANAMEMIN+1));
+ return SIADFAIL;
+ }
+ p->prompt = (unsigned char*)"login: ";
+ p->result = (unsigned char*)e->name;
+ p->min_result_length = 1;
+ p->max_result_length = SIANAMEMIN;
+ p->control_flags = 0;
+ return SIADSUCCESS;
+}
+
+static int
+setup_password(SIAENTITY *e, prompt_t *p)
+{
+ SIA_DEBUG(("DEBUG", "setup_password"));
+ e->password = malloc(SIAMXPASSWORD + 1);
+ if(e->password == NULL){
+ SIA_DEBUG(("DEBUG", "failed to malloc %u bytes", SIAMXPASSWORD+1));
+ return SIADFAIL;
+ }
+ p->prompt = (unsigned char*)"Password: ";
+ p->result = (unsigned char*)e->password;
+ p->min_result_length = 0;
+ p->max_result_length = SIAMXPASSWORD;
+ p->control_flags = SIARESINVIS;
+ return SIADSUCCESS;
+}
+
+
+static int
+doauth(SIAENTITY *entity, int pkgind, char *name)
+{
+ struct passwd pw, *pwd;
+ char pwbuf[1024];
+ struct state *s = (struct state*)entity->mech[pkgind];
+#ifdef SIA_KRB5
+ krb5_realm *realms, *r;
+ krb5_principal principal;
+ krb5_ccache ccache;
+ krb5_error_code ret;
+#endif
+#ifdef SIA_KRB4
+ char realm[REALM_SZ];
+ char *toname, *toinst;
+ int ret;
+ struct passwd fpw, *fpwd;
+ char fpwbuf[1024];
+ int secure;
+#endif
+
+ if(getpwnam_r(name, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0){
+ SIA_DEBUG(("DEBUG", "failed to getpwnam(%s)", name));
+ return SIADFAIL;
+ }
+
+#ifdef SIA_KRB5
+ ret = krb5_get_default_realms(s->context, &realms);
+
+ for (r = realms; *r != NULL; ++r) {
+ krb5_make_principal (s->context, &principal, *r, entity->name, NULL);
+
+ if(krb5_kuserok(s->context, principal, entity->name))
+ break;
+ }
+ krb5_free_host_realm (s->context, realms);
+ if (*r == NULL)
+ return SIADFAIL;
+
+ sprintf(s->ticket, "FILE:/tmp/krb5_cc%d_%d", pwd->pw_uid, getpid());
+ ret = krb5_cc_resolve(s->context, s->ticket, &ccache);
+ if(ret)
+ return SIADFAIL;
+#endif
+
+#ifdef SIA_KRB4
+ snprintf(s->ticket, sizeof(s->ticket),
+ "%s%u_%u", TKT_ROOT, (unsigned)pwd->pw_uid, (unsigned)getpid());
+ krb_get_lrealm(realm, 1);
+ toname = name;
+ toinst = "";
+ if(entity->authtype == SIA_A_SUAUTH){
+ uid_t ouid;
+#ifdef HAVE_SIAENTITY_OUID
+ ouid = entity->ouid;
+#else
+ ouid = getuid();
+#endif
+ if(getpwuid_r(ouid, &fpw, fpwbuf, sizeof(fpwbuf), &fpwd) != 0){
+ SIA_DEBUG(("DEBUG", "failed to getpwuid(%u)", ouid));
+ return SIADFAIL;
+ }
+ snprintf(s->ticket, sizeof(s->ticket), "%s_%s_to_%s_%d",
+ TKT_ROOT, fpwd->pw_name, pwd->pw_name, getpid());
+ if(strcmp(pwd->pw_name, "root") == 0){
+ toname = fpwd->pw_name;
+ toinst = pwd->pw_name;
+ }
+ }
+ if(entity->authtype == SIA_A_REAUTH)
+ snprintf(s->ticket, sizeof(s->ticket), "%s", tkt_string());
+
+ krb_set_tkt_string(s->ticket);
+
+ setuid(0); /* XXX fix for fix in tf_util.c */
+ if(krb_kuserok(toname, toinst, realm, name)){
+ SIA_DEBUG(("DEBUG", "%s.%s@%s is not allowed to login as %s",
+ toname, toinst, realm, name));
+ return SIADFAIL;
+ }
+#endif
+#ifdef SIA_KRB5
+ ret = krb5_verify_user_lrealm(s->context, principal, ccache,
+ entity->password, 1, NULL);
+ if(ret){
+ /* if this is most likely a local user (such as
+ root), just silently return failure when the
+ principal doesn't exist */
+ if(ret != KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN &&
+ ret != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN)
+ SIALOG("WARNING", "krb5_verify_user(%s): %s",
+ entity->name, error_message(ret));
+ return SIADFAIL;
+ }
+#endif
+#ifdef SIA_KRB4
+ if (getuid () == 0)
+ secure = KRB_VERIFY_SECURE;
+ else
+ secure = KRB_VERIFY_NOT_SECURE;
+
+ ret = krb_verify_user(toname, toinst, realm,
+ entity->password, secure, NULL);
+ if(ret){
+ SIA_DEBUG(("DEBUG", "krb_verify_user: %s", krb_get_err_text(ret)));
+ if(ret != KDC_PR_UNKNOWN)
+ /* since this is most likely a local user (such as
+ root), just silently return failure when the
+ principal doesn't exist */
+ SIALOG("WARNING", "krb_verify_user(%s.%s): %s",
+ toname, toinst, krb_get_err_text(ret));
+ return SIADFAIL;
+ }
+#endif
+ if(sia_make_entity_pwd(pwd, entity) == SIAFAIL)
+ return SIADFAIL;
+ s->valid = 1;
+ return SIADSUCCESS;
+}
+
+
+static int
+common_auth(sia_collect_func_t *collect,
+ SIAENTITY *entity,
+ int siastat,
+ int pkgind)
+{
+ prompt_t prompts[2], *pr;
+ char *name;
+
+ SIA_DEBUG(("DEBUG", "common_auth"));
+ if((siastat == SIADSUCCESS) && (geteuid() == 0))
+ return SIADSUCCESS;
+ if(entity == NULL) {
+ SIA_DEBUG(("DEBUG", "entity == NULL"));
+ return SIADFAIL | SIADSTOP;
+ }
+ name = entity->name;
+ if(entity->acctname)
+ name = entity->acctname;
+
+ if((collect != NULL) && entity->colinput) {
+ int num;
+ pr = prompts;
+ if(name == NULL){
+ if(setup_name(entity, pr) != SIADSUCCESS)
+ return SIADFAIL;
+ pr++;
+ }
+ if(entity->password == NULL){
+ if(setup_password(entity, pr) != SIADSUCCESS)
+ return SIADFAIL;
+ pr++;
+ }
+ num = pr - prompts;
+ if(num == 1){
+ if((*collect)(240, SIAONELINER, (unsigned char*)"", num,
+ prompts) != SIACOLSUCCESS){
+ SIA_DEBUG(("DEBUG", "collect failed"));
+ return SIADFAIL | SIADSTOP;
+ }
+ } else if(num > 0){
+ if((*collect)(0, SIAFORM, (unsigned char*)"", num,
+ prompts) != SIACOLSUCCESS){
+ SIA_DEBUG(("DEBUG", "collect failed"));
+ return SIADFAIL | SIADSTOP;
+ }
+ }
+ }
+ if(name == NULL)
+ name = entity->name;
+ if(name == NULL || name[0] == '\0'){
+ SIA_DEBUG(("DEBUG", "name is null"));
+ return SIADFAIL;
+ }
+
+ if(entity->password == NULL || strlen(entity->password) > SIAMXPASSWORD){
+ SIA_DEBUG(("DEBUG", "entity->password is null"));
+ return SIADFAIL;
+ }
+
+ return doauth(entity, pkgind, name);
+}
+
+
+int
+siad_ses_authent(sia_collect_func_t *collect,
+ SIAENTITY *entity,
+ int siastat,
+ int pkgind)
+{
+ SIA_DEBUG(("DEBUG", "siad_ses_authent"));
+ return common_auth(collect, entity, siastat, pkgind);
+}
+
+int
+siad_ses_estab(sia_collect_func_t *collect,
+ SIAENTITY *entity, int pkgind)
+{
+ SIA_DEBUG(("DEBUG", "siad_ses_estab"));
+ return SIADFAIL;
+}
+
+int
+siad_ses_launch(sia_collect_func_t *collect,
+ SIAENTITY *entity,
+ int pkgind)
+{
+ static char env[MaxPathLen];
+ struct state *s = (struct state*)entity->mech[pkgind];
+ SIA_DEBUG(("DEBUG", "siad_ses_launch"));
+ if(s->valid){
+#ifdef SIA_KRB5
+ chown(s->ticket + sizeof("FILE:") - 1,
+ entity->pwd->pw_uid,
+ entity->pwd->pw_gid);
+ snprintf(env, sizeof(env), "KRB5CCNAME=%s", s->ticket);
+#endif
+#ifdef SIA_KRB4
+ chown(s->ticket, entity->pwd->pw_uid, entity->pwd->pw_gid);
+ snprintf(env, sizeof(env), "KRBTKFILE=%s", s->ticket);
+#endif
+ putenv(env);
+ }
+#ifdef KRB4
+ if (k_hasafs()) {
+ char cell[64];
+ k_setpag();
+ if(k_afs_cell_of_file(entity->pwd->pw_dir, cell, sizeof(cell)) == 0)
+ krb_afslog(cell, 0);
+ krb_afslog_home(0, 0, entity->pwd->pw_dir);
+ }
+#endif
+ return SIADSUCCESS;
+}
+
+int
+siad_ses_release(SIAENTITY *entity, int pkgind)
+{
+ SIA_DEBUG(("DEBUG", "siad_ses_release"));
+ if(entity->mech[pkgind]){
+#ifdef SIA_KRB5
+ struct state *s = (struct state*)entity->mech[pkgind];
+ krb5_free_context(s->context);
+#endif
+ free(entity->mech[pkgind]);
+ }
+ return SIADSUCCESS;
+}
+
+int
+siad_ses_suauthent(sia_collect_func_t *collect,
+ SIAENTITY *entity,
+ int siastat,
+ int pkgind)
+{
+ SIA_DEBUG(("DEBUG", "siad_ses_suauth"));
+ if(geteuid() != 0)
+ return SIADFAIL;
+ if(entity->name == NULL)
+ return SIADFAIL;
+ if(entity->name[0] == '\0') {
+ free(entity->name);
+ entity->name = strdup("root");
+ if (entity->name == NULL)
+ return SIADFAIL;
+ }
+ return common_auth(collect, entity, siastat, pkgind);
+}
+
+int
+siad_ses_reauthent (sia_collect_func_t *collect,
+ SIAENTITY *entity,
+ int siastat,
+ int pkgind)
+{
+ int ret;
+ SIA_DEBUG(("DEBUG", "siad_ses_reauthent"));
+ if(entity == NULL || entity->name == NULL)
+ return SIADFAIL;
+ ret = common_auth(collect, entity, siastat, pkgind);
+ if((ret & SIADSUCCESS)){
+ /* launch isn't (always?) called when doing reauth, so we must
+ duplicate some code here... */
+ struct state *s = (struct state*)entity->mech[pkgind];
+ chown(s->ticket, entity->pwd->pw_uid, entity->pwd->pw_gid);
+#ifdef KRB4
+ if(k_hasafs()) {
+ char cell[64];
+ if(k_afs_cell_of_file(entity->pwd->pw_dir,
+ cell, sizeof(cell)) == 0)
+ krb_afslog(cell, 0);
+ krb_afslog_home(0, 0, entity->pwd->pw_dir);
+ }
+#endif
+ }
+ return ret;
+}
+
+int
+siad_chg_finger (sia_collect_func_t *collect,
+ const char *username,
+ int argc,
+ char *argv[])
+{
+ SIA_DEBUG(("DEBUG", "siad_chg_finger"));
+ return SIADFAIL;
+}
+
+#ifdef SIA_KRB5
+int
+siad_chg_password (sia_collect_func_t *collect,
+ const char *username,
+ int argc,
+ char *argv[])
+{
+ return SIADFAIL;
+}
+#endif
+
+#ifdef SIA_KRB4
+static void
+sia_message(sia_collect_func_t *collect, int rendition,
+ const char *title, const char *message)
+{
+ prompt_t prompt;
+ prompt.prompt = (unsigned char*)message;
+ (*collect)(0, rendition, (unsigned char*)title, 1, &prompt);
+}
+
+static int
+init_change(sia_collect_func_t *collect, krb_principal *princ)
+{
+ prompt_t prompt;
+ char old_pw[MAX_KPW_LEN+1];
+ char *msg;
+ char tktstring[128];
+ int ret;
+
+ SIA_DEBUG(("DEBUG", "init_change"));
+ prompt.prompt = (unsigned char*)"Old password: ";
+ prompt.result = (unsigned char*)old_pw;
+ prompt.min_result_length = 0;
+ prompt.max_result_length = sizeof(old_pw) - 1;
+ prompt.control_flags = SIARESINVIS;
+ asprintf(&msg, "Changing password for %s", krb_unparse_name(princ));
+ if(msg == NULL){
+ SIA_DEBUG(("DEBUG", "out of memory"));
+ return SIADFAIL;
+ }
+ ret = (*collect)(60, SIAONELINER, (unsigned char*)msg, 1, &prompt);
+ free(msg);
+ SIA_DEBUG(("DEBUG", "ret = %d", ret));
+ if(ret != SIACOLSUCCESS)
+ return SIADFAIL;
+ snprintf(tktstring, sizeof(tktstring),
+ "%s_cpw_%u", TKT_ROOT, (unsigned)getpid());
+ krb_set_tkt_string(tktstring);
+
+ ret = krb_get_pw_in_tkt(princ->name, princ->instance, princ->realm,
+ PWSERV_NAME, KADM_SINST, 1, old_pw);
+ if (ret != KSUCCESS) {
+ SIA_DEBUG(("DEBUG", "krb_get_pw_in_tkt: %s", krb_get_err_text(ret)));
+ if (ret == INTK_BADPW)
+ sia_message(collect, SIAWARNING, "", "Incorrect old password.");
+ else
+ sia_message(collect, SIAWARNING, "", "Kerberos error.");
+ memset(old_pw, 0, sizeof(old_pw));
+ return SIADFAIL;
+ }
+ if(chown(tktstring, getuid(), -1) < 0){
+ dest_tkt();
+ return SIADFAIL;
+ }
+ memset(old_pw, 0, sizeof(old_pw));
+ return SIADSUCCESS;
+}
+
+int
+siad_chg_password (sia_collect_func_t *collect,
+ const char *username,
+ int argc,
+ char *argv[])
+{
+ prompt_t prompts[2];
+ krb_principal princ;
+ int ret;
+ char new_pw1[MAX_KPW_LEN+1];
+ char new_pw2[MAX_KPW_LEN+1];
+ static struct et_list *et_list;
+
+ set_progname(argv[0]);
+
+ SIA_DEBUG(("DEBUG", "siad_chg_password"));
+ if(collect == NULL)
+ return SIADFAIL;
+
+ if(username == NULL)
+ username = getlogin();
+
+ ret = krb_parse_name(username, &princ);
+ if(ret)
+ return SIADFAIL;
+ if(princ.realm[0] == '\0')
+ krb_get_lrealm(princ.realm, 1);
+
+ if(et_list == NULL) {
+ initialize_kadm_error_table_r(&et_list);
+ initialize_krb_error_table_r(&et_list);
+ }
+
+ ret = init_change(collect, &princ);
+ if(ret != SIADSUCCESS)
+ return ret;
+
+again:
+ prompts[0].prompt = (unsigned char*)"New password: ";
+ prompts[0].result = (unsigned char*)new_pw1;
+ prompts[0].min_result_length = MIN_KPW_LEN;
+ prompts[0].max_result_length = sizeof(new_pw1) - 1;
+ prompts[0].control_flags = SIARESINVIS;
+ prompts[1].prompt = (unsigned char*)"Verify new password: ";
+ prompts[1].result = (unsigned char*)new_pw2;
+ prompts[1].min_result_length = MIN_KPW_LEN;
+ prompts[1].max_result_length = sizeof(new_pw2) - 1;
+ prompts[1].control_flags = SIARESINVIS;
+ if((*collect)(120, SIAFORM, (unsigned char*)"", 2, prompts) !=
+ SIACOLSUCCESS) {
+ dest_tkt();
+ return SIADFAIL;
+ }
+ if(strcmp(new_pw1, new_pw2) != 0){
+ sia_message(collect, SIAWARNING, "", "Password mismatch.");
+ goto again;
+ }
+ ret = kadm_check_pw(new_pw1);
+ if(ret) {
+ sia_message(collect, SIAWARNING, "", com_right(et_list, ret));
+ goto again;
+ }
+
+ memset(new_pw2, 0, sizeof(new_pw2));
+ ret = kadm_init_link (PWSERV_NAME, KRB_MASTER, princ.realm);
+ if (ret != KADM_SUCCESS)
+ sia_message(collect, SIAWARNING, "Error initing kadmin connection",
+ com_right(et_list, ret));
+ else {
+ des_cblock newkey;
+ char *pw_msg; /* message from server */
+
+ des_string_to_key(new_pw1, &newkey);
+ ret = kadm_change_pw_plain((unsigned char*)&newkey, new_pw1, &pw_msg);
+ memset(newkey, 0, sizeof(newkey));
+
+ if (ret == KADM_INSECURE_PW)
+ sia_message(collect, SIAWARNING, "Insecure password", pw_msg);
+ else if (ret != KADM_SUCCESS)
+ sia_message(collect, SIAWARNING, "Error changing password",
+ com_right(et_list, ret));
+ }
+ memset(new_pw1, 0, sizeof(new_pw1));
+
+ if (ret != KADM_SUCCESS)
+ sia_message(collect, SIAWARNING, "", "Password NOT changed.");
+ else
+ sia_message(collect, SIAINFO, "", "Password changed.");
+
+ dest_tkt();
+ if(ret)
+ return SIADFAIL;
+ return SIADSUCCESS;
+}
+#endif
+
+int
+siad_chg_shell (sia_collect_func_t *collect,
+ const char *username,
+ int argc,
+ char *argv[])
+{
+ return SIADFAIL;
+}
+
+int
+siad_getpwent(struct passwd *result,
+ char *buf,
+ int bufsize,
+ struct sia_context *context)
+{
+ return SIADFAIL;
+}
+
+int
+siad_getpwuid (uid_t uid,
+ struct passwd *result,
+ char *buf,
+ int bufsize,
+ struct sia_context *context)
+{
+ return SIADFAIL;
+}
+
+int
+siad_getpwnam (const char *name,
+ struct passwd *result,
+ char *buf,
+ int bufsize,
+ struct sia_context *context)
+{
+ return SIADFAIL;
+}
+
+int
+siad_setpwent (struct sia_context *context)
+{
+ return SIADFAIL;
+}
+
+int
+siad_endpwent (struct sia_context *context)
+{
+ return SIADFAIL;
+}
+
+int
+siad_getgrent(struct group *result,
+ char *buf,
+ int bufsize,
+ struct sia_context *context)
+{
+ return SIADFAIL;
+}
+
+int
+siad_getgrgid (gid_t gid,
+ struct group *result,
+ char *buf,
+ int bufsize,
+ struct sia_context *context)
+{
+ return SIADFAIL;
+}
+
+int
+siad_getgrnam (const char *name,
+ struct group *result,
+ char *buf,
+ int bufsize,
+ struct sia_context *context)
+{
+ return SIADFAIL;
+}
+
+int
+siad_setgrent (struct sia_context *context)
+{
+ return SIADFAIL;
+}
+
+int
+siad_endgrent (struct sia_context *context)
+{
+ return SIADFAIL;
+}
+
+int
+siad_chk_user (const char *logname, int checkflag)
+{
+ if(checkflag != CHGPASSWD)
+ return SIADFAIL;
+ return SIADSUCCESS;
+}
diff --git a/crypto/heimdal/lib/auth/sia/sia_locl.h b/crypto/heimdal/lib/auth/sia/sia_locl.h
new file mode 100644
index 000000000000..0f3f74d98d3b
--- /dev/null
+++ b/crypto/heimdal/lib/auth/sia/sia_locl.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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. */
+
+/* $Id: sia_locl.h,v 1.2 1999/04/01 16:09:22 joda Exp $ */
+
+#ifndef __sia_locl_h__
+#define __sia_locl_h__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <siad.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#ifdef KRB5
+#define SIA_KRB5
+#elif defined(KRB4)
+#define SIA_KRB4
+#endif
+
+#ifdef SIA_KRB5
+#include <krb5.h>
+#include <com_err.h>
+#endif
+#ifdef SIA_KRB4
+#include <krb.h>
+#include <krb_err.h>
+#include <kadm.h>
+#include <kadm_err.h>
+#endif
+#ifdef KRB4
+#include <kafs.h>
+#endif
+
+#include <roken.h>
+
+#ifndef POSIX_GETPWNAM_R
+
+#define getpwnam_r posix_getpwnam_r
+#define getpwuid_r posix_getpwuid_r
+
+#endif /* POSIX_GETPWNAM_R */
+
+#ifndef DEBUG
+#define SIA_DEBUG(X)
+#else
+#define SIA_DEBUG(X) SIALOG X
+#endif
+
+struct state{
+#ifdef SIA_KRB5
+ krb5_context context;
+ krb5_auth_context auth_context;
+#endif
+ char ticket[MaxPathLen];
+ int valid;
+};
+
+#endif /* __sia_locl_h__ */
diff --git a/crypto/heimdal/lib/des/rc4.h b/crypto/heimdal/lib/des/rc4.h
new file mode 100644
index 000000000000..15441f60198d
--- /dev/null
+++ b/crypto/heimdal/lib/des/rc4.h
@@ -0,0 +1,76 @@
+/* crypto/rc4/rc4.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* $Id: rc4.h,v 1.2 1999/10/21 12:58:31 joda Exp $ */
+
+#ifndef HEADER_RC4_H
+#define HEADER_RC4_H
+
+typedef unsigned int RC4_INT;
+
+typedef struct rc4_key_st {
+ RC4_INT x,y;
+ RC4_INT data[256];
+} RC4_KEY;
+
+
+void RC4_set_key(RC4_KEY *key, int len, unsigned char *data);
+void RC4(RC4_KEY *key, unsigned long len, unsigned char *indata,
+ unsigned char *outdata);
+
+#endif
diff --git a/crypto/heimdal/lib/des/rc4_enc.c b/crypto/heimdal/lib/des/rc4_enc.c
new file mode 100644
index 000000000000..6b1686f569b9
--- /dev/null
+++ b/crypto/heimdal/lib/des/rc4_enc.c
@@ -0,0 +1,133 @@
+/* crypto/rc4/rc4_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include "rc4.h"
+
+RCSID("$Id: rc4_enc.c,v 1.2 1999/10/21 12:58:43 joda Exp $");
+
+/* RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void RC4(RC4_KEY *key, unsigned long len, unsigned char *indata,
+ unsigned char *outdata)
+ {
+ register RC4_INT *d;
+ register RC4_INT x,y,tx,ty;
+ int i;
+
+ x=key->x;
+ y=key->y;
+ d=key->data;
+
+#define LOOP(in,out) \
+ x=((x+1)&0xff); \
+ tx=d[x]; \
+ y=(tx+y)&0xff; \
+ d[x]=ty=d[y]; \
+ d[y]=tx; \
+ (out) = d[(tx+ty)&0xff]^ (in);
+
+#ifndef RC4_INDEX
+#define RC4_LOOP(a,b,i) LOOP(*((a)++),*((b)++))
+#else
+#define RC4_LOOP(a,b,i) LOOP(a[i],b[i])
+#endif
+
+ i=(int)(len>>3L);
+ if (i)
+ {
+ for (;;)
+ {
+ RC4_LOOP(indata,outdata,0);
+ RC4_LOOP(indata,outdata,1);
+ RC4_LOOP(indata,outdata,2);
+ RC4_LOOP(indata,outdata,3);
+ RC4_LOOP(indata,outdata,4);
+ RC4_LOOP(indata,outdata,5);
+ RC4_LOOP(indata,outdata,6);
+ RC4_LOOP(indata,outdata,7);
+#ifdef RC4_INDEX
+ indata+=8;
+ outdata+=8;
+#endif
+ if (--i == 0) break;
+ }
+ }
+ i=(int)len&0x07;
+ if (i)
+ {
+ for (;;)
+ {
+ RC4_LOOP(indata,outdata,0); if (--i == 0) break;
+ RC4_LOOP(indata,outdata,1); if (--i == 0) break;
+ RC4_LOOP(indata,outdata,2); if (--i == 0) break;
+ RC4_LOOP(indata,outdata,3); if (--i == 0) break;
+ RC4_LOOP(indata,outdata,4); if (--i == 0) break;
+ RC4_LOOP(indata,outdata,5); if (--i == 0) break;
+ RC4_LOOP(indata,outdata,6); if (--i == 0) break;
+ }
+ }
+ key->x=x;
+ key->y=y;
+ }
diff --git a/crypto/heimdal/lib/des/rc4_skey.c b/crypto/heimdal/lib/des/rc4_skey.c
new file mode 100644
index 000000000000..f5bce4683f37
--- /dev/null
+++ b/crypto/heimdal/lib/des/rc4_skey.c
@@ -0,0 +1,101 @@
+/* crypto/rc4/rc4_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include "rc4.h"
+
+RCSID("$Id: rc4_skey.c,v 1.2 1999/10/21 12:58:52 joda Exp $");
+
+/* RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void RC4_set_key(RC4_KEY *key, int len, register unsigned char *data)
+ {
+ register RC4_INT tmp;
+ register int id1,id2;
+ register RC4_INT *d;
+ unsigned int i;
+
+ d= &(key->data[0]);
+ for (i=0; i<256; i++)
+ d[i]=i;
+ key->x = 0;
+ key->y = 0;
+ id1=id2=0;
+
+#define SK_LOOP(n) { \
+ tmp=d[(n)]; \
+ id2 = (data[id1] + tmp + id2) & 0xff; \
+ if (++id1 == len) id1=0; \
+ d[(n)]=d[id2]; \
+ d[id2]=tmp; }
+
+ for (i=0; i < 256; i+=4)
+ {
+ SK_LOOP(i+0);
+ SK_LOOP(i+1);
+ SK_LOOP(i+2);
+ SK_LOOP(i+3);
+ }
+ }
+
diff --git a/crypto/heimdal/lib/des/rc4test.c b/crypto/heimdal/lib/des/rc4test.c
new file mode 100644
index 000000000000..5abf8cff3073
--- /dev/null
+++ b/crypto/heimdal/lib/des/rc4test.c
@@ -0,0 +1,201 @@
+/* crypto/rc4/rc4test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef NO_RC4
+int main(int argc, char *argv[])
+{
+ printf("No RC4 support\n");
+ return(0);
+}
+#else
+#include <openssl/rc4.h>
+
+unsigned char keys[7][30]={
+ {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
+ {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
+ {8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {4,0xef,0x01,0x23,0x45},
+ {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
+ {4,0xef,0x01,0x23,0x45},
+ };
+
+unsigned char data_len[7]={8,8,8,20,28,10};
+unsigned char data[7][30]={
+ {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xff},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xff},
+ {0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
+ 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
+ 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
+ 0x12,0x34,0x56,0x78,0xff},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
+ {0},
+ };
+
+unsigned char output[7][30]={
+ {0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96,0x00},
+ {0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79,0x00},
+ {0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a,0x00},
+ {0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,
+ 0xbd,0x61,0x5a,0x11,0x62,0xe1,0xc7,0xba,
+ 0x36,0xb6,0x78,0x58,0x00},
+ {0x66,0xa0,0x94,0x9f,0x8a,0xf7,0xd6,0x89,
+ 0x1f,0x7f,0x83,0x2b,0xa8,0x33,0xc0,0x0c,
+ 0x89,0x2e,0xbe,0x30,0x14,0x3c,0xe2,0x87,
+ 0x40,0x01,0x1e,0xcf,0x00},
+ {0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61,0x00},
+ {0},
+ };
+
+int main(int argc, char *argv[])
+ {
+ int i,err=0;
+ int j;
+ unsigned char *p;
+ RC4_KEY key;
+ unsigned char buf[512],obuf[512];
+
+ for (i=0; i<512; i++) buf[i]=0x01;
+
+ for (i=0; i<6; i++)
+ {
+ RC4_set_key(&key,keys[i][0],&(keys[i][1]));
+ memset(obuf,0x00,sizeof(obuf));
+ RC4(&key,data_len[i],&(data[i][0]),obuf);
+ if (memcmp(obuf,output[i],data_len[i]+1) != 0)
+ {
+ printf("error calculating RC4\n");
+ printf("output:");
+ for (j=0; j<data_len[i]+1; j++)
+ printf(" %02x",obuf[j]);
+ printf("\n");
+ printf("expect:");
+ p= &(output[i][0]);
+ for (j=0; j<data_len[i]+1; j++)
+ printf(" %02x",*(p++));
+ printf("\n");
+ err++;
+ }
+ else
+ printf("test %d ok\n",i);
+ }
+ printf("test end processing ");
+ for (i=0; i<data_len[3]; i++)
+ {
+ RC4_set_key(&key,keys[3][0],&(keys[3][1]));
+ memset(obuf,0x00,sizeof(obuf));
+ RC4(&key,i,&(data[3][0]),obuf);
+ if ((memcmp(obuf,output[3],i) != 0) || (obuf[i] != 0))
+ {
+ printf("error in RC4 length processing\n");
+ printf("output:");
+ for (j=0; j<i+1; j++)
+ printf(" %02x",obuf[j]);
+ printf("\n");
+ printf("expect:");
+ p= &(output[3][0]);
+ for (j=0; j<i; j++)
+ printf(" %02x",*(p++));
+ printf(" 00\n");
+ err++;
+ }
+ else
+ {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+ printf("done\n");
+ printf("test multi-call ");
+ for (i=0; i<data_len[3]; i++)
+ {
+ RC4_set_key(&key,keys[3][0],&(keys[3][1]));
+ memset(obuf,0x00,sizeof(obuf));
+ RC4(&key,i,&(data[3][0]),obuf);
+ RC4(&key,data_len[3]-i,&(data[3][i]),&(obuf[i]));
+ if (memcmp(obuf,output[3],data_len[3]+1) != 0)
+ {
+ printf("error in RC4 multi-call processing\n");
+ printf("output:");
+ for (j=0; j<data_len[3]+1; j++)
+ printf(" %02x",obuf[j]);
+ printf("\n");
+ printf("expect:");
+ p= &(output[3][0]);
+ for (j=0; j<data_len[3]+1; j++)
+ printf(" %02x",*(p++));
+ err++;
+ }
+ else
+ {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+ printf("done\n");
+ exit(err);
+ return(0);
+ }
+#endif
diff --git a/crypto/heimdal/lib/gssapi/8003.c b/crypto/heimdal/lib/gssapi/8003.c
new file mode 100644
index 000000000000..61fe21561a86
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/8003.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: 8003.c,v 1.5 1999/12/02 17:05:03 joda Exp $");
+
+static krb5_error_code
+encode_om_uint32(OM_uint32 n, u_char *p)
+{
+ p[0] = (n >> 0) & 0xFF;
+ p[1] = (n >> 8) & 0xFF;
+ p[2] = (n >> 16) & 0xFF;
+ p[3] = (n >> 24) & 0xFF;
+ return 0;
+}
+
+static krb5_error_code
+decode_om_uint32(u_char *p, OM_uint32 *n)
+{
+ *n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+ return 0;
+}
+
+static krb5_error_code
+hash_input_chan_bindings (const gss_channel_bindings_t b,
+ u_char *p)
+{
+ u_char num[4];
+ struct md5 md5;
+
+ md5_init(&md5);
+ encode_om_uint32 (b->initiator_addrtype, num);
+ md5_update (&md5, num, sizeof(num));
+ encode_om_uint32 (b->initiator_address.length, num);
+ md5_update (&md5, num, sizeof(num));
+ if (b->initiator_address.length)
+ md5_update (&md5,
+ b->initiator_address.value,
+ b->initiator_address.length);
+ encode_om_uint32 (b->acceptor_addrtype, num);
+ md5_update (&md5, num, sizeof(num));
+ encode_om_uint32 (b->acceptor_address.length, num);
+ md5_update (&md5, num, sizeof(num));
+ if (b->acceptor_address.length)
+ md5_update (&md5,
+ b->acceptor_address.value,
+ b->acceptor_address.length);
+ encode_om_uint32 (b->application_data.length, num);
+ md5_update (&md5, num, sizeof(num));
+ if (b->application_data.length)
+ md5_update (&md5,
+ b->application_data.value,
+ b->application_data.length);
+ md5_finito (&md5, p);
+ return 0;
+}
+
+krb5_error_code
+gssapi_krb5_create_8003_checksum (
+ const gss_channel_bindings_t input_chan_bindings,
+ OM_uint32 flags,
+ Checksum *result)
+{
+ u_char *p;
+
+ result->cksumtype = 0x8003;
+ result->checksum.length = 24;
+ result->checksum.data = malloc (result->checksum.length);
+ if (result->checksum.data == NULL)
+ return ENOMEM;
+
+ p = result->checksum.data;
+ encode_om_uint32 (16, p);
+ p += 4;
+ if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS) {
+ memset (p, 0, 16);
+ } else {
+ hash_input_chan_bindings (input_chan_bindings, p);
+ }
+ p += 16;
+ encode_om_uint32 (flags, p);
+ p += 4;
+ if (p - (u_char *)result->checksum.data != result->checksum.length)
+ abort ();
+ return 0;
+}
+
+krb5_error_code
+gssapi_krb5_verify_8003_checksum(
+ const gss_channel_bindings_t input_chan_bindings,
+ Checksum *cksum,
+ OM_uint32 *flags)
+{
+ unsigned char hash[16];
+ unsigned char *p;
+ OM_uint32 length;
+
+ /* XXX should handle checksums > 24 bytes */
+ if(cksum->cksumtype != 0x8003 || cksum->checksum.length != 24)
+ return GSS_S_BAD_BINDINGS;
+
+ p = cksum->checksum.data;
+ decode_om_uint32(p, &length);
+ if(length != sizeof(hash))
+ return GSS_S_FAILURE;
+
+ p += 4;
+
+ if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
+ if(hash_input_chan_bindings(input_chan_bindings, hash) != 0)
+ return GSS_S_FAILURE;
+ if(memcmp(hash, p, sizeof(hash)) != 0)
+ return GSS_S_FAILURE;
+ }
+
+ p += sizeof(hash);
+
+ decode_om_uint32(p, flags);
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/ChangeLog b/crypto/heimdal/lib/gssapi/ChangeLog
new file mode 100644
index 000000000000..2524003f4c2c
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ChangeLog
@@ -0,0 +1,60 @@
+2000-01-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 0:4:0
+
+1999-12-26 Assar Westerlund <assar@sics.se>
+
+ * accept_sec_context.c (gss_accept_sec_context): always set
+ `output_token'
+ * init_sec_context.c (init_auth): always initialize `output_token'
+ * delete_sec_context.c (gss_delete_sec_context): always set
+ `output_token'
+
+1999-12-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 0:3:0
+
+1999-10-20 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 0:2:0
+
+1999-09-21 Assar Westerlund <assar@sics.se>
+
+ * init_sec_context.c (gss_init_sec_context): initialize `ticket'
+
+ * gssapi.h (gss_ctx_id_t_desc): add ticket in here. ick.
+
+ * delete_sec_context.c (gss_delete_sec_context): free ticket
+
+ * accept_sec_context.c (gss_accept_sec_context): stove away
+ `krb5_ticket' in context so that ugly programs such as
+ gss_nt_server can get at it. uck.
+
+1999-09-20 Johan Danielsson <joda@pdc.kth.se>
+
+ * accept_sec_context.c: set minor_status
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * display_status.c (calling_error, routine_error): right shift the
+ code to make it possible to index into the arrays
+
+1999-07-28 Assar Westerlund <assar@sics.se>
+
+ * gssapi.h (GSS_C_AF_INET6): add
+
+ * import_name.c (import_hostbased_name): set minor_status
+
+1999-07-26 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 0:1:0
+
+Wed Apr 7 14:05:15 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * display_status.c: set minor_status
+
+ * init_sec_context.c: set minor_status
+
+ * lib/gssapi/init.c: remove donep (check gssapi_krb5_context
+ directly)
+
diff --git a/crypto/heimdal/lib/gssapi/Makefile.am b/crypto/heimdal/lib/gssapi/Makefile.am
new file mode 100644
index 000000000000..ff4ef63b4466
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/Makefile.am
@@ -0,0 +1,46 @@
+# $Id: Makefile.am,v 1.17 2000/01/06 21:47:40 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += -I$(srcdir)/../krb5
+
+lib_LTLIBRARIES = libgssapi.la
+libgssapi_la_LDFLAGS = -version-info 0:4:0
+
+include_HEADERS = gssapi.h
+
+libgssapi_la_SOURCES = \
+ 8003.c \
+ accept_sec_context.c \
+ acquire_cred.c \
+ add_oid_set_member.c \
+ canonicalize_name.c \
+ compare_name.c \
+ context_time.c \
+ create_emtpy_oid_set.c \
+ decapsulate.c \
+ delete_sec_context.c \
+ display_name.c \
+ display_status.c \
+ duplicate_name.c \
+ encapsulate.c \
+ export_name.c \
+ external.c \
+ get_mic.c \
+ gssapi.h \
+ gssapi_locl.h \
+ import_name.c \
+ indicate_mechs.c \
+ init.c \
+ init_sec_context.c \
+ inquire_context.c \
+ inquire_cred.c \
+ release_buffer.c \
+ release_cred.c \
+ release_name.c \
+ release_oid_set.c \
+ test_oid_set_member.c \
+ unwrap.c \
+ v1.c \
+ verify_mic.c \
+ wrap.c
diff --git a/crypto/heimdal/lib/gssapi/Makefile.in b/crypto/heimdal/lib/gssapi/Makefile.in
new file mode 100644
index 000000000000..4e658c19d355
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/Makefile.in
@@ -0,0 +1,654 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.17 2000/01/06 21:47:40 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include -I$(srcdir)/../krb5
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+lib_LTLIBRARIES = libgssapi.la
+libgssapi_la_LDFLAGS = -version-info 0:4:0
+
+include_HEADERS = gssapi.h
+
+libgssapi_la_SOURCES = 8003.c accept_sec_context.c acquire_cred.c add_oid_set_member.c canonicalize_name.c compare_name.c context_time.c create_emtpy_oid_set.c decapsulate.c delete_sec_context.c display_name.c display_status.c duplicate_name.c encapsulate.c export_name.c external.c get_mic.c gssapi.h gssapi_locl.h import_name.c indicate_mechs.c init.c init_sec_context.c inquire_context.c inquire_cred.c release_buffer.c release_cred.c release_name.c release_oid_set.c test_oid_set_member.c unwrap.c v1.c verify_mic.c wrap.c
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libgssapi_la_LIBADD =
+libgssapi_la_OBJECTS = 8003.lo accept_sec_context.lo acquire_cred.lo \
+add_oid_set_member.lo canonicalize_name.lo compare_name.lo \
+context_time.lo create_emtpy_oid_set.lo decapsulate.lo \
+delete_sec_context.lo display_name.lo display_status.lo \
+duplicate_name.lo encapsulate.lo export_name.lo external.lo get_mic.lo \
+import_name.lo indicate_mechs.lo init.lo init_sec_context.lo \
+inquire_context.lo inquire_cred.lo release_buffer.lo release_cred.lo \
+release_name.lo release_oid_set.lo test_oid_set_member.lo unwrap.lo \
+v1.lo verify_mic.lo wrap.lo
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(include_HEADERS)
+
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libgssapi_la_SOURCES)
+OBJECTS = $(libgssapi_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/gssapi/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libgssapi.la: $(libgssapi_la_OBJECTS) $(libgssapi_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libgssapi_la_LDFLAGS) $(libgssapi_la_OBJECTS) $(libgssapi_la_LIBADD) $(LIBS)
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/gssapi
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-includeHEADERS install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool uninstall-includeHEADERS \
+install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-local install-data-am install-data install-am install \
+uninstall-am uninstall all-local all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/gssapi/accept_sec_context.c b/crypto/heimdal/lib/gssapi/accept_sec_context.c
new file mode 100644
index 000000000000..4d9a2b07aa25
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/accept_sec_context.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: accept_sec_context.c,v 1.15 1999/12/26 18:32:08 assar Exp $");
+
+static krb5_keytab gss_keytab;
+
+OM_uint32
+gsskrb5_register_acceptor_identity (char *identity)
+{
+ char *p;
+ if(gss_keytab != NULL) {
+ krb5_kt_close(gssapi_krb5_context, gss_keytab);
+ gss_keytab = NULL;
+ }
+ asprintf(&p, "FILE:%s", identity);
+ if(p == NULL)
+ return GSS_S_FAILURE;
+ krb5_kt_resolve(gssapi_krb5_context, p, &gss_keytab);
+ free(p);
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 gss_accept_sec_context
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t * delegated_cred_handle
+ )
+{
+ krb5_error_code kret;
+ OM_uint32 ret;
+ krb5_data indata;
+ krb5_flags ap_options;
+ OM_uint32 flags;
+ krb5_ticket *ticket = NULL;
+ krb5_keytab keytab = NULL;
+
+ gssapi_krb5_init ();
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ *context_handle = malloc(sizeof(**context_handle));
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ (*context_handle)->auth_context = NULL;
+ (*context_handle)->source = NULL;
+ (*context_handle)->target = NULL;
+ (*context_handle)->flags = 0;
+ (*context_handle)->more_flags = 0;
+ (*context_handle)->ticket = NULL;
+
+ kret = krb5_auth_con_init (gssapi_krb5_context,
+ &(*context_handle)->auth_context);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ {
+ int32_t tmp;
+
+ krb5_auth_con_getflags(gssapi_krb5_context,
+ (*context_handle)->auth_context,
+ &tmp);
+ tmp |= KRB5_AUTH_CONTEXT_DO_SEQUENCE;
+ krb5_auth_con_setflags(gssapi_krb5_context,
+ (*context_handle)->auth_context,
+ tmp);
+ }
+
+ ret = gssapi_krb5_decapsulate (input_token_buffer,
+ &indata,
+ "\x01\x00");
+ if (ret) {
+ kret = 0;
+ goto failure;
+ }
+
+ if (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) {
+ if (gss_keytab != NULL) {
+ keytab = gss_keytab;
+ }
+ } else if (acceptor_cred_handle->keytab != NULL) {
+ keytab = acceptor_cred_handle->keytab;
+ }
+
+ kret = krb5_rd_req (gssapi_krb5_context,
+ &(*context_handle)->auth_context,
+ &indata,
+ (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) ? NULL
+ : acceptor_cred_handle->principal,
+ keytab,
+ &ap_options,
+ &ticket);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ kret = krb5_copy_principal (gssapi_krb5_context,
+ ticket->client,
+ &(*context_handle)->source);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (src_name) {
+ kret = krb5_copy_principal (gssapi_krb5_context,
+ ticket->client,
+ src_name);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+ }
+
+ {
+ krb5_authenticator authenticator;
+
+ kret = krb5_auth_getauthenticator(gssapi_krb5_context,
+ (*context_handle)->auth_context,
+ &authenticator);
+ if(kret) {
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ kret = gssapi_krb5_verify_8003_checksum(input_chan_bindings,
+ authenticator->cksum,
+ &flags);
+ krb5_free_authenticator(gssapi_krb5_context, &authenticator);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+ }
+
+ if (ret_flags)
+ *ret_flags = flags;
+ (*context_handle)->flags = flags;
+ (*context_handle)->more_flags |= OPEN;
+
+ if (mech_type)
+ *mech_type = GSS_KRB5_MECHANISM;
+
+ if (time_rec)
+ *time_rec = GSS_C_INDEFINITE;
+
+ if(flags & GSS_C_MUTUAL_FLAG) {
+ krb5_data outbuf;
+
+ kret = krb5_mk_rep (gssapi_krb5_context,
+ &(*context_handle)->auth_context,
+ &outbuf);
+ if (kret) {
+ krb5_data_free (&outbuf);
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+ ret = gssapi_krb5_encapsulate (&outbuf,
+ output_token,
+ "\x02\x00");
+ if (ret) {
+ kret = 0;
+ goto failure;
+ }
+ } else {
+ output_token->length = 0;
+ }
+
+ (*context_handle)->ticket = ticket;
+ ticket = NULL;
+
+#if 0
+ krb5_free_ticket (context, ticket);
+#endif
+
+ return GSS_S_COMPLETE;
+
+failure:
+ if (ticket != NULL)
+ krb5_free_ticket (gssapi_krb5_context, ticket);
+ krb5_auth_con_free (gssapi_krb5_context,
+ (*context_handle)->auth_context);
+ if((*context_handle)->source)
+ krb5_free_principal (gssapi_krb5_context,
+ (*context_handle)->source);
+ if((*context_handle)->target)
+ krb5_free_principal (gssapi_krb5_context,
+ (*context_handle)->target);
+ free (*context_handle);
+ *context_handle = GSS_C_NO_CONTEXT;
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+}
diff --git a/crypto/heimdal/lib/gssapi/acquire_cred.c b/crypto/heimdal/lib/gssapi/acquire_cred.c
new file mode 100644
index 000000000000..821bbc3e71ec
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/acquire_cred.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: acquire_cred.c,v 1.3 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32 gss_acquire_cred
+ (OM_uint32 * minor_status,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ const gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t * output_cred_handle,
+ gss_OID_set * actual_mechs,
+ OM_uint32 * time_rec
+ )
+{
+ gss_cred_id_t handle;
+ OM_uint32 ret;
+
+ handle = (gss_cred_id_t)malloc(sizeof(*handle));
+ if (handle == GSS_C_NO_CREDENTIAL) {
+ return GSS_S_FAILURE;
+ }
+
+ ret = gss_duplicate_name(minor_status, desired_name, &handle->principal);
+ if (ret) {
+ return ret;
+ }
+
+ /* XXX */
+ handle->lifetime = time_req;
+
+ handle->keytab = NULL;
+ handle->usage = cred_usage;
+
+ ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ if (ret) {
+ return ret;
+ }
+ ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
+ if (ret) {
+ return ret;
+ }
+
+ ret = gss_inquire_cred(minor_status, handle, NULL, time_rec, NULL,
+ actual_mechs);
+ if (ret) {
+ return ret;
+ }
+
+ *output_cred_handle = handle;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/add_oid_set_member.c b/crypto/heimdal/lib/gssapi/add_oid_set_member.c
new file mode 100644
index 000000000000..996c5cfeb8c6
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/add_oid_set_member.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: add_oid_set_member.c,v 1.3 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32 gss_add_oid_set_member (
+ OM_uint32 * minor_status,
+ const gss_OID member_oid,
+ gss_OID_set * oid_set
+ )
+{
+ size_t n = (*oid_set)->count;
+
+ (*oid_set)->elements = realloc ((*oid_set)->elements,
+ n * sizeof(gss_OID_desc));
+ if ((*oid_set)->elements == NULL) {
+ return GSS_S_FAILURE;
+ }
+ (*oid_set)->count = n;
+ (*oid_set)->elements[n-1] = *member_oid;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/canonicalize_name.c b/crypto/heimdal/lib/gssapi/canonicalize_name.c
new file mode 100644
index 000000000000..afa39f3a4f96
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/canonicalize_name.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: canonicalize_name.c,v 1.2 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32 gss_canonicalize_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ const gss_OID mech_type,
+ gss_name_t * output_name
+ )
+{
+ return gss_duplicate_name (minor_status, input_name, output_name);
+}
diff --git a/crypto/heimdal/lib/gssapi/compare_name.c b/crypto/heimdal/lib/gssapi/compare_name.c
new file mode 100644
index 000000000000..5926b158b73a
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/compare_name.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: compare_name.c,v 1.2 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32 gss_compare_name
+ (OM_uint32 * minor_status,
+ const gss_name_t name1,
+ const gss_name_t name2,
+ int * name_equal
+ )
+{
+ gssapi_krb5_init ();
+ *name_equal = krb5_principal_compare (gssapi_krb5_context,
+ name1, name2);
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/context_time.c b/crypto/heimdal/lib/gssapi/context_time.c
new file mode 100644
index 000000000000..2a04ce8cc20c
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/context_time.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: context_time.c,v 1.2 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32 gss_context_time
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ OM_uint32 * time_rec
+ )
+{
+ OM_uint32 lifetime;
+ OM_uint32 ret;
+ krb5_error_code kret;
+ int32_t timeret;
+
+ gssapi_krb5_init();
+
+ ret = gss_inquire_context(minor_status, context_handle,
+ NULL, NULL, &lifetime, NULL, NULL, NULL, NULL);
+ if (ret) {
+ return ret;
+ }
+
+ kret = krb5_timeofday(gssapi_krb5_context, &timeret);
+ if (kret) {
+ return GSS_S_FAILURE;
+ }
+
+ *time_rec = lifetime - timeret;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/create_emtpy_oid_set.c b/crypto/heimdal/lib/gssapi/create_emtpy_oid_set.c
new file mode 100644
index 000000000000..acec30e8a00a
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/create_emtpy_oid_set.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: create_emtpy_oid_set.c,v 1.3 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32 gss_create_empty_oid_set (
+ OM_uint32 * minor_status,
+ gss_OID_set * oid_set
+ )
+{
+ *oid_set = malloc(sizeof(**oid_set));
+ if (*oid_set == NULL) {
+ return GSS_S_FAILURE;
+ }
+ (*oid_set)->count = 0;
+ (*oid_set)->elements = NULL;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/decapsulate.c b/crypto/heimdal/lib/gssapi/decapsulate.c
new file mode 100644
index 000000000000..e3603c7e0d62
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/decapsulate.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: decapsulate.c,v 1.5 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32
+gssapi_krb5_verify_header(u_char **str,
+ size_t total_len,
+ char *type)
+{
+ size_t len, len_len, mech_len, foo;
+ int e;
+ u_char *p = *str;
+
+ if (*p++ != 0x60)
+ return GSS_S_DEFECTIVE_TOKEN;
+ e = der_get_length (p, total_len - 1, &len, &len_len);
+ if (e || 1 + len_len + len != total_len)
+ abort ();
+ p += len_len;
+ if (*p++ != 0x06)
+ return GSS_S_DEFECTIVE_TOKEN;
+ e = der_get_length (p, total_len - 1 - len_len - 1,
+ &mech_len, &foo);
+ if (e)
+ abort ();
+ p += foo;
+ if (mech_len != GSS_KRB5_MECHANISM->length)
+ return GSS_S_BAD_MECH;
+ if (memcmp(p,
+ GSS_KRB5_MECHANISM->elements,
+ GSS_KRB5_MECHANISM->length) != 0)
+ return GSS_S_BAD_MECH;
+ p += mech_len;
+ if (memcmp (p, type, 2) != 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ p += 2;
+ *str = p;
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * Remove the GSS-API wrapping from `in_token' giving `out_data.
+ * Does not copy data, so just free `in_token'.
+ */
+
+OM_uint32
+gssapi_krb5_decapsulate(
+ gss_buffer_t input_token_buffer,
+ krb5_data *out_data,
+ char *type
+)
+{
+ u_char *p;
+ OM_uint32 ret;
+
+ p = input_token_buffer->value;
+ ret = gssapi_krb5_verify_header(&p,
+ input_token_buffer->length,
+ type);
+ if (ret)
+ return ret;
+
+ out_data->length = input_token_buffer->length -
+ (p - (u_char *)input_token_buffer->value);
+ out_data->data = p;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/delete_sec_context.c b/crypto/heimdal/lib/gssapi/delete_sec_context.c
new file mode 100644
index 000000000000..514206cf2ddb
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/delete_sec_context.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: delete_sec_context.c,v 1.5 1999/12/26 18:31:06 assar Exp $");
+
+OM_uint32 gss_delete_sec_context
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t output_token
+ )
+{
+ gssapi_krb5_init ();
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ krb5_auth_con_free (gssapi_krb5_context,
+ (*context_handle)->auth_context);
+ if((*context_handle)->source)
+ krb5_free_principal (gssapi_krb5_context,
+ (*context_handle)->source);
+ if((*context_handle)->target)
+ krb5_free_principal (gssapi_krb5_context,
+ (*context_handle)->target);
+ if ((*context_handle)->ticket)
+ krb5_free_ticket (gssapi_krb5_context,
+ (*context_handle)->ticket);
+ free (*context_handle);
+ if (output_token)
+ output_token->length = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/display_name.c b/crypto/heimdal/lib/gssapi/display_name.c
new file mode 100644
index 000000000000..4efed142f06d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/display_name.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: display_name.c,v 1.5 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32 gss_display_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t output_name_buffer,
+ gss_OID * output_name_type
+ )
+{
+ krb5_error_code kret;
+ char *buf;
+ size_t len;
+
+ gssapi_krb5_init ();
+ kret = krb5_unparse_name (gssapi_krb5_context,
+ input_name,
+ &buf);
+ if (kret)
+ return GSS_S_FAILURE;
+ len = strlen (buf);
+ output_name_buffer->length = len;
+ output_name_buffer->value = malloc(len + 1);
+ if (output_name_buffer->value == NULL) {
+ free (buf);
+ return GSS_S_FAILURE;
+ }
+ memcpy (output_name_buffer->value, buf, len);
+ ((char *)output_name_buffer->value)[len] = '\0';
+ free (buf);
+ if (output_name_type)
+ *output_name_type = GSS_KRB5_NT_PRINCIPAL_NAME;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/display_status.c b/crypto/heimdal/lib/gssapi/display_status.c
new file mode 100644
index 000000000000..f08c47e2a5ce
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/display_status.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: display_status.c,v 1.5 1999/12/02 17:05:03 joda Exp $");
+
+static char *
+calling_error(OM_uint32 v)
+{
+ static char *msgs[] = {
+ NULL, /* 0 */
+ "A required input parameter could not be read.", /* */
+ "A required output parameter could not be written.", /* */
+ "A parameter was malformed"
+ };
+
+ v >>= GSS_C_CALLING_ERROR_OFFSET;
+
+ if (v == 0)
+ return "";
+ else if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown calling error";
+ else
+ return msgs[v];
+}
+
+static char *
+routine_error(OM_uint32 v)
+{
+ static char *msgs[] = {
+ NULL, /* 0 */
+ "An unsupported mechanism was requested",
+ "An invalid name was supplied",
+ "A supplied name was of an unsupported type",
+ "Incorrect channel bindings were supplied",
+ "An invalid status code was supplied",
+ "A token had an invalid MIC",
+ "No credentials were supplied, "
+ "or the credentials were unavailable or inaccessible.",
+ "No context has been established",
+ "A token was invalid",
+ "A credential was invalid",
+ "The referenced credentials have expired",
+ "The context has expired",
+ "Miscellaneous failure (see text)",
+ "The quality-of-protection requested could not be provide",
+ "The operation is forbidden by local security policy",
+ "The operation or option is not available",
+ "The requested credential element already exists",
+ "The provided name was not a mechanism name.",
+ };
+
+ v >>= GSS_C_ROUTINE_ERROR_OFFSET;
+
+ if (v == 0)
+ return "";
+ else if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown routine error";
+ else
+ return msgs[v];
+}
+
+OM_uint32 gss_display_status
+ (OM_uint32 *minor_status,
+ OM_uint32 status_value,
+ int status_type,
+ const gss_OID mech_type,
+ OM_uint32 *message_context,
+ gss_buffer_t status_string)
+{
+ char *buf;
+
+ gssapi_krb5_init ();
+
+ *minor_status = 0;
+
+ if (mech_type != GSS_C_NO_OID &&
+ mech_type != GSS_KRB5_MECHANISM)
+ return GSS_S_BAD_MECH;
+
+ if (status_type == GSS_C_GSS_CODE) {
+ asprintf (&buf, "%s %s",
+ calling_error(GSS_CALLING_ERROR(status_value)),
+ routine_error(GSS_ROUTINE_ERROR(status_value)));
+ if (buf == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ } else if (status_type == GSS_C_MECH_CODE) {
+ buf = strdup(krb5_get_err_text (gssapi_krb5_context, status_value));
+ if (buf == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ } else
+ return GSS_S_BAD_STATUS;
+
+ *message_context = 0;
+
+ status_string->length = strlen(buf);
+ status_string->value = buf;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/duplicate_name.c b/crypto/heimdal/lib/gssapi/duplicate_name.c
new file mode 100644
index 000000000000..a3118d3566fe
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/duplicate_name.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: duplicate_name.c,v 1.3 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32 gss_duplicate_name (
+ OM_uint32 * minor_status,
+ const gss_name_t src_name,
+ gss_name_t * dest_name
+ )
+{
+ krb5_error_code kret;
+
+ gssapi_krb5_init ();
+
+ kret = krb5_copy_principal (gssapi_krb5_context,
+ src_name,
+ dest_name);
+ if (kret)
+ return GSS_S_FAILURE;
+ else
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/encapsulate.c b/crypto/heimdal/lib/gssapi/encapsulate.c
new file mode 100644
index 000000000000..1b8636bc5a4d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/encapsulate.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: encapsulate.c,v 1.4 1999/12/02 17:05:03 joda Exp $");
+
+void
+gssapi_krb5_encap_length (size_t data_len,
+ size_t *len,
+ size_t *total_len)
+{
+ size_t len_len;
+
+ *len = 1 + 1 + GSS_KRB5_MECHANISM->length + 2 + data_len;
+
+ len_len = length_len(*len);
+
+ *total_len = 1 + len_len + *len;
+}
+
+u_char *
+gssapi_krb5_make_header (u_char *p,
+ size_t len,
+ u_char *type)
+{
+ int e;
+ size_t len_len, foo;
+
+ *p++ = 0x60;
+ len_len = length_len(len);
+ e = der_put_length (p + len_len - 1, len_len, len, &foo);
+ if(e || foo != len_len)
+ abort ();
+ p += len_len;
+ *p++ = 0x06;
+ *p++ = GSS_KRB5_MECHANISM->length;
+ memcpy (p, GSS_KRB5_MECHANISM->elements, GSS_KRB5_MECHANISM->length);
+ p += GSS_KRB5_MECHANISM->length;
+ memcpy (p, type, 2);
+ p += 2;
+ return p;
+}
+
+/*
+ * Give it a krb5_data and it will encapsulate with extra GSS-API wrappings.
+ */
+
+OM_uint32
+gssapi_krb5_encapsulate(
+ krb5_data *in_data,
+ gss_buffer_t output_token,
+ u_char *type
+)
+{
+ size_t len, outer_len;
+ u_char *p;
+
+ gssapi_krb5_encap_length (in_data->length, &len, &outer_len);
+
+ output_token->length = outer_len;
+ output_token->value = malloc (outer_len);
+ if (output_token->value == NULL)
+ return GSS_S_FAILURE;
+
+ p = gssapi_krb5_make_header (output_token->value, len, type);
+ memcpy (p, in_data->data, in_data->length);
+ krb5_data_free (in_data);
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/export_name.c b/crypto/heimdal/lib/gssapi/export_name.c
new file mode 100644
index 000000000000..efbd9c4eaf91
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/export_name.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: export_name.c,v 1.4 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32 gss_export_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t exported_name
+ )
+{
+ return gss_display_name(minor_status,
+ input_name,
+ exported_name,
+ NULL);
+}
diff --git a/crypto/heimdal/lib/gssapi/external.c b/crypto/heimdal/lib/gssapi/external.c
new file mode 100644
index 000000000000..19e830689eb1
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/external.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: external.c,v 1.4 1999/12/02 17:05:03 joda Exp $");
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+static gss_OID_desc gss_c_nt_user_name_oid_desc =
+{10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ "\x01\x02\x01\x01"};
+
+gss_OID GSS_C_NT_USER_NAME = &gss_c_nt_user_name_oid_desc;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+static gss_OID_desc gss_c_nt_machine_uid_name_oid_desc =
+{10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ "\x01\x02\x01\x02"};
+
+gss_OID GSS_C_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+static gss_OID_desc gss_c_nt_string_uid_name_oid_desc =
+{10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ "\x01\x02\x01\x03"};
+
+gss_OID GSS_C_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 2(gss-host-based-services)}. The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+static gss_OID_desc gss_c_nt_hostbased_service_oid_desc =
+{6, (void *)"\x2b\x06\x01\x05\x06\x02"};
+
+gss_OID GSS_C_NT_HOSTBASED_SERVICE = &gss_c_nt_hostbased_service_oid_desc;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+static gss_OID_desc gss_c_nt_anonymous_oid_desc =
+{6, (void *)"\x2b\x06\01\x05\x06\x03"};
+
+gss_OID GSS_C_NT_ANONYMOUS = &gss_c_nt_anonymous_oid_desc;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+static gss_OID_desc gss_c_nt_export_name_oid_desc =
+{6, (void *)"\x2b\x06\x01\x05\x06\x04"};
+
+gss_OID GSS_C_NT_EXPORT_NAME = &gss_c_nt_export_name_oid_desc;
+
+/*
+ * This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * krb5(2) krb5_name(1)}. The recommended symbolic name for this type
+ * is "GSS_KRB5_NT_PRINCIPAL_NAME".
+ */
+
+static gss_OID_desc gss_krb5_nt_principal_name_oid_desc =
+{10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01"};
+
+gss_OID GSS_KRB5_NT_PRINCIPAL_NAME = &gss_krb5_nt_principal_name_oid_desc;
+
+/*
+ * This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) user_name(1)}. The recommended symbolic name for this
+ * type is "GSS_KRB5_NT_USER_NAME".
+ */
+
+gss_OID GSS_KRB5_NT_USER_NAME = &gss_c_nt_user_name_oid_desc;
+
+/*
+ * This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) machine_uid_name(2)}. The recommended symbolic name for
+ * this type is "GSS_KRB5_NT_MACHINE_UID_NAME".
+ */
+
+gss_OID GSS_KRB5_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc;
+
+/*
+ * This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) string_uid_name(3)}. The recommended symbolic name for
+ * this type is "GSS_KRB5_NT_STRING_UID_NAME".
+ */
+
+gss_OID GSS_KRB5_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc;
+
+/*
+ * To support ongoing experimentation, testing, and evolution of the
+ * specification, the Kerberos V5 GSS-API mechanism as defined in this
+ * and any successor memos will be identified with the following Object
+ * Identifier, as defined in RFC-1510, until the specification is
+ * advanced to the level of Proposed Standard RFC:
+ *
+ * {iso(1), org(3), dod(5), internet(1), security(5), kerberosv5(2)}
+ *
+ * Upon advancement to the level of Proposed Standard RFC, the Kerberos
+ * V5 GSS-API mechanism will be identified by an Object Identifier
+ * having the value:
+ *
+ * {iso(1) member-body(2) United States(840) mit(113554) infosys(1)
+ * gssapi(2) krb5(2)}
+ */
+
+#if 0 /* This is the old OID */
+
+static gss_OID_desc gss_krb5_mechanism_oid_desc =
+{5, (void *)"\x2b\x05\x01\x05\x02"};
+
+#endif
+
+static gss_OID_desc gss_krb5_mechanism_oid_desc =
+{9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"};
+
+gss_OID GSS_KRB5_MECHANISM = &gss_krb5_mechanism_oid_desc;
+
+/*
+ * Context for krb5 calls.
+ */
+
+krb5_context gssapi_krb5_context;
diff --git a/crypto/heimdal/lib/gssapi/get_mic.c b/crypto/heimdal/lib/gssapi/get_mic.c
new file mode 100644
index 000000000000..2b779c798e49
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/get_mic.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: get_mic.c,v 1.9 1999/12/02 17:05:03 joda Exp $");
+
+OM_uint32 gss_get_mic
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token
+ )
+{
+ u_char *p;
+ struct md5 md5;
+ u_char hash[16];
+ des_key_schedule schedule;
+ des_cblock key;
+ des_cblock zero;
+ int32_t seq_number;
+ size_t len, total_len;
+
+ gssapi_krb5_encap_length (22, &len, &total_len);
+
+ message_token->length = total_len;
+ message_token->value = malloc (total_len);
+ if (message_token->value == NULL)
+ return GSS_S_FAILURE;
+
+ p = gssapi_krb5_make_header(message_token->value,
+ len,
+ "\x01\x01");
+
+ memcpy (p, "\x00\x00", 2);
+ p += 2;
+ memcpy (p, "\xff\xff\xff\xff", 4);
+ p += 4;
+
+ /* Fill in later */
+ memset (p, 0, 16);
+ p += 16;
+
+ /* checksum */
+ md5_init (&md5);
+ md5_update (&md5, p - 24, 8);
+ md5_update (&md5, message_buffer->value,
+ message_buffer->length);
+ md5_finito (&md5, hash);
+
+ memset (&zero, 0, sizeof(zero));
+ gss_krb5_getsomekey(context_handle, &key);
+ des_set_key (&key, schedule);
+ des_cbc_cksum ((des_cblock *)hash,
+ (des_cblock *)hash, sizeof(hash), schedule, &zero);
+ memcpy (p - 8, hash, 8);
+
+ /* sequence number */
+ krb5_auth_getlocalseqnumber (gssapi_krb5_context,
+ context_handle->auth_context,
+ &seq_number);
+
+ p -= 16;
+ p[0] = (seq_number >> 0) & 0xFF;
+ p[1] = (seq_number >> 8) & 0xFF;
+ p[2] = (seq_number >> 16) & 0xFF;
+ p[3] = (seq_number >> 24) & 0xFF;
+ memset (p + 4,
+ (context_handle->more_flags & LOCAL) ? 0 : 0xFF,
+ 4);
+
+ des_set_key (&key, schedule);
+ des_cbc_encrypt ((des_cblock *)p, (des_cblock *)p, 8,
+ schedule, (des_cblock *)(p + 8), DES_ENCRYPT);
+
+ krb5_auth_setlocalseqnumber (gssapi_krb5_context,
+ context_handle->auth_context,
+ ++seq_number);
+
+ memset (key, 0, sizeof(key));
+ memset (schedule, 0, sizeof(schedule));
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/gssapi.h b/crypto/heimdal/lib/gssapi/gssapi.h
new file mode 100644
index 000000000000..4c1b606bec41
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gssapi.h
@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: gssapi.h,v 1.14 1999/12/02 17:05:03 joda Exp $ */
+
+#ifndef GSSAPI_H_
+#define GSSAPI_H_
+
+/*
+ * First, include stddef.h to get size_t defined.
+ */
+#include <stddef.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#include <krb5-types.h>
+
+/*
+ * Now define the three implementation-dependent types.
+ */
+
+typedef u_int32_t OM_uint32;
+
+/*
+ * This is to avoid having to include <krb5.h>
+ */
+
+struct krb5_auth_context_data;
+
+struct Principal;
+
+/* typedef void *gss_name_t; */
+
+typedef struct Principal *gss_name_t;
+
+typedef struct gss_ctx_id_t_desc_struct {
+ struct krb5_auth_context_data *auth_context;
+ gss_name_t source, target;
+ OM_uint32 flags;
+ enum { LOCAL = 1, OPEN = 2} more_flags;
+ struct krb5_ticket *ticket;
+} gss_ctx_id_t_desc;
+
+typedef gss_ctx_id_t_desc *gss_ctx_id_t;
+
+typedef struct gss_OID_desc_struct {
+ OM_uint32 length;
+ void *elements;
+} gss_OID_desc, *gss_OID;
+
+typedef struct gss_OID_set_desc_struct {
+ size_t count;
+ gss_OID elements;
+} gss_OID_set_desc, *gss_OID_set;
+
+struct krb5_keytab_data;
+
+typedef int gss_cred_usage_t;
+
+typedef struct gss_cred_id_t_desc_struct {
+ gss_name_t principal;
+ struct krb5_keytab_data *keytab;
+ OM_uint32 lifetime;
+ gss_cred_usage_t usage;
+ gss_OID_set mechanisms;
+} gss_cred_id_t_desc;
+
+typedef gss_cred_id_t_desc *gss_cred_id_t;
+
+typedef struct gss_buffer_desc_struct {
+ size_t length;
+ void *value;
+} gss_buffer_desc, *gss_buffer_t;
+
+typedef struct gss_channel_bindings_struct {
+ OM_uint32 initiator_addrtype;
+ gss_buffer_desc initiator_address;
+ OM_uint32 acceptor_addrtype;
+ gss_buffer_desc acceptor_address;
+ gss_buffer_desc application_data;
+} *gss_channel_bindings_t;
+
+/*
+ * For now, define a QOP-type as an OM_uint32
+ */
+typedef OM_uint32 gss_qop_t;
+
+/*
+ * Flag bits for context-level services.
+ */
+#define GSS_C_DELEG_FLAG 1
+#define GSS_C_MUTUAL_FLAG 2
+#define GSS_C_REPLAY_FLAG 4
+#define GSS_C_SEQUENCE_FLAG 8
+#define GSS_C_CONF_FLAG 16
+#define GSS_C_INTEG_FLAG 32
+#define GSS_C_ANON_FLAG 64
+#define GSS_C_PROT_READY_FLAG 128
+#define GSS_C_TRANS_FLAG 256
+
+/*
+ * Credential usage options
+ */
+#define GSS_C_BOTH 0
+#define GSS_C_INITIATE 1
+#define GSS_C_ACCEPT 2
+
+/*
+ * Status code types for gss_display_status
+ */
+#define GSS_C_GSS_CODE 1
+#define GSS_C_MECH_CODE 2
+
+/*
+ * The constant definitions for channel-bindings address families
+ */
+#define GSS_C_AF_UNSPEC 0
+#define GSS_C_AF_LOCAL 1
+#define GSS_C_AF_INET 2
+#define GSS_C_AF_IMPLINK 3
+#define GSS_C_AF_PUP 4
+#define GSS_C_AF_CHAOS 5
+#define GSS_C_AF_NS 6
+#define GSS_C_AF_NBS 7
+#define GSS_C_AF_ECMA 8
+#define GSS_C_AF_DATAKIT 9
+#define GSS_C_AF_CCITT 10
+#define GSS_C_AF_SNA 11
+#define GSS_C_AF_DECnet 12
+#define GSS_C_AF_DLI 13
+#define GSS_C_AF_LAT 14
+#define GSS_C_AF_HYLINK 15
+#define GSS_C_AF_APPLETALK 16
+#define GSS_C_AF_BSC 17
+#define GSS_C_AF_DSS 18
+#define GSS_C_AF_OSI 19
+#define GSS_C_AF_X25 21
+#define GSS_C_AF_INET6 24
+
+#define GSS_C_AF_NULLADDR 255
+
+/*
+ * Various Null values
+ */
+#define GSS_C_NO_NAME ((gss_name_t) 0)
+#define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
+#define GSS_C_NO_OID ((gss_OID) 0)
+#define GSS_C_NO_OID_SET ((gss_OID_set) 0)
+#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
+#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
+#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
+#define GSS_C_EMPTY_BUFFER {0, NULL}
+
+/*
+ * Some alternate names for a couple of the above
+ * values. These are defined for V1 compatibility.
+ */
+#define GSS_C_NULL_OID GSS_C_NO_OID
+#define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET
+
+/*
+ * Define the default Quality of Protection for per-message
+ * services. Note that an implementation that offers multiple
+ * levels of QOP may define GSS_C_QOP_DEFAULT to be either zero
+ * (as done here) to mean "default protection", or to a specific
+ * explicit QOP value. However, a value of 0 should always be
+ * interpreted by a GSSAPI implementation as a request for the
+ * default protection level.
+ */
+#define GSS_C_QOP_DEFAULT 0
+
+/*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+#define GSS_C_INDEFINITE 0xfffffffful
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_USER_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_STRING_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 2(gss-host-based-services)}. The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_ANONYMOUS;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_EXPORT_NAME;
+
+/*
+ * This if for kerberos5 names.
+ */
+
+extern gss_OID GSS_KRB5_NT_PRINCIPAL_NAME;
+extern gss_OID GSS_KRB5_NT_USER_NAME;
+extern gss_OID GSS_KRB5_NT_MACHINE_UID_NAME;
+extern gss_OID GSS_KRB5_NT_STRING_UID_NAME;
+
+extern gss_OID GSS_KRB5_MECHANISM;
+
+/* Major status codes */
+
+#define GSS_S_COMPLETE 0
+
+/*
+ * Some "helper" definitions to make the status code macros obvious.
+ */
+#define GSS_C_CALLING_ERROR_OFFSET 24
+#define GSS_C_ROUTINE_ERROR_OFFSET 16
+#define GSS_C_SUPPLEMENTARY_OFFSET 0
+#define GSS_C_CALLING_ERROR_MASK 0377ul
+#define GSS_C_ROUTINE_ERROR_MASK 0377ul
+#define GSS_C_SUPPLEMENTARY_MASK 0177777ul
+
+/*
+ * The macros that test status codes for error conditions.
+ * Note that the GSS_ERROR() macro has changed slightly from
+ * the V1 GSSAPI so that it now evaluates its argument
+ * only once.
+ */
+#define GSS_CALLING_ERROR(x) \
+ (x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+#define GSS_ROUTINE_ERROR(x) \
+ (x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+#define GSS_SUPPLEMENTARY_INFO(x) \
+ (x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+#define GSS_ERROR(x) \
+ (x & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
+ (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
+
+/*
+ * Now the actual status code definitions
+ */
+
+/*
+ * Calling errors:
+ */
+#define GSS_S_CALL_INACCESSIBLE_READ \
+ (1ul << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_INACCESSIBLE_WRITE \
+ (2ul << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_BAD_STRUCTURE \
+ (3ul << GSS_C_CALLING_ERROR_OFFSET)
+
+/*
+ * Routine errors:
+ */
+#define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET)
+
+#define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_MIC GSS_S_BAD_SIG
+#define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_QOP (14ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAUTHORIZED (15ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAVAILABLE (16ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DUPLICATE_ELEMENT (17ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NAME_NOT_MN (18ul << GSS_C_ROUTINE_ERROR_OFFSET)
+
+/*
+ * Supplementary info bits:
+ */
+#define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
+#define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
+#define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
+#define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
+#define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
+
+/*
+ * From RFC1964:
+ *
+ * 4.1.1. Non-Kerberos-specific codes
+ */
+
+#define GSS_KRB5_S_G_BAD_SERVICE_NAME 1
+ /* "No @ in SERVICE-NAME name string" */
+#define GSS_KRB5_S_G_BAD_STRING_UID 2
+ /* "STRING-UID-NAME contains nondigits" */
+#define GSS_KRB5_S_G_NOUSER 3
+ /* "UID does not resolve to username" */
+#define GSS_KRB5_S_G_VALIDATE_FAILED 4
+ /* "Validation error" */
+#define GSS_KRB5_S_G_BUFFER_ALLOC 5
+ /* "Couldn't allocate gss_buffer_t data" */
+#define GSS_KRB5_S_G_BAD_MSG_CTX 6
+ /* "Message context invalid" */
+#define GSS_KRB5_S_G_WRONG_SIZE 7
+ /* "Buffer is the wrong size" */
+#define GSS_KRB5_S_G_BAD_USAGE 8
+ /* "Credential usage type is unknown" */
+#define GSS_KRB5_S_G_UNKNOWN_QOP 9
+ /* "Unknown quality of protection specified" */
+
+ /*
+ * 4.1.2. Kerberos-specific-codes
+ */
+
+#define GSS_KRB5_S_KG_CCACHE_NOMATCH 10
+ /* "Principal in credential cache does not match desired name" */
+#define GSS_KRB5_S_KG_KEYTAB_NOMATCH 11
+ /* "No principal in keytab matches desired name" */
+#define GSS_KRB5_S_KG_TGT_MISSING 12
+ /* "Credential cache has no TGT" */
+#define GSS_KRB5_S_KG_NO_SUBKEY 13
+ /* "Authenticator has no subkey" */
+#define GSS_KRB5_S_KG_CONTEXT_ESTABLISHED 14
+ /* "Context is already fully established" */
+#define GSS_KRB5_S_KG_BAD_SIGN_TYPE 15
+ /* "Unknown signature type in token" */
+#define GSS_KRB5_S_KG_BAD_LENGTH 16
+ /* "Invalid field length in token" */
+#define GSS_KRB5_S_KG_CTX_INCOMPLETE 17
+ /* "Attempt to use incomplete security context" */
+
+/*
+ * Finally, function prototypes for the GSS-API routines.
+ */
+
+OM_uint32 gss_acquire_cred
+ (OM_uint32 * minor_status,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ const gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t * output_cred_handle,
+ gss_OID_set * actual_mechs,
+ OM_uint32 * time_rec
+ );
+
+OM_uint32 gss_release_cred
+ (OM_uint32 * minor_status,
+ gss_cred_id_t * cred_handle
+ );
+
+OM_uint32 gss_init_sec_context
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ );
+
+OM_uint32 gss_accept_sec_context
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t * delegated_cred_handle
+ );
+
+OM_uint32 gss_process_context_token
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t token_buffer
+ );
+
+OM_uint32 gss_delete_sec_context
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t output_token
+ );
+
+OM_uint32 gss_context_time
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ OM_uint32 * time_rec
+ );
+
+OM_uint32 gss_get_mic
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token
+ );
+
+OM_uint32 gss_verify_mic
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state
+ );
+
+OM_uint32 gss_wrap
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ const gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer
+ );
+
+OM_uint32 gss_unwrap
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ gss_qop_t * qop_state
+ );
+
+OM_uint32 gss_display_status
+ (OM_uint32 * minor_status,
+ OM_uint32 status_value,
+ int status_type,
+ const gss_OID mech_type,
+ OM_uint32 * message_context,
+ gss_buffer_t status_string
+ );
+
+OM_uint32 gss_indicate_mechs
+ (OM_uint32 * minor_status,
+ gss_OID_set * mech_set
+ );
+
+OM_uint32 gss_compare_name
+ (OM_uint32 * minor_status,
+ const gss_name_t name1,
+ const gss_name_t name2,
+ int * name_equal
+ );
+
+OM_uint32 gss_display_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t output_name_buffer,
+ gss_OID * output_name_type
+ );
+
+OM_uint32 gss_import_name
+ (OM_uint32 * minor_status,
+ const gss_buffer_t input_name_buffer,
+ const gss_OID input_name_type,
+ gss_name_t * output_name
+ );
+
+OM_uint32 gss_export_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t exported_name
+ );
+
+OM_uint32 gss_release_name
+ (OM_uint32 * minor_status,
+ gss_name_t * input_name
+ );
+
+OM_uint32 gss_release_buffer
+ (OM_uint32 * minor_status,
+ gss_buffer_t buffer
+ );
+
+OM_uint32 gss_release_oid_set
+ (OM_uint32 * minor_status,
+ gss_OID_set * set
+ );
+
+OM_uint32 gss_inquire_cred
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t * name,
+ OM_uint32 * lifetime,
+ gss_cred_usage_t * cred_usage,
+ gss_OID_set * mechanisms
+ );
+
+OM_uint32 gss_inquire_context (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_name_t * src_name,
+ gss_name_t * targ_name,
+ OM_uint32 * lifetime_rec,
+ gss_OID * mech_type,
+ OM_uint32 * ctx_flags,
+ int * locally_initiated,
+ int * open
+ );
+
+OM_uint32 gss_wrap_size_limit (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 * max_input_size
+ );
+
+OM_uint32 gss_add_cred (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t input_cred_handle,
+ const gss_name_t desired_name,
+ const gss_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t * output_cred_handle,
+ gss_OID_set * actual_mechs,
+ OM_uint32 * initiator_time_rec,
+ OM_uint32 * acceptor_time_rec
+ );
+
+OM_uint32 gss_inquire_cred_by_mech (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID mech_type,
+ gss_name_t * name,
+ OM_uint32 * initiator_lifetime,
+ OM_uint32 * acceptor_lifetime,
+ gss_cred_usage_t * cred_usage
+ );
+
+OM_uint32 gss_export_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t interprocess_token
+ );
+
+OM_uint32 gss_import_sec_context (
+ OM_uint32 * minor_status,
+ const gss_buffer_t interprocess_token,
+ gss_ctx_id_t * context_handle
+ );
+
+OM_uint32 gss_create_empty_oid_set (
+ OM_uint32 * minor_status,
+ gss_OID_set * oid_set
+ );
+
+OM_uint32 gss_add_oid_set_member (
+ OM_uint32 * minor_status,
+ const gss_OID member_oid,
+ gss_OID_set * oid_set
+ );
+
+OM_uint32 gss_test_oid_set_member (
+ OM_uint32 * minor_status,
+ const gss_OID member,
+ const gss_OID_set set,
+ int * present
+ );
+
+OM_uint32 gss_inquire_names_for_mech (
+ OM_uint32 * minor_status,
+ const gss_OID mechanism,
+ gss_OID_set * name_types
+ );
+
+OM_uint32 gss_inquire_mechs_for_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_OID_set * mech_types
+ );
+
+OM_uint32 gss_canonicalize_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ const gss_OID mech_type,
+ gss_name_t * output_name
+ );
+
+OM_uint32 gss_duplicate_name (
+ OM_uint32 * minor_status,
+ const gss_name_t src_name,
+ gss_name_t * dest_name
+ );
+
+/*
+ * The following routines are obsolete variants of gss_get_mic,
+ * gss_verify_mic, gss_wrap and gss_unwrap. They should be
+ * provided by GSSAPI V2 implementations for backwards
+ * compatibility with V1 applications. Distinct entrypoints
+ * (as opposed to #defines) should be provided, both to allow
+ * GSSAPI V1 applications to link against GSSAPI V2 implementations,
+ * and to retain the slight parameter type differences between the
+ * obsolete versions of these routines and their current forms.
+ */
+
+OM_uint32 gss_sign
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int qop_req,
+ gss_buffer_t message_buffer,
+ gss_buffer_t message_token
+ );
+
+OM_uint32 gss_verify
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t message_buffer,
+ gss_buffer_t token_buffer,
+ int * qop_state
+ );
+
+OM_uint32 gss_seal
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ int qop_req,
+ gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer
+ );
+
+OM_uint32 gss_unseal
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ int * qop_state
+ );
+
+/*
+ * kerberos mechanism specific functions
+ */
+
+OM_uint32 gsskrb5_register_acceptor_identity
+ (char *identity);
+
+#endif /* GSSAPI_H_ */
diff --git a/crypto/heimdal/lib/gssapi/gssapi_locl.h b/crypto/heimdal/lib/gssapi/gssapi_locl.h
new file mode 100644
index 000000000000..f488a2004046
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gssapi_locl.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: gssapi_locl.h,v 1.11 1999/12/02 17:05:03 joda Exp $ */
+
+#ifndef GSSAPI_LOCL_H
+#define GSSAPI_LOCL_H
+
+#include <krb5_locl.h>
+#include <gssapi.h>
+
+extern krb5_context gssapi_krb5_context;
+
+void gssapi_krb5_init (void);
+
+krb5_error_code
+gssapi_krb5_create_8003_checksum (
+ const gss_channel_bindings_t input_chan_bindings,
+ OM_uint32 flags,
+ Checksum *result);
+
+krb5_error_code
+gssapi_krb5_verify_8003_checksum (
+ const gss_channel_bindings_t input_chan_bindings,
+ Checksum *cksum,
+ OM_uint32 *flags);
+
+OM_uint32
+gssapi_krb5_encapsulate(
+ krb5_data *in_data,
+ gss_buffer_t output_token,
+ u_char *type);
+
+OM_uint32
+gssapi_krb5_decapsulate(
+ gss_buffer_t input_token_buffer,
+ krb5_data *out_data,
+ char *type);
+
+void
+gssapi_krb5_encap_length (size_t data_len,
+ size_t *len,
+ size_t *total_len);
+
+u_char *
+gssapi_krb5_make_header (u_char *p,
+ size_t len,
+ u_char *type);
+
+OM_uint32
+gssapi_krb5_verify_header(u_char **str,
+ size_t total_len,
+ char *type);
+
+OM_uint32
+gss_krb5_getsomekey(const gss_ctx_id_t context_handle,
+ des_cblock *key);
+
+#endif
diff --git a/crypto/heimdal/lib/gssapi/import_name.c b/crypto/heimdal/lib/gssapi/import_name.c
new file mode 100644
index 000000000000..6cb94c4a9a36
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/import_name.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: import_name.c,v 1.8 1999/12/02 17:05:03 joda Exp $");
+
+static OM_uint32
+import_krb5_name (OM_uint32 *minor_status,
+ const gss_buffer_t input_name_buffer,
+ gss_name_t *output_name)
+{
+ krb5_error_code kerr;
+ char *tmp;
+
+ tmp = malloc (input_name_buffer->length + 1);
+ if (tmp == NULL)
+ return GSS_S_FAILURE;
+ memcpy (tmp,
+ input_name_buffer->value,
+ input_name_buffer->length);
+ tmp[input_name_buffer->length] = '\0';
+
+ kerr = krb5_parse_name (gssapi_krb5_context,
+ tmp,
+ output_name);
+ free (tmp);
+ if (kerr == 0)
+ return GSS_S_COMPLETE;
+ else if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
+ return GSS_S_BAD_NAME;
+ else
+ return GSS_S_FAILURE;
+}
+
+static OM_uint32
+import_hostbased_name (OM_uint32 *minor_status,
+ const gss_buffer_t input_name_buffer,
+ gss_name_t *output_name)
+{
+ krb5_error_code kerr;
+ char *tmp;
+ char *p;
+ char *host;
+ char local_hostname[MAXHOSTNAMELEN];
+
+ tmp = malloc (input_name_buffer->length + 1);
+ if (tmp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy (tmp,
+ input_name_buffer->value,
+ input_name_buffer->length);
+ tmp[input_name_buffer->length] = '\0';
+
+ p = strchr (tmp, '@');
+ if (p != NULL) {
+ *p = '\0';
+ host = p + 1;
+ } else {
+ if (gethostname(local_hostname, sizeof(local_hostname)) < 0) {
+ *minor_status = errno;
+ free (tmp);
+ return GSS_S_FAILURE;
+ }
+ host = local_hostname;
+ }
+
+ kerr = krb5_sname_to_principal (gssapi_krb5_context,
+ host,
+ tmp,
+ KRB5_NT_SRV_HST,
+ output_name);
+ free (tmp);
+ *minor_status = kerr;
+ if (kerr == 0)
+ return GSS_S_COMPLETE;
+ else if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
+ return GSS_S_BAD_NAME;
+ else
+ return GSS_S_FAILURE;
+}
+
+OM_uint32 gss_import_name
+ (OM_uint32 * minor_status,
+ const gss_buffer_t input_name_buffer,
+ const gss_OID input_name_type,
+ gss_name_t * output_name
+ )
+{
+ gssapi_krb5_init ();
+
+ if (input_name_type == GSS_C_NT_HOSTBASED_SERVICE)
+ return import_hostbased_name (minor_status,
+ input_name_buffer,
+ output_name);
+ else if (input_name_type == GSS_C_NO_OID
+ || input_name_type == GSS_C_NT_USER_NAME
+ || input_name_type == GSS_KRB5_NT_PRINCIPAL_NAME)
+ /* default printable syntax */
+ return import_krb5_name (minor_status,
+ input_name_buffer,
+ output_name);
+ else
+ return GSS_S_BAD_NAMETYPE;
+}
diff --git a/crypto/heimdal/lib/gssapi/indicate_mechs.c b/crypto/heimdal/lib/gssapi/indicate_mechs.c
new file mode 100644
index 000000000000..26e018e80d76
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/indicate_mechs.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: indicate_mechs.c,v 1.3 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32 gss_indicate_mechs
+ (OM_uint32 * minor_status,
+ gss_OID_set * mech_set
+ )
+{
+ *mech_set = malloc(sizeof(**mech_set));
+ if (*mech_set == NULL) {
+ return GSS_S_FAILURE;
+ }
+ (*mech_set)->count = 1;
+ (*mech_set)->elements = malloc((*mech_set)->count * sizeof(gss_OID_desc));
+ if ((*mech_set)->elements == NULL) {
+ free (*mech_set);
+ return GSS_S_FAILURE;
+ }
+ (*mech_set)->elements[0] = *GSS_KRB5_MECHANISM;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/init.c b/crypto/heimdal/lib/gssapi/init.c
new file mode 100644
index 000000000000..2c0149038dd5
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/init.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: init.c,v 1.4 1999/12/02 17:05:04 joda Exp $");
+
+void
+gssapi_krb5_init (void)
+{
+ if(gssapi_krb5_context == NULL)
+ krb5_init_context (&gssapi_krb5_context);
+}
diff --git a/crypto/heimdal/lib/gssapi/init_sec_context.c b/crypto/heimdal/lib/gssapi/init_sec_context.c
new file mode 100644
index 000000000000..2f9bbc9ab5d2
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/init_sec_context.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: init_sec_context.c,v 1.18 1999/12/26 18:31:36 assar Exp $");
+
+static OM_uint32
+init_auth
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ OM_uint32 ret = GSS_S_FAILURE;
+ krb5_error_code kret;
+ krb5_flags ap_options;
+ krb5_creds this_cred, *cred;
+ krb5_data outbuf;
+ krb5_ccache ccache;
+ u_int32_t flags;
+ Authenticator *auth;
+ krb5_data authenticator;
+ Checksum cksum;
+ krb5_enctype enctype;
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ outbuf.length = 0;
+ outbuf.data = NULL;
+
+ *minor_status = 0;
+
+ *context_handle = malloc(sizeof(**context_handle));
+ if (*context_handle == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ (*context_handle)->auth_context = NULL;
+ (*context_handle)->source = NULL;
+ (*context_handle)->target = NULL;
+ (*context_handle)->flags = 0;
+ (*context_handle)->more_flags = 0;
+ (*context_handle)->ticket = NULL;
+
+ kret = krb5_auth_con_init (gssapi_krb5_context,
+ &(*context_handle)->auth_context);
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ {
+ int32_t tmp;
+
+ krb5_auth_con_getflags(gssapi_krb5_context,
+ (*context_handle)->auth_context,
+ &tmp);
+ tmp |= KRB5_AUTH_CONTEXT_DO_SEQUENCE;
+ krb5_auth_con_setflags(gssapi_krb5_context,
+ (*context_handle)->auth_context,
+ tmp);
+ }
+
+ if (actual_mech_type)
+ *actual_mech_type = GSS_KRB5_MECHANISM;
+
+ flags = 0;
+ ap_options = 0;
+ if (req_flags & GSS_C_DELEG_FLAG)
+ ; /* XXX */
+ if (req_flags & GSS_C_MUTUAL_FLAG) {
+ flags |= GSS_C_MUTUAL_FLAG;
+ ap_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+ if (req_flags & GSS_C_REPLAY_FLAG)
+ ; /* XXX */
+ if (req_flags & GSS_C_SEQUENCE_FLAG)
+ ; /* XXX */
+ if (req_flags & GSS_C_ANON_FLAG)
+ ; /* XXX */
+ flags |= GSS_C_CONF_FLAG;
+ flags |= GSS_C_INTEG_FLAG;
+ flags |= GSS_C_SEQUENCE_FLAG;
+ flags |= GSS_C_TRANS_FLAG;
+
+ if (ret_flags)
+ *ret_flags = flags;
+ (*context_handle)->flags = flags;
+ (*context_handle)->more_flags = LOCAL;
+
+ kret = krb5_cc_default (gssapi_krb5_context, &ccache);
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ kret = krb5_cc_get_principal (gssapi_krb5_context,
+ ccache,
+ &(*context_handle)->source);
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ kret = krb5_copy_principal (gssapi_krb5_context,
+ target_name,
+ &(*context_handle)->target);
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ memset(&this_cred, 0, sizeof(this_cred));
+ this_cred.client = (*context_handle)->source;
+ this_cred.server = (*context_handle)->target;
+ this_cred.times.endtime = 0;
+ this_cred.session.keytype = ETYPE_DES_CBC_CRC;
+
+ kret = krb5_get_credentials (gssapi_krb5_context,
+ KRB5_TC_MATCH_KEYTYPE,
+ ccache,
+ &this_cred,
+ &cred);
+
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ krb5_auth_con_setkey(gssapi_krb5_context,
+ (*context_handle)->auth_context,
+ &cred->session);
+
+ kret = gssapi_krb5_create_8003_checksum (input_chan_bindings,
+ flags,
+ &cksum);
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+#if 1
+ enctype = (*context_handle)->auth_context->keyblock->keytype;
+#else
+ if ((*context_handle)->auth_context->enctype)
+ enctype = (*context_handle)->auth_context->enctype;
+ else {
+ kret = krb5_keytype_to_enctype(gssapi_krb5_context,
+ (*context_handle)->auth_context->keyblock->keytype,
+ &enctype);
+ if (kret)
+ return kret;
+ }
+#endif
+
+
+
+ kret = krb5_build_authenticator (gssapi_krb5_context,
+ (*context_handle)->auth_context,
+ enctype,
+ cred,
+ &cksum,
+ &auth,
+ &authenticator);
+
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ kret = krb5_build_ap_req (gssapi_krb5_context,
+ enctype,
+ cred,
+ ap_options,
+ authenticator,
+ &outbuf);
+
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ ret = gssapi_krb5_encapsulate (&outbuf,
+ output_token,
+ "\x01\x00");
+ if (ret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ if (flags & GSS_C_MUTUAL_FLAG) {
+ return GSS_S_CONTINUE_NEEDED;
+ } else {
+ (*context_handle)->more_flags |= OPEN;
+ return GSS_S_COMPLETE;
+ }
+
+failure:
+ krb5_auth_con_free (gssapi_krb5_context,
+ (*context_handle)->auth_context);
+ if((*context_handle)->source)
+ krb5_free_principal (gssapi_krb5_context,
+ (*context_handle)->source);
+ if((*context_handle)->target)
+ krb5_free_principal (gssapi_krb5_context,
+ (*context_handle)->target);
+ free (*context_handle);
+ krb5_data_free (&outbuf);
+ *context_handle = GSS_C_NO_CONTEXT;
+ return ret;
+}
+
+static OM_uint32
+repl_mutual
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ OM_uint32 ret;
+ krb5_error_code kret;
+ krb5_data indata;
+ krb5_ap_rep_enc_part *repl;
+
+ ret = gssapi_krb5_decapsulate (input_token,
+ &indata,
+ "\x02\x00");
+ if (ret) {
+ /* XXX - Handle AP_ERROR */
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_rd_rep (gssapi_krb5_context,
+ (*context_handle)->auth_context,
+ &indata,
+ &repl);
+ if (kret)
+ return GSS_S_FAILURE;
+ krb5_free_ap_rep_enc_part (gssapi_krb5_context,
+ repl);
+
+ output_token->length = 0;
+
+ (*context_handle)->more_flags |= OPEN;
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * gss_init_sec_context
+ */
+
+OM_uint32 gss_init_sec_context
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ gssapi_krb5_init ();
+
+ if (input_token == GSS_C_NO_BUFFER || input_token->length == 0)
+ return init_auth (minor_status,
+ initiator_cred_handle,
+ context_handle,
+ target_name,
+ mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+ else
+ return repl_mutual(minor_status,
+ initiator_cred_handle,
+ context_handle,
+ target_name,
+ mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+}
diff --git a/crypto/heimdal/lib/gssapi/inquire_context.c b/crypto/heimdal/lib/gssapi/inquire_context.c
new file mode 100644
index 000000000000..64632530b932
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/inquire_context.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: inquire_context.c,v 1.3 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32 gss_inquire_context (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_name_t * src_name,
+ gss_name_t * targ_name,
+ OM_uint32 * lifetime_rec,
+ gss_OID * mech_type,
+ OM_uint32 * ctx_flags,
+ int * locally_initiated,
+ int * open
+ )
+{
+ OM_uint32 ret;
+
+ if (src_name) {
+ ret = gss_duplicate_name (minor_status,
+ context_handle->source,
+ src_name);
+ if (ret)
+ return ret;
+ }
+
+ if (targ_name) {
+ ret = gss_duplicate_name (minor_status,
+ context_handle->target,
+ targ_name);
+ if (ret)
+ return ret;
+ }
+
+ if (lifetime_rec)
+ *lifetime_rec = GSS_C_INDEFINITE;
+
+ if (mech_type)
+ *mech_type = GSS_KRB5_MECHANISM;
+
+ if (ctx_flags)
+ *ctx_flags = context_handle->flags;
+
+ if (locally_initiated)
+ *locally_initiated = context_handle->more_flags & LOCAL;
+
+ if (open)
+ *open = context_handle->more_flags & OPEN;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/inquire_cred.c b/crypto/heimdal/lib/gssapi/inquire_cred.c
new file mode 100644
index 000000000000..9e181f3f5e66
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/inquire_cred.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: inquire_cred.c,v 1.2 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32 gss_inquire_cred
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t * name,
+ OM_uint32 * lifetime,
+ gss_cred_usage_t * cred_usage,
+ gss_OID_set * mechanisms
+ )
+{
+ OM_uint32 ret;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ return GSS_S_FAILURE;
+ }
+
+ if (name != NULL) {
+ ret = gss_duplicate_name(minor_status, cred_handle->principal, name);
+ if (ret) {
+ return ret;
+ }
+ }
+ if (lifetime != NULL) {
+ *lifetime = cred_handle->lifetime;
+ }
+ if (cred_usage != NULL) {
+ *cred_usage = cred_handle->usage;
+ }
+ if (mechanisms != NULL) {
+ ret = gss_create_empty_oid_set(minor_status, mechanisms);
+ if (ret) {
+ return ret;
+ }
+ ret = gss_add_oid_set_member(minor_status,
+ &cred_handle->mechanisms->elements[0],
+ mechanisms);
+ if (ret) {
+ return ret;
+ }
+ }
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/release_buffer.c b/crypto/heimdal/lib/gssapi/release_buffer.c
new file mode 100644
index 000000000000..85f971f12231
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/release_buffer.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: release_buffer.c,v 1.3 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32 gss_release_buffer
+ (OM_uint32 * minor_status,
+ gss_buffer_t buffer
+ )
+{
+ free (buffer->value);
+ buffer->length = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/release_cred.c b/crypto/heimdal/lib/gssapi/release_cred.c
new file mode 100644
index 000000000000..0ee876e386a3
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/release_cred.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: release_cred.c,v 1.4 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32 gss_release_cred
+ (OM_uint32 * minor_status,
+ gss_cred_id_t * cred_handle
+ )
+{
+ if (*cred_handle == GSS_C_NO_CREDENTIAL) {
+ return GSS_S_COMPLETE;
+ }
+
+ gssapi_krb5_init ();
+
+ krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal);
+ if ((*cred_handle)->keytab != NULL)
+ krb5_kt_close(gssapi_krb5_context, (*cred_handle)->keytab);
+ gss_release_oid_set(NULL, &(*cred_handle)->mechanisms);
+ free(*cred_handle);
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+ return GSS_S_COMPLETE;
+}
+
diff --git a/crypto/heimdal/lib/gssapi/release_name.c b/crypto/heimdal/lib/gssapi/release_name.c
new file mode 100644
index 000000000000..7c0fcd36c0a7
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/release_name.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: release_name.c,v 1.4 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32 gss_release_name
+ (OM_uint32 * minor_status,
+ gss_name_t * input_name
+ )
+{
+ gssapi_krb5_init ();
+ krb5_free_principal(gssapi_krb5_context,
+ *input_name);
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/release_oid_set.c b/crypto/heimdal/lib/gssapi/release_oid_set.c
new file mode 100644
index 000000000000..fe7171ed6b55
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/release_oid_set.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: release_oid_set.c,v 1.3 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32 gss_release_oid_set
+ (OM_uint32 * minor_status,
+ gss_OID_set * set
+ )
+{
+ free ((*set)->elements);
+ free (*set);
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/test_oid_set_member.c b/crypto/heimdal/lib/gssapi/test_oid_set_member.c
new file mode 100644
index 000000000000..47e9fa789fb9
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/test_oid_set_member.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: test_oid_set_member.c,v 1.4 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32 gss_test_oid_set_member (
+ OM_uint32 * minor_status,
+ const gss_OID member,
+ const gss_OID_set set,
+ int * present
+ )
+{
+ size_t i;
+
+ *present = 0;
+ for (i = 0; i < set->count; ++i)
+ if (member->length == set->elements[i].length
+ && memcmp (member->elements,
+ set->elements[i].elements,
+ member->length) == 0) {
+ *present = 1;
+ break;
+ }
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/unwrap.c b/crypto/heimdal/lib/gssapi/unwrap.c
new file mode 100644
index 000000000000..45b1df1eda01
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/unwrap.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: unwrap.c,v 1.10 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32
+gss_krb5_getsomekey(const gss_ctx_id_t context_handle,
+ des_cblock *key)
+{
+ /* XXX this is ugly, and probably incorrect... */
+ krb5_keyblock *skey;
+ krb5_auth_con_getlocalsubkey(gssapi_krb5_context,
+ context_handle->auth_context,
+ &skey);
+ if(skey == NULL)
+ krb5_auth_con_getremotesubkey(gssapi_krb5_context,
+ context_handle->auth_context,
+ &skey);
+ if(skey == NULL)
+ krb5_auth_con_getkey(gssapi_krb5_context,
+ context_handle->auth_context,
+ &skey);
+ if(skey == NULL)
+ return GSS_S_FAILURE;
+ memcpy(key, skey->keyvalue.data, sizeof(*key));
+ krb5_free_keyblock(gssapi_krb5_context, skey);
+ return 0;
+}
+
+OM_uint32 gss_unwrap
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ gss_qop_t * qop_state
+ )
+{
+ u_char *p, *pad;
+ size_t len;
+ struct md5 md5;
+ u_char hash[16], seq_data[8];
+ des_key_schedule schedule;
+ des_cblock key;
+ des_cblock zero;
+ int i;
+ int32_t seq_number;
+ size_t padlength;
+ OM_uint32 ret;
+ int cstate;
+
+ p = input_message_buffer->value;
+ ret = gssapi_krb5_verify_header (&p,
+ input_message_buffer->length,
+ "\x02\x01");
+ if (ret)
+ return ret;
+
+ if (memcmp (p, "\x00\x00", 2) != 0)
+ return GSS_S_BAD_SIG;
+ p += 2;
+ if (memcmp (p, "\x00\x00", 2) == 0) {
+ cstate = 1;
+ } else if (memcmp (p, "\xFF\xFF", 2) == 0) {
+ cstate = 0;
+ } else
+ return GSS_S_BAD_MIC;
+ p += 2;
+ if(conf_state != NULL)
+ *conf_state = cstate;
+ if (memcmp (p, "\xff\xff", 2) != 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ p += 2;
+ p += 16;
+
+ len = p - (u_char *)input_message_buffer->value;
+
+ if(cstate) {
+ /* decrypt data */
+ gss_krb5_getsomekey(context_handle, &key);
+ for (i = 0; i < sizeof(key); ++i)
+ key[i] ^= 0xf0;
+ des_set_key (&key, schedule);
+ memset (&zero, 0, sizeof(zero));
+ des_cbc_encrypt ((des_cblock *)p,
+ (des_cblock *)p,
+ input_message_buffer->length - len,
+ schedule,
+ &zero,
+ DES_DECRYPT);
+
+ memset (key, 0, sizeof(key));
+ memset (schedule, 0, sizeof(schedule));
+ }
+ /* check pad */
+
+ pad = (u_char *)input_message_buffer->value + input_message_buffer->length - 1;
+ padlength = *pad;
+
+ for (i = padlength; i > 0 && *pad == padlength; i--, pad--)
+ ;
+ if (i != 0)
+ return GSS_S_BAD_MIC;
+
+ md5_init (&md5);
+ md5_update (&md5, p - 24, 8);
+ md5_update (&md5, p, input_message_buffer->length - len);
+ md5_finito (&md5, hash);
+
+ memset (&zero, 0, sizeof(zero));
+ gss_krb5_getsomekey(context_handle, &key);
+ des_set_key (&key, schedule);
+ des_cbc_cksum ((des_cblock *)hash,
+ (des_cblock *)hash, sizeof(hash), schedule, &zero);
+ if (memcmp (p - 8, hash, 8) != 0)
+ return GSS_S_BAD_MIC;
+
+ /* verify sequence number */
+
+ krb5_auth_getremoteseqnumber (gssapi_krb5_context,
+ context_handle->auth_context,
+ &seq_number);
+ seq_data[0] = (seq_number >> 0) & 0xFF;
+ seq_data[1] = (seq_number >> 8) & 0xFF;
+ seq_data[2] = (seq_number >> 16) & 0xFF;
+ seq_data[3] = (seq_number >> 24) & 0xFF;
+ memset (seq_data + 4,
+ (context_handle->more_flags & LOCAL) ? 0xFF : 0,
+ 4);
+
+ p -= 16;
+ des_set_key (&key, schedule);
+ des_cbc_encrypt ((des_cblock *)p, (des_cblock *)p, 8,
+ schedule, (des_cblock *)hash, DES_DECRYPT);
+
+ memset (key, 0, sizeof(key));
+ memset (schedule, 0, sizeof(schedule));
+
+ if (memcmp (p, seq_data, 8) != 0) {
+ return GSS_S_BAD_MIC;
+ }
+
+ krb5_auth_setremoteseqnumber (gssapi_krb5_context,
+ context_handle->auth_context,
+ ++seq_number);
+
+ /* copy out data */
+
+ output_message_buffer->length = input_message_buffer->length
+ - len - 8 - padlength;
+ output_message_buffer->value = malloc(output_message_buffer->length);
+ if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
+ return GSS_S_FAILURE;
+ memcpy (output_message_buffer->value,
+ p + 24,
+ output_message_buffer->length);
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/v1.c b/crypto/heimdal/lib/gssapi/v1.c
new file mode 100644
index 000000000000..34091ea71572
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/v1.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: v1.c,v 1.2 1999/12/02 17:05:04 joda Exp $");
+
+/* These functions are for V1 compatibility */
+
+OM_uint32 gss_sign
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int qop_req,
+ gss_buffer_t message_buffer,
+ gss_buffer_t message_token
+ )
+{
+ return gss_get_mic(minor_status,
+ context_handle,
+ (gss_qop_t)qop_req,
+ message_buffer,
+ message_token);
+}
+
+OM_uint32 gss_verify
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t message_buffer,
+ gss_buffer_t token_buffer,
+ int * qop_state
+ )
+{
+ return gss_verify_mic(minor_status,
+ context_handle,
+ message_buffer,
+ token_buffer,
+ (gss_qop_t *)qop_state);
+}
+
+OM_uint32 gss_seal
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ int qop_req,
+ gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer
+ )
+{
+ return gss_wrap(minor_status,
+ context_handle,
+ conf_req_flag,
+ (gss_qop_t)qop_req,
+ input_message_buffer,
+ conf_state,
+ output_message_buffer);
+}
+
+OM_uint32 gss_unseal
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ int * qop_state
+ )
+{
+ return gss_unwrap(minor_status,
+ context_handle,
+ input_message_buffer,
+ output_message_buffer,
+ conf_state,
+ (gss_qop_t *)qop_state);
+}
diff --git a/crypto/heimdal/lib/gssapi/verify_mic.c b/crypto/heimdal/lib/gssapi/verify_mic.c
new file mode 100644
index 000000000000..d4342a63e052
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/verify_mic.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: verify_mic.c,v 1.8 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32 gss_verify_mic
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state
+ )
+{
+ u_char *p;
+ struct md5 md5;
+ u_char hash[16], seq_data[8];
+ des_key_schedule schedule;
+ des_cblock key;
+ des_cblock zero;
+ int32_t seq_number;
+ OM_uint32 ret;
+
+ p = token_buffer->value;
+ ret = gssapi_krb5_verify_header (&p,
+ token_buffer->length,
+ "\x01\x01");
+ if (ret)
+ return ret;
+
+ if (memcmp(p, "\x00\x00", 2) != 0)
+ return GSS_S_BAD_SIG;
+ p += 2;
+ if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
+ return GSS_S_BAD_MIC;
+ p += 4;
+ p += 16;
+
+ /* verify checksum */
+ md5_init (&md5);
+ md5_update (&md5, p - 24, 8);
+ md5_update (&md5, message_buffer->value,
+ message_buffer->length);
+ md5_finito (&md5, hash);
+
+ memset (&zero, 0, sizeof(zero));
+#if 0
+ memcpy (&key, context_handle->auth_context->key.keyvalue.data,
+ sizeof(key));
+#endif
+ memcpy (&key, context_handle->auth_context->remote_subkey->keyvalue.data,
+ sizeof(key));
+
+ des_set_key (&key, schedule);
+ des_cbc_cksum ((des_cblock *)hash,
+ (des_cblock *)hash, sizeof(hash), schedule, &zero);
+ if (memcmp (p - 8, hash, 8) != 0) {
+ memset (key, 0, sizeof(key));
+ memset (schedule, 0, sizeof(schedule));
+ return GSS_S_BAD_MIC;
+ }
+
+ /* verify sequence number */
+
+ krb5_auth_getremoteseqnumber (gssapi_krb5_context,
+ context_handle->auth_context,
+ &seq_number);
+ seq_data[0] = (seq_number >> 0) & 0xFF;
+ seq_data[1] = (seq_number >> 8) & 0xFF;
+ seq_data[2] = (seq_number >> 16) & 0xFF;
+ seq_data[3] = (seq_number >> 24) & 0xFF;
+ memset (seq_data + 4,
+ (context_handle->more_flags & LOCAL) ? 0xFF : 0,
+ 4);
+
+ p -= 16;
+ des_set_key (&key, schedule);
+ des_cbc_encrypt ((des_cblock *)p, (des_cblock *)p, 8,
+ schedule, (des_cblock *)hash, DES_DECRYPT);
+
+ memset (key, 0, sizeof(key));
+ memset (schedule, 0, sizeof(schedule));
+
+ if (memcmp (p, seq_data, 8) != 0) {
+ return GSS_S_BAD_MIC;
+ }
+
+ krb5_auth_setremoteseqnumber (gssapi_krb5_context,
+ context_handle->auth_context,
+ ++seq_number);
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/wrap.c b/crypto/heimdal/lib/gssapi/wrap.c
new file mode 100644
index 000000000000..98ee6891e65b
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/wrap.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "gssapi_locl.h"
+
+RCSID("$Id: wrap.c,v 1.10 1999/12/02 17:05:04 joda Exp $");
+
+OM_uint32 gss_wrap_size_limit (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 * max_input_size
+ )
+{
+ size_t len, total_len, padlength;
+ padlength = 8 - (req_output_size % 8);
+ len = req_output_size + 8 + padlength + 22;
+ gssapi_krb5_encap_length(len, &len, &total_len);
+ *max_input_size = (OM_uint32)total_len;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 gss_wrap
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ const gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer
+ )
+{
+ u_char *p;
+ struct md5 md5;
+ u_char hash[16];
+ des_key_schedule schedule;
+ des_cblock key;
+ des_cblock zero;
+ int i;
+ int32_t seq_number;
+ size_t len, total_len, padlength;
+
+ padlength = 8 - (input_message_buffer->length % 8);
+ len = input_message_buffer->length + 8 + padlength + 22;
+ gssapi_krb5_encap_length (len, &len, &total_len);
+
+ output_message_buffer->length = total_len;
+ output_message_buffer->value = malloc (total_len);
+ if (output_message_buffer->value == NULL)
+ return GSS_S_FAILURE;
+
+ p = gssapi_krb5_make_header(output_message_buffer->value,
+ len,
+ "\x02\x01");
+
+
+ /* SGN_ALG */
+ memcpy (p, "\x00\x00", 2);
+ p += 2;
+ /* SEAL_ALG */
+ if(conf_req_flag)
+ memcpy (p, "\x00\x00", 2);
+ else
+ memcpy (p, "\xff\xff", 2);
+ p += 2;
+ /* Filler */
+ memcpy (p, "\xff\xff", 2);
+ p += 2;
+
+ /* fill in later */
+ memset (p, 0, 16);
+ p += 16;
+
+ /* confounder + data + pad */
+ des_new_random_key((des_cblock*)p);
+ memcpy (p + 8, input_message_buffer->value,
+ input_message_buffer->length);
+ memset (p + 8 + input_message_buffer->length, padlength, padlength);
+
+ /* checksum */
+ md5_init (&md5);
+ md5_update (&md5, p - 24, 8);
+ md5_update (&md5, p, input_message_buffer->length + padlength + 8);
+ md5_finito (&md5, hash);
+
+ memset (&zero, 0, sizeof(zero));
+ gss_krb5_getsomekey(context_handle, &key);
+ des_set_key (&key, schedule);
+ des_cbc_cksum ((des_cblock *)hash,
+ (des_cblock *)hash, sizeof(hash), schedule, &zero);
+ memcpy (p - 8, hash, 8);
+
+ /* sequence number */
+ krb5_auth_getlocalseqnumber (gssapi_krb5_context,
+ context_handle->auth_context,
+ &seq_number);
+
+ p -= 16;
+ p[0] = (seq_number >> 0) & 0xFF;
+ p[1] = (seq_number >> 8) & 0xFF;
+ p[2] = (seq_number >> 16) & 0xFF;
+ p[3] = (seq_number >> 24) & 0xFF;
+ memset (p + 4,
+ (context_handle->more_flags & LOCAL) ? 0 : 0xFF,
+ 4);
+
+ des_set_key (&key, schedule);
+ des_cbc_encrypt ((des_cblock *)p, (des_cblock *)p, 8,
+ schedule, (des_cblock *)(p + 8), DES_ENCRYPT);
+
+ krb5_auth_setlocalseqnumber (gssapi_krb5_context,
+ context_handle->auth_context,
+ ++seq_number);
+
+ /* encrypt the data */
+ p += 16;
+
+ if(conf_req_flag) {
+ gss_krb5_getsomekey(context_handle, &key);
+ for (i = 0; i < sizeof(key); ++i)
+ key[i] ^= 0xf0;
+ des_set_key (&key, schedule);
+ memset (&zero, 0, sizeof(zero));
+ des_cbc_encrypt ((des_cblock *)p,
+ (des_cblock *)p,
+ 8 + input_message_buffer->length + padlength,
+ schedule,
+ &zero,
+ DES_ENCRYPT);
+
+ memset (key, 0, sizeof(key));
+ memset (schedule, 0, sizeof(schedule));
+ }
+ if(conf_state != NULL)
+ *conf_state = conf_req_flag;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/hdb/Makefile.am b/crypto/heimdal/lib/hdb/Makefile.am
new file mode 100644
index 000000000000..6c4341e7d27f
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/Makefile.am
@@ -0,0 +1,57 @@
+# $Id: Makefile.am,v 1.33 2000/01/06 21:45:41 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += -I../asn1 -I$(srcdir)/../asn1
+
+BUILT_SOURCES = asn1_Key.c asn1_Event.c asn1_HDBFlags.c asn1_hdb_entry.c \
+ asn1_Salt.c hdb_err.c hdb_err.h
+
+foo = asn1_Key.x asn1_Event.x asn1_HDBFlags.x asn1_hdb_entry.x asn1_Salt.x
+
+CLEANFILES = $(BUILT_SOURCES) $(foo) hdb_asn1.h asn1_files
+
+noinst_PROGRAMS = convert_db
+LDADD = libhdb.la \
+ ../krb5/libkrb5.la \
+ ../asn1/libasn1.la \
+ ../des/libdes.la \
+ $(LIB_roken) \
+ $(DBLIB)
+
+lib_LTLIBRARIES = libhdb.la
+libhdb_la_LDFLAGS = -version-info 4:1:1
+
+libhdb_la_SOURCES = \
+ keytab.c \
+ hdb.c \
+ common.c \
+ db.c \
+ ndbm.c \
+ print.c \
+ $(BUILT_SOURCES)
+
+include_HEADERS = hdb.h hdb_err.h hdb_asn1.h hdb-protos.h hdb-private.h
+
+libhdb_la_LIBADD =
+
+$(libhdb_la_OBJECTS): $(srcdir)/hdb-protos.h $(srcdir)/hdb-private.h
+
+$(srcdir)/hdb-protos.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -o hdb-protos.h $(libhdb_la_SOURCES) || rm -f hdb-protos.h
+
+$(srcdir)/hdb-private.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -p hdb-private.h $(libhdb_la_SOURCES) || rm -f hdb-private.h
+
+$(foo) hdb_asn1.h: asn1_files
+
+asn1_files: ../asn1/asn1_compile$(EXEEXT) $(srcdir)/hdb.asn1
+ ../asn1/asn1_compile$(EXEEXT) $(srcdir)/hdb.asn1 hdb_asn1
+
+$(libhdb_la_OBJECTS): hdb_asn1.h hdb_err.h
+
+$(convert_db_OBJECTS): hdb_asn1.h hdb_err.h
+
+# to help stupid solaris make
+
+hdb_err.h: hdb_err.et
diff --git a/crypto/heimdal/lib/hdb/Makefile.in b/crypto/heimdal/lib/hdb/Makefile.in
new file mode 100644
index 000000000000..ef925509766c
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/Makefile.in
@@ -0,0 +1,709 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.33 2000/01/06 21:45:41 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include -I../asn1 -I$(srcdir)/../asn1
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+BUILT_SOURCES = asn1_Key.c asn1_Event.c asn1_HDBFlags.c asn1_hdb_entry.c asn1_Salt.c hdb_err.c hdb_err.h
+
+
+foo = asn1_Key.x asn1_Event.x asn1_HDBFlags.x asn1_hdb_entry.x asn1_Salt.x
+
+CLEANFILES = $(BUILT_SOURCES) $(foo) hdb_asn1.h asn1_files
+
+noinst_PROGRAMS = convert_db
+LDADD = libhdb.la ../krb5/libkrb5.la ../asn1/libasn1.la ../des/libdes.la $(LIB_roken) $(DBLIB)
+
+
+lib_LTLIBRARIES = libhdb.la
+libhdb_la_LDFLAGS = -version-info 4:1:1
+
+libhdb_la_SOURCES = keytab.c hdb.c common.c db.c ndbm.c print.c $(BUILT_SOURCES)
+
+
+include_HEADERS = hdb.h hdb_err.h hdb_asn1.h hdb-protos.h hdb-private.h
+
+libhdb_la_LIBADD =
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libhdb_la_DEPENDENCIES =
+libhdb_la_OBJECTS = keytab.lo hdb.lo common.lo db.lo ndbm.lo print.lo \
+asn1_Key.lo asn1_Event.lo asn1_HDBFlags.lo asn1_hdb_entry.lo \
+asn1_Salt.lo hdb_err.lo
+noinst_PROGRAMS = convert_db$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+convert_db_SOURCES = convert_db.c
+convert_db_OBJECTS = convert_db.$(OBJEXT)
+convert_db_LDADD = $(LDADD)
+convert_db_DEPENDENCIES = libhdb.la ../krb5/libkrb5.la \
+../asn1/libasn1.la ../des/libdes.la
+convert_db_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(include_HEADERS)
+
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libhdb_la_SOURCES) convert_db.c
+OBJECTS = $(libhdb_la_OBJECTS) convert_db.$(OBJEXT)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/hdb/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libhdb.la: $(libhdb_la_OBJECTS) $(libhdb_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libhdb_la_LDFLAGS) $(libhdb_la_OBJECTS) $(libhdb_la_LIBADD) $(LIBS)
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+convert_db$(EXEEXT): $(convert_db_OBJECTS) $(convert_db_DEPENDENCIES)
+ @rm -f convert_db$(EXEEXT)
+ $(LINK) $(convert_db_LDFLAGS) $(convert_db_OBJECTS) $(convert_db_LDADD) $(LIBS)
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/hdb
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-includeHEADERS install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-noinstPROGRAMS \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \
+ clean-noinstPROGRAMS clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-noinstPROGRAMS \
+ distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool mostlyclean-noinstPROGRAMS \
+distclean-noinstPROGRAMS clean-noinstPROGRAMS \
+maintainer-clean-noinstPROGRAMS uninstall-includeHEADERS \
+install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-local install-data-am install-data install-am install \
+uninstall-am uninstall all-local all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+$(libhdb_la_OBJECTS): $(srcdir)/hdb-protos.h $(srcdir)/hdb-private.h
+
+$(srcdir)/hdb-protos.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -o hdb-protos.h $(libhdb_la_SOURCES) || rm -f hdb-protos.h
+
+$(srcdir)/hdb-private.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -p hdb-private.h $(libhdb_la_SOURCES) || rm -f hdb-private.h
+
+$(foo) hdb_asn1.h: asn1_files
+
+asn1_files: ../asn1/asn1_compile$(EXEEXT) $(srcdir)/hdb.asn1
+ ../asn1/asn1_compile$(EXEEXT) $(srcdir)/hdb.asn1 hdb_asn1
+
+$(libhdb_la_OBJECTS): hdb_asn1.h hdb_err.h
+
+$(convert_db_OBJECTS): hdb_asn1.h hdb_err.h
+
+# to help stupid solaris make
+
+hdb_err.h: hdb_err.et
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/hdb/common.c b/crypto/heimdal/lib/hdb/common.c
new file mode 100644
index 000000000000..6e95667359e6
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/common.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "hdb_locl.h"
+
+RCSID("$Id: common.c,v 1.6 1999/12/02 17:05:04 joda Exp $");
+
+int
+hdb_principal2key(krb5_context context, krb5_principal p, krb5_data *key)
+{
+ Principal new;
+ size_t len;
+ unsigned char *buf;
+ int ret;
+
+ ret = copy_Principal(p, &new);
+ if(ret)
+ goto out;
+ new.name.name_type = 0;
+ len = length_Principal(&new);
+ buf = malloc(len);
+ if(buf == NULL){
+ ret = ENOMEM;
+ goto out;
+ }
+ ret = encode_Principal(buf + len - 1, len, &new, &len);
+ if(ret){
+ free(buf);
+ goto out;
+ }
+ key->data = buf;
+ key->length = len;
+out:
+ free_Principal(&new);
+ return ret;
+}
+
+int
+hdb_key2principal(krb5_context context, krb5_data *key, krb5_principal p)
+{
+ return decode_Principal(key->data, key->length, p, NULL);
+}
+
+int
+hdb_entry2value(krb5_context context, hdb_entry *ent, krb5_data *value)
+{
+ unsigned char *buf;
+ size_t len;
+ int ret;
+
+ len = length_hdb_entry(ent);
+ buf = malloc(len);
+ if(buf == NULL)
+ return ENOMEM;
+ ret = encode_hdb_entry(buf + len - 1, len, ent, &len);
+ if(ret){
+ free(buf);
+ return ret;
+ }
+ value->data = buf;
+ value->length = len;
+ return 0;
+}
+
+int
+hdb_value2entry(krb5_context context, krb5_data *value, hdb_entry *ent)
+{
+ return decode_hdb_entry(value->data, value->length, ent, NULL);
+}
+
+krb5_error_code
+_hdb_fetch(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
+{
+ krb5_data key, value;
+ int code;
+
+ hdb_principal2key(context, entry->principal, &key);
+ code = db->_get(context, db, key, &value);
+ krb5_data_free(&key);
+ if(code)
+ return code;
+ hdb_value2entry(context, &value, entry);
+ if (db->master_key_set && (flags & HDB_F_DECRYPT))
+ hdb_unseal_keys (db, entry);
+ krb5_data_free(&value);
+ return 0;
+}
+
+krb5_error_code
+_hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
+{
+ krb5_data key, value;
+ int code;
+
+ hdb_principal2key(context, entry->principal, &key);
+ hdb_seal_keys(db, entry);
+ hdb_entry2value(context, entry, &value);
+ code = db->_put(context, db, flags & HDB_F_REPLACE, key, value);
+ krb5_data_free(&value);
+ krb5_data_free(&key);
+ return code;
+}
+
+krb5_error_code
+_hdb_remove(krb5_context context, HDB *db, hdb_entry *entry)
+{
+ krb5_data key;
+ int code;
+
+ hdb_principal2key(context, entry->principal, &key);
+ code = db->_del(context, db, key);
+ krb5_data_free(&key);
+ return code;
+}
+
diff --git a/crypto/heimdal/lib/hdb/convert_db.c b/crypto/heimdal/lib/hdb/convert_db.c
new file mode 100644
index 000000000000..b25780927959
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/convert_db.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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. */
+
+/* Converts a database from version 0.0* to 0.1. This is done by
+ * making three copies of each DES key (DES-CBC-CRC, DES-CBC-MD4, and
+ * DES-CBC-MD5).
+ *
+ * Use with care.
+ */
+
+#include "hdb_locl.h"
+#include "getarg.h"
+
+RCSID("$Id: convert_db.c,v 1.8 1999/05/09 22:47:47 assar Exp $");
+
+static krb5_error_code
+update_keytypes(krb5_context context, HDB *db, hdb_entry *entry, void *data)
+{
+ int i;
+ int n = 0;
+ Key *k;
+ int save_len;
+ Key *save_val;
+ HDB *new = data;
+ krb5_error_code ret;
+
+ for(i = 0; i < entry->keys.len; i++)
+ if(entry->keys.val[i].key.keytype == KEYTYPE_DES)
+ n += 2;
+ else if(entry->keys.val[i].key.keytype == KEYTYPE_DES3)
+ n += 1;
+ k = malloc(sizeof(*k) * (entry->keys.len + n));
+ n = 0;
+ for(i = 0; i < entry->keys.len; i++) {
+ copy_Key(&entry->keys.val[i], &k[n]);
+ if(entry->keys.val[i].key.keytype == KEYTYPE_DES) {
+ copy_Key(&entry->keys.val[i], &k[n+1]);
+ k[n+1].key.keytype = ETYPE_DES_CBC_MD4;
+ copy_Key(&entry->keys.val[i], &k[n+2]);
+ k[n+2].key.keytype = ETYPE_DES_CBC_MD5;
+ n += 2;
+ }
+ else if(entry->keys.val[i].key.keytype == KEYTYPE_DES3) {
+ copy_Key(&entry->keys.val[i], &k[n+1]);
+ k[n+1].key.keytype = ETYPE_DES3_CBC_MD5;
+ n += 1;
+ }
+ n++;
+ }
+ save_len = entry->keys.len;
+ save_val = entry->keys.val;
+ entry->keys.len = n;
+ entry->keys.val = k;
+ ret = new->store(context, new, HDB_F_REPLACE, entry);
+ entry->keys.len = save_len;
+ entry->keys.val = save_val;
+ for(i = 0; i < n; i++)
+ free_Key(&k[i]);
+ free(k);
+ return 0;
+}
+
+static krb5_error_code
+update_version2(krb5_context context, HDB *db, hdb_entry *entry, void *data)
+{
+ HDB *new = data;
+ if(!db->master_key_set) {
+ int i;
+ for(i = 0; i < entry->keys.len; i++) {
+ free(entry->keys.val[i].mkvno);
+ entry->keys.val[i].mkvno = NULL;
+ }
+ }
+ new->store(context, new, HDB_F_REPLACE, entry);
+ return 0;
+}
+
+char *old_database = HDB_DEFAULT_DB;
+char *new_database = HDB_DEFAULT_DB ".new";
+char *mkeyfile;
+int update_version;
+int help_flag;
+int version_flag;
+
+struct getargs args[] = {
+ { "old-database", 0, arg_string, &old_database,
+ "name of database to convert", "file" },
+ { "new-database", 0, arg_string, &new_database,
+ "name of converted database", "file" },
+ { "master-key", 0, arg_string, &mkeyfile,
+ "v5 master key file", "file" },
+ { "update-version", 0, arg_flag, &update_version,
+ "update the database to the current version" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 0, arg_flag, &version_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ HDB *db, *new;
+ EncryptionKey key;
+ int optind = 0;
+ int master_key_set = 0;
+
+ set_progname(argv[0]);
+
+ if(getarg(args, num_args, argc, argv, &optind))
+ krb5_std_usage(1, args, num_args);
+
+ if(help_flag)
+ krb5_std_usage(0, args, num_args);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ ret = krb5_init_context(&context);
+ if(ret != 0)
+ krb5_err(NULL, 1, ret, "krb5_init_context");
+
+ ret = hdb_create(context, &db, old_database);
+ if(ret != 0)
+ krb5_err(context, 1, ret, "hdb_create");
+
+ ret = hdb_read_master_key(context, mkeyfile, &key);
+ if(ret == 0) {
+ if(key.keytype == KEYTYPE_DES)
+ key.keytype = ETYPE_DES_CBC_MD5;
+
+ ret = hdb_set_master_key(context, db, key);
+ if (ret)
+ krb5_err(context, 1, ret, "hdb_set_master_key");
+ master_key_set = 1;
+ }
+ ret = hdb_create(context, &new, new_database);
+ if(ret != 0)
+ krb5_err(context, 1, ret, "hdb_create");
+ if (master_key_set) {
+ ret = hdb_set_master_key(context, new, key);
+ if (ret)
+ krb5_err(context, 1, ret, "hdb_set_master_key");
+ }
+ ret = db->open(context, db, O_RDONLY, 0);
+ if(ret == HDB_ERR_BADVERSION) {
+ krb5_data tag;
+ krb5_data version;
+ int foo;
+ unsigned ver;
+ tag.data = HDB_DB_FORMAT_ENTRY;
+ tag.length = strlen(tag.data);
+ ret = (*db->_get)(context, db, tag, &version);
+ if(ret)
+ krb5_errx(context, 1, "database is wrong version, "
+ "but couldn't find version key (%s)",
+ HDB_DB_FORMAT_ENTRY);
+ foo = sscanf(version.data, "%u", &ver);
+ krb5_data_free (&version);
+ if(foo != 1)
+ krb5_errx(context, 1, "database version is not a number");
+ if(ver == 1 && HDB_DB_FORMAT == 2) {
+ krb5_warnx(context, "will upgrade database from version %d to %d",
+ ver, HDB_DB_FORMAT);
+ krb5_warnx(context, "rerun to do other conversions");
+ update_version = 1;
+ } else
+ krb5_errx(context, 1,
+ "don't know how to upgrade from version %d to %d",
+ ver, HDB_DB_FORMAT);
+ } else if(ret)
+ krb5_err(context, 1, ret, "%s", old_database);
+ ret = new->open(context, new, O_CREAT|O_EXCL|O_RDWR, 0600);
+ if(ret)
+ krb5_err(context, 1, ret, "%s", new_database);
+ if(update_version)
+ ret = hdb_foreach(context, db, 0, update_version2, new);
+ else
+ ret = hdb_foreach(context, db, 0, update_keytypes, new);
+ if(ret != 0)
+ krb5_err(context, 1, ret, "hdb_foreach");
+ db->close(context, db);
+ new->close(context, new);
+ krb5_warnx(context, "wrote converted database to `%s'", new_database);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/hdb/db.c b/crypto/heimdal/lib/hdb/db.c
new file mode 100644
index 000000000000..46994378da26
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/db.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "hdb_locl.h"
+
+RCSID("$Id: db.c,v 1.25 1999/12/02 17:05:04 joda Exp $");
+
+#ifdef HAVE_DB_H
+
+static krb5_error_code
+DB_close(krb5_context context, HDB *db)
+{
+ DB *d = (DB*)db->db;
+ d->close(d);
+ return 0;
+}
+
+static krb5_error_code
+DB_destroy(krb5_context context, HDB *db)
+{
+ krb5_error_code ret;
+
+ ret = hdb_clear_master_key (context, db);
+ free(db->name);
+ free(db);
+ return ret;
+}
+
+static krb5_error_code
+DB_lock(krb5_context context, HDB *db, int operation)
+{
+ DB *d = (DB*)db->db;
+ int fd = (*d->fd)(d);
+ if(fd < 0)
+ return HDB_ERR_CANT_LOCK_DB;
+ return hdb_lock(fd, operation);
+}
+
+static krb5_error_code
+DB_unlock(krb5_context context, HDB *db)
+{
+ DB *d = (DB*)db->db;
+ int fd = (*d->fd)(d);
+ if(fd < 0)
+ return HDB_ERR_CANT_LOCK_DB;
+ return hdb_unlock(fd);
+}
+
+
+static krb5_error_code
+DB_seq(krb5_context context, HDB *db,
+ unsigned flags, hdb_entry *entry, int flag)
+{
+ DB *d = (DB*)db->db;
+ DBT key, value;
+ krb5_data key_data, data;
+ int code;
+
+ code = db->lock(context, db, HDB_RLOCK);
+ if(code == -1)
+ return HDB_ERR_DB_INUSE;
+ code = d->seq(d, &key, &value, flag);
+ db->unlock(context, db); /* XXX check value */
+ if(code == -1)
+ return errno;
+ if(code == 1)
+ return HDB_ERR_NOENTRY;
+
+ key_data.data = key.data;
+ key_data.length = key.size;
+ data.data = value.data;
+ data.length = value.size;
+ if (hdb_value2entry(context, &data, entry))
+ return DB_seq(context, db, flags, entry, R_NEXT);
+ if (db->master_key_set && (flags & HDB_F_DECRYPT))
+ hdb_unseal_keys (db, entry);
+ if (entry->principal == NULL) {
+ entry->principal = malloc(sizeof(*entry->principal));
+ hdb_key2principal(context, &key_data, entry->principal);
+ }
+ return 0;
+}
+
+
+static krb5_error_code
+DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
+{
+ return DB_seq(context, db, flags, entry, R_FIRST);
+}
+
+
+static krb5_error_code
+DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
+{
+ return DB_seq(context, db, flags, entry, R_NEXT);
+}
+
+static krb5_error_code
+DB_rename(krb5_context context, HDB *db, const char *new_name)
+{
+ int ret;
+ char *old, *new;
+
+ asprintf(&old, "%s.db", db->name);
+ asprintf(&new, "%s.db", new_name);
+ ret = rename(old, new);
+ free(old);
+ free(new);
+ if(ret)
+ return errno;
+
+ free(db->name);
+ db->name = strdup(new_name);
+ return 0;
+}
+
+static krb5_error_code
+DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply)
+{
+ DB *d = (DB*)db->db;
+ DBT k, v;
+ int code;
+
+ k.data = key.data;
+ k.size = key.length;
+ code = db->lock(context, db, HDB_RLOCK);
+ if(code)
+ return code;
+ code = d->get(d, &k, &v, 0);
+ db->unlock(context, db);
+ if(code < 0)
+ return errno;
+ if(code == 1)
+ return HDB_ERR_NOENTRY;
+
+ krb5_data_copy(reply, v.data, v.size);
+ return 0;
+}
+
+static krb5_error_code
+DB__put(krb5_context context, HDB *db, int replace,
+ krb5_data key, krb5_data value)
+{
+ DB *d = (DB*)db->db;
+ DBT k, v;
+ int code;
+
+ k.data = key.data;
+ k.size = key.length;
+ v.data = value.data;
+ v.size = value.length;
+ code = db->lock(context, db, HDB_WLOCK);
+ if(code)
+ return code;
+ code = d->put(d, &k, &v, replace ? 0 : R_NOOVERWRITE);
+ db->unlock(context, db);
+ if(code < 0)
+ return errno;
+ if(code == 1)
+ return HDB_ERR_EXISTS;
+ return 0;
+}
+
+static krb5_error_code
+DB__del(krb5_context context, HDB *db, krb5_data key)
+{
+ DB *d = (DB*)db->db;
+ DBT k;
+ krb5_error_code code;
+ k.data = key.data;
+ k.size = key.length;
+ code = db->lock(context, db, HDB_WLOCK);
+ if(code)
+ return code;
+ code = d->del(d, &k, 0);
+ db->unlock(context, db);
+ if(code == 1)
+ return HDB_ERR_NOENTRY;
+ if(code < 0)
+ return errno;
+ return 0;
+}
+
+static krb5_error_code
+DB_open(krb5_context context, HDB *db, int flags, mode_t mode)
+{
+ char *fn;
+ krb5_error_code ret;
+
+ asprintf(&fn, "%s.db", db->name);
+ if (fn == NULL)
+ return ENOMEM;
+ db->db = dbopen(fn, flags, mode, DB_BTREE, NULL);
+ free(fn);
+ /* try to open without .db extension */
+ if(db->db == NULL && errno == ENOENT)
+ db->db = dbopen(db->name, flags, mode, DB_BTREE, NULL);
+ if(db->db == NULL)
+ return errno;
+ if((flags & O_ACCMODE) == O_RDONLY)
+ ret = hdb_check_db_format(context, db);
+ else
+ ret = hdb_init_db(context, db);
+ if(ret == HDB_ERR_NOENTRY)
+ return 0;
+ return ret;
+}
+
+krb5_error_code
+hdb_db_create(krb5_context context, HDB **db,
+ const char *filename)
+{
+ *db = malloc(sizeof(**db));
+ if (*db == NULL)
+ return ENOMEM;
+
+ (*db)->db = NULL;
+ (*db)->name = strdup(filename);
+ (*db)->master_key_set = 0;
+ (*db)->openp = 0;
+ (*db)->open = DB_open;
+ (*db)->close = DB_close;
+ (*db)->fetch = _hdb_fetch;
+ (*db)->store = _hdb_store;
+ (*db)->remove = _hdb_remove;
+ (*db)->firstkey = DB_firstkey;
+ (*db)->nextkey= DB_nextkey;
+ (*db)->lock = DB_lock;
+ (*db)->unlock = DB_unlock;
+ (*db)->rename = DB_rename;
+ (*db)->_get = DB__get;
+ (*db)->_put = DB__put;
+ (*db)->_del = DB__del;
+ (*db)->destroy = DB_destroy;
+ return 0;
+}
+
+#endif
diff --git a/crypto/heimdal/lib/hdb/hdb-private.h b/crypto/heimdal/lib/hdb/hdb-private.h
new file mode 100644
index 000000000000..ce868bd98098
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/hdb-private.h
@@ -0,0 +1,48 @@
+/* This is a generated file */
+#ifndef __hdb_private_h__
+#define __hdb_private_h__
+
+#ifdef __STDC__
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+krb5_error_code
+_hdb_fetch __P((
+ krb5_context context,
+ HDB *db,
+ unsigned flags,
+ hdb_entry *entry));
+
+krb5_error_code
+_hdb_remove __P((
+ krb5_context context,
+ HDB *db,
+ hdb_entry *entry));
+
+void
+_hdb_seal_keys_int __P((
+ hdb_entry *ent,
+ int key_version,
+ krb5_data schedule));
+
+krb5_error_code
+_hdb_store __P((
+ krb5_context context,
+ HDB *db,
+ unsigned flags,
+ hdb_entry *entry));
+
+void
+_hdb_unseal_keys_int __P((
+ hdb_entry *ent,
+ int key_version,
+ krb5_data schedule));
+
+#endif /* __hdb_private_h__ */
diff --git a/crypto/heimdal/lib/hdb/hdb-protos.h b/crypto/heimdal/lib/hdb/hdb-protos.h
new file mode 100644
index 000000000000..e0f15b1dde46
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/hdb-protos.h
@@ -0,0 +1,158 @@
+/* This is a generated file */
+#ifndef __hdb_protos_h__
+#define __hdb_protos_h__
+
+#ifdef __STDC__
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+krb5_error_code
+hdb_check_db_format __P((
+ krb5_context context,
+ HDB *db));
+
+krb5_error_code
+hdb_clear_master_key __P((
+ krb5_context context,
+ HDB *db));
+
+krb5_error_code
+hdb_create __P((
+ krb5_context context,
+ HDB **db,
+ const char *filename));
+
+krb5_error_code
+hdb_db_create __P((
+ krb5_context context,
+ HDB **db,
+ const char *filename));
+
+krb5_error_code
+hdb_enctype2key __P((
+ krb5_context context,
+ hdb_entry *e,
+ krb5_enctype enctype,
+ Key **key));
+
+krb5_error_code
+hdb_entry2string __P((
+ krb5_context context,
+ hdb_entry *ent,
+ char **str));
+
+int
+hdb_entry2value __P((
+ krb5_context context,
+ hdb_entry *ent,
+ krb5_data *value));
+
+krb5_error_code
+hdb_foreach __P((
+ krb5_context context,
+ HDB *db,
+ unsigned flags,
+ hdb_foreach_func_t func,
+ void *data));
+
+void
+hdb_free_entry __P((
+ krb5_context context,
+ hdb_entry *ent));
+
+void
+hdb_free_key __P((Key *key));
+
+krb5_error_code
+hdb_init_db __P((
+ krb5_context context,
+ HDB *db));
+
+int
+hdb_key2principal __P((
+ krb5_context context,
+ krb5_data *key,
+ krb5_principal p));
+
+krb5_error_code
+hdb_lock __P((
+ int fd,
+ int operation));
+
+krb5_error_code
+hdb_ndbm_create __P((
+ krb5_context context,
+ HDB **db,
+ const char *filename));
+
+krb5_error_code
+hdb_next_enctype2key __P((
+ krb5_context context,
+ hdb_entry *e,
+ krb5_enctype enctype,
+ Key **key));
+
+int
+hdb_principal2key __P((
+ krb5_context context,
+ krb5_principal p,
+ krb5_data *key));
+
+krb5_error_code
+hdb_print_entry __P((
+ krb5_context context,
+ HDB *db,
+ hdb_entry *entry,
+ void *data));
+
+krb5_error_code
+hdb_process_master_key __P((
+ krb5_context context,
+ EncryptionKey key,
+ krb5_data *schedule));
+
+krb5_error_code
+hdb_read_master_key __P((
+ krb5_context context,
+ const char *filename,
+ EncryptionKey *key));
+
+void
+hdb_seal_keys __P((
+ HDB *db,
+ hdb_entry *ent));
+
+krb5_error_code
+hdb_set_master_key __P((
+ krb5_context context,
+ HDB *db,
+ EncryptionKey key));
+
+krb5_error_code
+hdb_set_master_keyfile __P((
+ krb5_context context,
+ HDB *db,
+ const char *keyfile));
+
+krb5_error_code
+hdb_unlock __P((int fd));
+
+void
+hdb_unseal_keys __P((
+ HDB *db,
+ hdb_entry *ent));
+
+int
+hdb_value2entry __P((
+ krb5_context context,
+ krb5_data *value,
+ hdb_entry *ent));
+
+#endif /* __hdb_protos_h__ */
diff --git a/crypto/heimdal/lib/hdb/hdb.asn1 b/crypto/heimdal/lib/hdb/hdb.asn1
new file mode 100644
index 000000000000..99537d6ded1c
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/hdb.asn1
@@ -0,0 +1,65 @@
+-- $Id: hdb.asn1,v 1.7 1999/05/03 16:48:52 joda Exp $
+HDB DEFINITIONS ::=
+BEGIN
+
+EncryptionKey EXTERNAL
+KerberosTime EXTERNAL
+Principal EXTERNAL
+
+HDB_DB_FORMAT INTEGER ::= 2 -- format of database,
+ -- update when making changes
+
+-- these should have the same value as the pa-* counterparts
+hdb-pw-salt INTEGER ::= 3
+hdb-afs3-salt INTEGER ::= 10
+
+Salt ::= SEQUENCE {
+ type[0] INTEGER,
+ salt[1] OCTET STRING
+}
+
+Key ::= SEQUENCE {
+ mkvno[0] INTEGER OPTIONAL, -- master key version number
+ key[1] EncryptionKey,
+ salt[2] Salt OPTIONAL
+}
+
+Event ::= SEQUENCE {
+ time[0] KerberosTime,
+ principal[1] Principal OPTIONAL
+}
+
+HDBFlags ::= BIT STRING {
+ initial(0), -- require as-req
+ forwardable(1), -- may issue forwardable
+ proxiable(2), -- may issue proxiable
+ renewable(3), -- may issue renewable
+ postdate(4), -- may issue postdatable
+ server(5), -- may be server
+ client(6), -- may be client
+ invalid(7), -- entry is invalid
+ require-preauth(8), -- must use preauth
+ change-pw(9), -- change password service
+ require-hwauth(10), -- must use hwauth
+ ok-as-delegate(11), -- as in TicketFlags
+ user-to-user(12), -- may use user-to-user auth
+ immutable(13) -- may not be deleted
+}
+
+hdb_entry ::= SEQUENCE {
+ principal[0] Principal OPTIONAL, -- this is optional only
+ -- for compatibility with libkrb5
+ kvno[1] INTEGER,
+ keys[2] SEQUENCE OF Key,
+ created-by[3] Event,
+ modified-by[4] Event OPTIONAL,
+ valid-start[5] KerberosTime OPTIONAL,
+ valid-end[6] KerberosTime OPTIONAL,
+ pw-end[7] KerberosTime OPTIONAL,
+ max-life[8] INTEGER OPTIONAL,
+ max-renew[9] INTEGER OPTIONAL,
+ flags[10] HDBFlags,
+ etypes[11] SEQUENCE OF INTEGER OPTIONAL
+}
+
+END
diff --git a/crypto/heimdal/lib/hdb/hdb.c b/crypto/heimdal/lib/hdb/hdb.c
new file mode 100644
index 000000000000..edf6677e6041
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/hdb.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "hdb_locl.h"
+
+RCSID("$Id: hdb.c,v 1.35 1999/12/02 17:05:05 joda Exp $");
+
+krb5_error_code
+hdb_next_enctype2key(krb5_context context,
+ hdb_entry *e,
+ krb5_enctype enctype,
+ Key **key)
+{
+ Key *k;
+
+ for (k = *key ? *key : e->keys.val;
+ k < e->keys.val + e->keys.len;
+ k++)
+ if(k->key.keytype == enctype){
+ *key = k;
+ return 0;
+ }
+ return KRB5_PROG_ETYPE_NOSUPP; /* XXX */
+}
+
+krb5_error_code
+hdb_enctype2key(krb5_context context,
+ hdb_entry *e,
+ krb5_enctype enctype,
+ Key **key)
+{
+ *key = NULL;
+ return hdb_next_enctype2key(context, e, enctype, key);
+}
+
+/* this is a bit ugly, but will get better when the crypto framework
+ gets fixed */
+
+krb5_error_code
+hdb_process_master_key(krb5_context context, EncryptionKey key,
+ krb5_data *schedule)
+{
+ krb5_error_code ret;
+
+ if(key.keytype != ETYPE_DES_CBC_MD5)
+ return KRB5_PROG_KEYTYPE_NOSUPP;
+
+ ret = krb5_data_alloc (schedule, sizeof(des_key_schedule));
+ if (ret)
+ return ret;
+
+ des_set_key((des_cblock*)key.keyvalue.data, schedule->data);
+ return 0;
+}
+
+krb5_error_code
+hdb_read_master_key(krb5_context context, const char *filename,
+ EncryptionKey *key)
+{
+ FILE *f;
+ unsigned char buf[256];
+ size_t len;
+ krb5_error_code ret;
+ if(filename == NULL)
+ filename = HDB_DB_DIR "/m-key";
+ f = fopen(filename, "r");
+ if(f == NULL)
+ return errno;
+ len = fread(buf, 1, sizeof(buf), f);
+ if(ferror(f))
+ ret = errno;
+ else
+ ret = decode_EncryptionKey(buf, len, key, &len);
+ fclose(f);
+ memset(buf, 0, sizeof(buf));
+ return ret;
+}
+
+void
+_hdb_unseal_keys_int(hdb_entry *ent, int key_version, krb5_data schedule)
+{
+ int i;
+ for(i = 0; i < ent->keys.len; i++){
+ des_cblock iv;
+ int num = 0;
+ if(ent->keys.val[i].mkvno == NULL)
+ continue;
+ if(*ent->keys.val[i].mkvno != key_version)
+ ;
+ memset(&iv, 0, sizeof(iv));
+
+ des_cfb64_encrypt(ent->keys.val[i].key.keyvalue.data,
+ ent->keys.val[i].key.keyvalue.data,
+ ent->keys.val[i].key.keyvalue.length,
+ schedule.data, &iv, &num, 0);
+ free(ent->keys.val[i].mkvno);
+ ent->keys.val[i].mkvno = NULL;
+ }
+}
+
+void
+hdb_unseal_keys(HDB *db, hdb_entry *ent)
+{
+ if (db->master_key_set == 0)
+ return;
+ _hdb_unseal_keys_int(ent, db->master_key_version, db->master_key);
+}
+
+void
+_hdb_seal_keys_int(hdb_entry *ent, int key_version, krb5_data schedule)
+{
+ int i;
+ for(i = 0; i < ent->keys.len; i++){
+ des_cblock iv;
+ int num = 0;
+
+ if(ent->keys.val[i].mkvno != NULL)
+ continue;
+ memset(&iv, 0, sizeof(iv));
+ des_cfb64_encrypt(ent->keys.val[i].key.keyvalue.data,
+ ent->keys.val[i].key.keyvalue.data,
+ ent->keys.val[i].key.keyvalue.length,
+ schedule.data, &iv, &num, 1);
+ ent->keys.val[i].mkvno = malloc(sizeof(*ent->keys.val[i].mkvno));
+ *ent->keys.val[i].mkvno = key_version;
+ }
+}
+
+void
+hdb_seal_keys(HDB *db, hdb_entry *ent)
+{
+ if (db->master_key_set == 0)
+ return;
+
+ _hdb_seal_keys_int(ent, db->master_key_version, db->master_key);
+}
+
+void
+hdb_free_key(Key *key)
+{
+ memset(key->key.keyvalue.data,
+ 0,
+ key->key.keyvalue.length);
+ free_Key(key);
+ free(key);
+}
+
+
+krb5_error_code
+hdb_lock(int fd, int operation)
+{
+ int i, code;
+ for(i = 0; i < 3; i++){
+ code = flock(fd, (operation == HDB_RLOCK ? LOCK_SH : LOCK_EX) | LOCK_NB);
+ if(code == 0 || errno != EWOULDBLOCK)
+ break;
+ sleep(1);
+ }
+ if(code == 0)
+ return 0;
+ if(errno == EWOULDBLOCK)
+ return HDB_ERR_DB_INUSE;
+ return HDB_ERR_CANT_LOCK_DB;
+}
+
+krb5_error_code
+hdb_unlock(int fd)
+{
+ int code;
+ code = flock(fd, LOCK_UN);
+ if(code)
+ return 4711 /* XXX */;
+ return 0;
+}
+
+void
+hdb_free_entry(krb5_context context, hdb_entry *ent)
+{
+ int i;
+
+ for(i = 0; i < ent->keys.len; ++i) {
+ Key *k = &ent->keys.val[i];
+
+ memset (k->key.keyvalue.data, 0, k->key.keyvalue.length);
+ }
+ free_hdb_entry(ent);
+}
+
+krb5_error_code
+hdb_foreach(krb5_context context,
+ HDB *db,
+ unsigned flags,
+ hdb_foreach_func_t func,
+ void *data)
+{
+ krb5_error_code ret;
+ hdb_entry entry;
+ ret = db->firstkey(context, db, flags, &entry);
+ while(ret == 0){
+ ret = (*func)(context, db, &entry, data);
+ hdb_free_entry(context, &entry);
+ if(ret == 0)
+ ret = db->nextkey(context, db, flags, &entry);
+ }
+ if(ret == HDB_ERR_NOENTRY)
+ ret = 0;
+ return ret;
+}
+
+krb5_error_code
+hdb_check_db_format(krb5_context context, HDB *db)
+{
+ krb5_data tag;
+ krb5_data version;
+ krb5_error_code ret;
+ unsigned ver;
+ int foo;
+
+ tag.data = HDB_DB_FORMAT_ENTRY;
+ tag.length = strlen(tag.data);
+ ret = (*db->_get)(context, db, tag, &version);
+ if(ret)
+ return ret;
+ foo = sscanf(version.data, "%u", &ver);
+ krb5_data_free (&version);
+ if (foo != 1)
+ return HDB_ERR_BADVERSION;
+ if(ver != HDB_DB_FORMAT)
+ return HDB_ERR_BADVERSION;
+ return 0;
+}
+
+krb5_error_code
+hdb_init_db(krb5_context context, HDB *db)
+{
+ krb5_error_code ret;
+ krb5_data tag;
+ krb5_data version;
+ char ver[32];
+
+ ret = hdb_check_db_format(context, db);
+ if(ret != HDB_ERR_NOENTRY)
+ return ret;
+
+ tag.data = HDB_DB_FORMAT_ENTRY;
+ tag.length = strlen(tag.data);
+ snprintf(ver, sizeof(ver), "%u", HDB_DB_FORMAT);
+ version.data = ver;
+ version.length = strlen(version.data) + 1; /* zero terminated */
+ ret = (*db->_put)(context, db, 0, tag, version);
+ return ret;
+}
+
+krb5_error_code
+hdb_create(krb5_context context, HDB **db, const char *filename)
+{
+ krb5_error_code ret = 0;
+ if(filename == NULL)
+ filename = HDB_DEFAULT_DB;
+ initialize_hdb_error_table_r(&context->et_list);
+#ifdef HAVE_DB_H
+ ret = hdb_db_create(context, db, filename);
+#elif HAVE_NDBM_H
+ ret = hdb_ndbm_create(context, db, filename);
+#else
+ krb5_errx(context, 1, "No database support! (hdb_create)");
+#endif
+ return ret;
+}
+
+krb5_error_code
+hdb_set_master_key (krb5_context context,
+ HDB *db,
+ EncryptionKey key)
+{
+ krb5_error_code ret;
+
+ ret = hdb_process_master_key(context, key, &db->master_key);
+ if (ret)
+ return ret;
+#if 0 /* XXX - why? */
+ des_set_random_generator_seed(key.keyvalue.data);
+#endif
+ db->master_key_set = 1;
+ db->master_key_version = 0; /* XXX */
+ return 0;
+}
+
+krb5_error_code
+hdb_set_master_keyfile (krb5_context context,
+ HDB *db,
+ const char *keyfile)
+{
+ EncryptionKey key;
+ krb5_error_code ret;
+
+ ret = hdb_read_master_key(context, keyfile, &key);
+ if (ret) {
+ if (ret != ENOENT)
+ return ret;
+ return 0;
+ }
+ ret = hdb_set_master_key(context, db, key);
+ memset(key.keyvalue.data, 0, key.keyvalue.length);
+ free_EncryptionKey(&key);
+ return ret;
+}
+
+krb5_error_code
+hdb_clear_master_key (krb5_context context,
+ HDB *db)
+{
+ if (db->master_key_set) {
+ memset(db->master_key.data, 0, db->master_key.length);
+ krb5_data_free(&db->master_key);
+ db->master_key_set = 0;
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/hdb/hdb.h b/crypto/heimdal/lib/hdb/hdb.h
new file mode 100644
index 000000000000..f4cb001da819
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/hdb.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: hdb.h,v 1.26 1999/12/02 17:05:05 joda Exp $ */
+
+#ifndef __HDB_H__
+#define __HDB_H__
+
+#include <hdb_err.h>
+
+#include <hdb_asn1.h>
+
+enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
+
+/* flags for various functions */
+#define HDB_F_DECRYPT 1 /* decrypt keys */
+#define HDB_F_REPLACE 2 /* replace entry */
+
+typedef struct HDB{
+ void *db;
+ char *name;
+ int master_key_set;
+ krb5_data master_key;
+ int master_key_version;
+ int openp;
+
+ krb5_error_code (*open)(krb5_context, struct HDB*, int, mode_t);
+ krb5_error_code (*close)(krb5_context, struct HDB*);
+ krb5_error_code (*fetch)(krb5_context, struct HDB*, unsigned, hdb_entry*);
+ krb5_error_code (*store)(krb5_context, struct HDB*, unsigned, hdb_entry*);
+ krb5_error_code (*remove)(krb5_context, struct HDB*, hdb_entry*);
+ krb5_error_code (*firstkey)(krb5_context, struct HDB*,
+ unsigned, hdb_entry*);
+ krb5_error_code (*nextkey)(krb5_context, struct HDB*,
+ unsigned, hdb_entry*);
+ krb5_error_code (*lock)(krb5_context, struct HDB*, int operation);
+ krb5_error_code (*unlock)(krb5_context, struct HDB*);
+ krb5_error_code (*rename)(krb5_context, struct HDB*, const char*);
+ krb5_error_code (*_get)(krb5_context, struct HDB*, krb5_data, krb5_data*);
+ krb5_error_code (*_put)(krb5_context, struct HDB*, int,
+ krb5_data, krb5_data);
+ krb5_error_code (*_del)(krb5_context, struct HDB*, krb5_data);
+ krb5_error_code (*destroy)(krb5_context, struct HDB*);
+}HDB;
+
+#define HDB_DB_DIR "/var/heimdal"
+#define HDB_DEFAULT_DB HDB_DB_DIR "/heimdal"
+#define HDB_DB_FORMAT_ENTRY "hdb/db-format"
+
+typedef krb5_error_code (*hdb_foreach_func_t)(krb5_context, HDB*,
+ hdb_entry*, void*);
+extern krb5_kt_ops hdb_kt_ops;
+
+#include <hdb-protos.h>
+
+#endif /* __HDB_H__ */
diff --git a/crypto/heimdal/lib/hdb/hdb_err.et b/crypto/heimdal/lib/hdb/hdb_err.et
new file mode 100644
index 000000000000..a08a2d4b4f2e
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/hdb_err.et
@@ -0,0 +1,26 @@
+#
+# Error messages for the hdb library
+#
+# This might look like a com_err file, but is not
+#
+id "$Id: hdb_err.et,v 1.4 1998/02/16 16:29:15 joda Exp $"
+
+error_table hdb
+
+prefix HDB_ERR
+
+index 1
+#error_code INUSE, "Entry already exists in database"
+error_code UK_SERROR, "Database store error"
+error_code UK_RERROR, "Database read error"
+error_code NOENTRY, "No such entry in the database"
+error_code DB_INUSE, "Database is locked or in use--try again later"
+error_code DB_CHANGED, "Database was modified during read"
+error_code RECURSIVELOCK, "Attempt to lock database twice"
+error_code NOTLOCKED, "Attempt to unlock database when not locked"
+error_code BADLOCKMODE, "Invalid kdb lock mode"
+error_code CANT_LOCK_DB, "Insufficient access to lock database"
+error_code EXISTS, "Entry already exists in database"
+error_code BADVERSION, "Wrong database version"
+
+end
diff --git a/crypto/heimdal/lib/hdb/hdb_locl.h b/crypto/heimdal/lib/hdb/hdb_locl.h
new file mode 100644
index 000000000000..76ba4796e6ce
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/hdb_locl.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: hdb_locl.h,v 1.12 1999/12/02 17:05:05 joda Exp $ */
+
+#ifndef __HDB_LOCL_H__
+#define __HDB_LOCL_H__
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#include <roken.h>
+
+#include <krb5.h>
+#include <hdb.h>
+#include <hdb-private.h>
+
+#if defined(HAVE_DB_185_H)
+#include <db_185.h>
+#elif defined(HAVE_DB_H)
+#include <db.h>
+#endif
+
+#ifdef HAVE_NDBM_H
+#include <ndbm.h>
+#endif
+
+int hdb_principal2key(krb5_context, krb5_principal, krb5_data*);
+int hdb_key2principal(krb5_context, krb5_data*, krb5_principal);
+
+krb5_error_code hdb_lock(int, int);
+krb5_error_code hdb_unlock(int);
+
+krb5_error_code _hdb_fetch(krb5_context, HDB*, unsigned, hdb_entry*);
+krb5_error_code _hdb_store(krb5_context, HDB*, unsigned, hdb_entry*);
+krb5_error_code _hdb_remove(krb5_context, HDB*, hdb_entry*);
+
+#endif /* __HDB_LOCL_H__ */
diff --git a/crypto/heimdal/lib/hdb/keytab.c b/crypto/heimdal/lib/hdb/keytab.c
new file mode 100644
index 000000000000..d9be75d34be6
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/keytab.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "hdb_locl.h"
+
+/* keytab backend for HDB databases */
+
+RCSID("$Id: keytab.c,v 1.2 1999/08/26 13:24:05 joda Exp $");
+
+struct hdb_data {
+ char *dbname;
+ char *mkey;
+ HDB *db;
+};
+
+static krb5_error_code
+hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
+{
+ krb5_error_code ret;
+ struct hdb_data *d;
+ const char *db, *mkey;
+ d = malloc(sizeof(*d));
+ if(d == NULL)
+ return ENOMEM;
+ db = name;
+ mkey = strchr(name, ':');
+ if(mkey == NULL || mkey[1] == '\0') {
+ if(*name == '\0')
+ d->dbname = NULL;
+ else {
+ d->dbname = strdup(name);
+ if(d->dbname == NULL) {
+ free(d);
+ return ENOMEM;
+ }
+ }
+ d->mkey = NULL;
+ } else {
+ if((mkey - db) == 0) {
+ d->dbname = NULL;
+ } else {
+ d->dbname = malloc(mkey - db);
+ if(d->dbname == NULL) {
+ free(d);
+ return ENOMEM;
+ }
+ strncpy(d->dbname, db, mkey - db);
+ d->dbname[mkey - db] = '\0';
+ }
+ d->mkey = strdup(mkey + 1);
+ if(d->mkey == NULL) {
+ free(d->dbname);
+ free(d);
+ return ENOMEM;
+ }
+ }
+ ret = hdb_create(context, &d->db, d->dbname);
+ if(ret) {
+ free(d->dbname);
+ free(d->mkey);
+ free(d);
+ return ret;
+ }
+ ret = hdb_set_master_keyfile (context, d->db, d->mkey);
+ if(ret) {
+ (*d->db->destroy)(context, d->db);
+ free(d->dbname);
+ free(d->mkey);
+ free(d);
+ return ret;
+ }
+ id->data = d;
+ return 0;
+}
+
+static krb5_error_code
+hdb_close(krb5_context context, krb5_keytab id)
+{
+ struct hdb_data *d = id->data;
+ (*d->db->destroy)(context, d->db);
+ free(d);
+ return 0;
+}
+
+static krb5_error_code
+hdb_get_name(krb5_context context,
+ krb5_keytab id,
+ char *name,
+ size_t namesize)
+{
+ struct hdb_data *d = id->data;
+ snprintf(name, namesize, "%s%s%s",
+ d->dbname ? d->dbname : "",
+ (d->dbname || d->mkey) ? ":" : "",
+ d->mkey ? d->mkey : "");
+ return 0;
+}
+
+static krb5_error_code
+hdb_get_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_const_principal principal,
+ krb5_kvno kvno,
+ krb5_enctype enctype,
+ krb5_keytab_entry *entry)
+{
+ hdb_entry ent;
+ krb5_error_code ret;
+ struct hdb_data *d = id->data;
+ int i;
+
+ ret = (*d->db->open)(context, d->db, O_RDONLY, 0);
+ if (ret)
+ return ret;
+ ent.principal = (krb5_principal)principal;
+ ret = (*d->db->fetch)(context, d->db, HDB_F_DECRYPT, &ent);
+ (*d->db->close)(context, d->db);
+ if(ret == HDB_ERR_NOENTRY)
+ return KRB5_KT_NOTFOUND;
+ else if(ret)
+ return ret;
+ if(kvno && ent.kvno != kvno) {
+ hdb_free_entry(context, &ent);
+ return KRB5_KT_NOTFOUND;
+ }
+ if(enctype == 0)
+ if(ent.keys.len > 0)
+ enctype = ent.keys.val[0].key.keytype;
+ ret = KRB5_KT_NOTFOUND;
+ for(i = 0; i < ent.keys.len; i++) {
+ if(ent.keys.val[i].key.keytype == enctype) {
+ krb5_copy_principal(context, principal, &entry->principal);
+ entry->vno = ent.kvno;
+ krb5_copy_keyblock_contents(context,
+ &ent.keys.val[i].key,
+ &entry->keyblock);
+ ret = 0;
+ break;
+ }
+ }
+ hdb_free_entry(context, &ent);
+ return ret;
+}
+
+krb5_kt_ops hdb_kt_ops = {
+ "HDB",
+ hdb_resolve,
+ hdb_get_name,
+ hdb_close,
+ hdb_get_entry,
+ NULL, /* start_seq_get */
+ NULL, /* next_entry */
+ NULL, /* end_seq_get */
+ NULL, /* add */
+ NULL /* remove */
+};
+
diff --git a/crypto/heimdal/lib/hdb/libasn1.h b/crypto/heimdal/lib/hdb/libasn1.h
new file mode 100644
index 000000000000..03d951ae411b
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/libasn1.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: libasn1.h,v 1.4 1999/12/02 17:05:05 joda Exp $ */
+
+#ifndef __LIBASN1_H__
+#define __LIBASN1_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include <asn1.h>
+#include <der.h>
+#include "hdb_asn1.h"
+#include <asn1_err.h>
+#include <parse_units.h>
+
+#endif /* __LIBASN1_H__ */
diff --git a/crypto/heimdal/lib/hdb/ndbm.c b/crypto/heimdal/lib/hdb/ndbm.c
new file mode 100644
index 000000000000..79ca978e74bb
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/ndbm.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "hdb_locl.h"
+
+RCSID("$Id: ndbm.c,v 1.26 1999/12/02 17:05:05 joda Exp $");
+
+#ifdef HAVE_NDBM_H
+
+struct ndbm_db {
+ DBM *db;
+ int lock_fd;
+};
+
+static krb5_error_code
+NDBM_destroy(krb5_context context, HDB *db)
+{
+ krb5_error_code ret;
+
+ ret = hdb_clear_master_key (context, db);
+ free(db->name);
+ free(db);
+ return 0;
+}
+
+static krb5_error_code
+NDBM_lock(krb5_context context, HDB *db, int operation)
+{
+ struct ndbm_db *d = db->db;
+ return hdb_lock(d->lock_fd, operation);
+}
+
+static krb5_error_code
+NDBM_unlock(krb5_context context, HDB *db)
+{
+ struct ndbm_db *d = db->db;
+ return hdb_unlock(d->lock_fd);
+}
+
+static krb5_error_code
+NDBM_seq(krb5_context context, HDB *db,
+ unsigned flags, hdb_entry *entry, int first)
+
+{
+ struct ndbm_db *d = (struct ndbm_db *)db->db;
+ datum key, value;
+ krb5_data key_data, data;
+ krb5_error_code ret;
+
+ if(first)
+ key = dbm_firstkey(d->db);
+ else
+ key = dbm_nextkey(d->db);
+ if(key.dptr == NULL)
+ return HDB_ERR_NOENTRY;
+ key_data.data = key.dptr;
+ key_data.length = key.dsize;
+ ret = db->lock(context, db, HDB_RLOCK);
+ if(ret) return ret;
+ value = dbm_fetch(d->db, key);
+ db->unlock(context, db);
+ data.data = value.dptr;
+ data.length = value.dsize;
+ if(hdb_value2entry(context, &data, entry))
+ return NDBM_seq(context, db, flags, entry, 0);
+ if (db->master_key_set && (flags & HDB_F_DECRYPT))
+ hdb_unseal_keys (db, entry);
+ if (entry->principal == NULL) {
+ entry->principal = malloc (sizeof(*entry->principal));
+ hdb_key2principal (context, &key_data, entry->principal);
+ }
+ return 0;
+}
+
+
+static krb5_error_code
+NDBM_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
+{
+ return NDBM_seq(context, db, flags, entry, 1);
+}
+
+
+static krb5_error_code
+NDBM_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
+{
+ return NDBM_seq(context, db, flags, entry, 0);
+}
+
+static krb5_error_code
+NDBM_rename(krb5_context context, HDB *db, const char *new_name)
+{
+ /* XXX this function will break */
+ struct ndbm_db *d = db->db;
+
+ int ret;
+ char *old_dir, *old_pag, *new_dir, *new_pag;
+ char *new_lock;
+ int lock_fd;
+
+ /* lock old and new databases */
+ ret = db->lock(context, db, HDB_WLOCK);
+ if(ret) return ret;
+ asprintf(&new_lock, "%s.lock", new_name);
+ lock_fd = open(new_lock, O_RDWR | O_CREAT, 0600);
+ free(new_lock);
+ if(lock_fd < 0) {
+ ret = errno;
+ db->unlock(context, db);
+ return ret;
+ }
+ ret = hdb_lock(lock_fd, HDB_WLOCK);
+ if(ret) {
+ db->unlock(context, db);
+ close(lock_fd);
+ return ret;
+ }
+
+ asprintf(&old_dir, "%s.dir", db->name);
+ asprintf(&old_pag, "%s.pag", db->name);
+ asprintf(&new_dir, "%s.dir", new_name);
+ asprintf(&new_pag, "%s.pag", new_name);
+
+ ret = rename(old_dir, new_dir) || rename(old_pag, new_pag);
+ free(old_dir);
+ free(old_pag);
+ free(new_dir);
+ free(new_pag);
+ hdb_unlock(lock_fd);
+ db->unlock(context, db);
+
+ if(ret) {
+ close(lock_fd);
+ return errno;
+ }
+
+ close(d->lock_fd);
+ d->lock_fd = lock_fd;
+
+ free(db->name);
+ db->name = strdup(new_name);
+ return 0;
+}
+
+static krb5_error_code
+NDBM__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply)
+{
+ struct ndbm_db *d = (struct ndbm_db *)db->db;
+ datum k, v;
+ int code;
+
+ k.dptr = key.data;
+ k.dsize = key.length;
+ code = db->lock(context, db, HDB_RLOCK);
+ if(code)
+ return code;
+ v = dbm_fetch(d->db, k);
+ db->unlock(context, db);
+ if(v.dptr == NULL)
+ return HDB_ERR_NOENTRY;
+
+ krb5_data_copy(reply, v.dptr, v.dsize);
+ return 0;
+}
+
+static krb5_error_code
+NDBM__put(krb5_context context, HDB *db, int replace,
+ krb5_data key, krb5_data value)
+{
+ struct ndbm_db *d = (struct ndbm_db *)db->db;
+ datum k, v;
+ int code;
+
+ k.dptr = key.data;
+ k.dsize = key.length;
+ v.dptr = value.data;
+ v.dsize = value.length;
+
+ code = db->lock(context, db, HDB_WLOCK);
+ if(code)
+ return code;
+ code = dbm_store(d->db, k, v, replace ? DBM_REPLACE : DBM_INSERT);
+ db->unlock(context, db);
+ if(code == 1)
+ return HDB_ERR_EXISTS;
+ if (code < 0)
+ return code;
+ return 0;
+}
+
+static krb5_error_code
+NDBM__del(krb5_context context, HDB *db, krb5_data key)
+{
+ struct ndbm_db *d = (struct ndbm_db *)db->db;
+ datum k;
+ int code;
+ krb5_error_code ret;
+
+ k.dptr = key.data;
+ k.dsize = key.length;
+ ret = db->lock(context, db, HDB_WLOCK);
+ if(ret) return ret;
+ code = dbm_delete(d->db, k);
+ db->unlock(context, db);
+ if(code < 0)
+ return errno;
+ return 0;
+}
+
+static krb5_error_code
+NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode)
+{
+ krb5_error_code ret;
+ struct ndbm_db *d = malloc(sizeof(*d));
+ char *lock_file;
+
+ if(d == NULL)
+ return ENOMEM;
+ asprintf(&lock_file, "%s.lock", (char*)db->name);
+ if(lock_file == NULL) {
+ free(d);
+ return ENOMEM;
+ }
+ d->db = dbm_open((char*)db->name, flags, mode);
+ if(d->db == NULL){
+ free(d);
+ free(lock_file);
+ return errno;
+ }
+ d->lock_fd = open(lock_file, O_RDWR | O_CREAT, 0600);
+ free(lock_file);
+ if(d->lock_fd < 0){
+ dbm_close(d->db);
+ free(d);
+ return errno;
+ }
+ db->db = d;
+ if((flags & O_ACCMODE) == O_RDONLY)
+ ret = hdb_check_db_format(context, db);
+ else
+ ret = hdb_init_db(context, db);
+ if(ret == HDB_ERR_NOENTRY)
+ return 0;
+ return ret;
+}
+
+static krb5_error_code
+NDBM_close(krb5_context context, HDB *db)
+{
+ struct ndbm_db *d = db->db;
+ dbm_close(d->db);
+ close(d->lock_fd);
+ free(d);
+ return 0;
+}
+
+krb5_error_code
+hdb_ndbm_create(krb5_context context, HDB **db,
+ const char *filename)
+{
+ *db = malloc(sizeof(**db));
+ if (*db == NULL)
+ return ENOMEM;
+
+ (*db)->db = NULL;
+ (*db)->name = strdup(filename);
+ (*db)->master_key_set = 0;
+ (*db)->openp = 0;
+ (*db)->open = NDBM_open;
+ (*db)->close = NDBM_close;
+ (*db)->fetch = _hdb_fetch;
+ (*db)->store = _hdb_store;
+ (*db)->remove = _hdb_remove;
+ (*db)->firstkey = NDBM_firstkey;
+ (*db)->nextkey= NDBM_nextkey;
+ (*db)->lock = NDBM_lock;
+ (*db)->unlock = NDBM_unlock;
+ (*db)->rename = NDBM_rename;
+ (*db)->_get = NDBM__get;
+ (*db)->_put = NDBM__put;
+ (*db)->_del = NDBM__del;
+ (*db)->destroy = NDBM_destroy;
+ return 0;
+}
+
+
+#endif
diff --git a/crypto/heimdal/lib/hdb/print.c b/crypto/heimdal/lib/hdb/print.c
new file mode 100644
index 000000000000..5db316618cf9
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/print.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "hdb_locl.h"
+#include <ctype.h>
+
+RCSID("$Id: print.c,v 1.4 1999/12/26 13:50:22 assar Exp $");
+
+/*
+ This is the present contents of a dump line. This might change at
+ any time. Fields are separated by white space.
+
+ principal
+ keyblock
+ kvno
+ keys...
+ mkvno
+ enctype
+ keyvalue
+ salt (- means use normal salt)
+ creation date and principal
+ modification date and principal
+ principal valid from date (not used)
+ principal valid end date (not used)
+ principal key expires (not used)
+ max ticket life
+ max renewable life
+ flags
+ */
+
+static void
+append_hex(char *str, krb5_data *data)
+{
+ int i, s = 1;
+ char *p;
+
+ p = data->data;
+ for(i = 0; i < data->length; i++)
+ if(!isalnum((unsigned char)p[i]) && p[i] != '.'){
+ s = 0;
+ break;
+ }
+ if(s){
+ p = calloc(1, data->length + 2 + 1);
+ p[0] = '\"';
+ p[data->length + 1] = '\"';
+ memcpy(p + 1, data->data, data->length);
+ }else{
+ p = calloc(1, data->length * 2 + 1);
+ for(i = 0; i < data->length; i++)
+ sprintf(p + 2 * i, "%02x", ((u_char*)data->data)[i]);
+ }
+ strcat(str, p);
+ free(p);
+}
+
+static char *
+time2str(time_t t)
+{
+ static char buf[128];
+ strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", gmtime(&t));
+ return buf;
+}
+
+static krb5_error_code
+event2string(krb5_context context, Event *ev, char **str)
+{
+ char *p;
+ char *pr;
+ krb5_error_code ret;
+ if(ev == NULL){
+ *str = strdup("-");
+ return (*str == NULL) ? ENOMEM : 0;
+ }
+ if (ev->principal == NULL) {
+ pr = strdup("UNKNOWN");
+ if (pr == NULL)
+ return ENOMEM;
+ } else {
+ ret = krb5_unparse_name(context, ev->principal, &pr);
+ if(ret)
+ return ret;
+ }
+ ret = asprintf(&p, "%s:%s", time2str(ev->time), pr);
+ free(pr);
+ if(ret < 0)
+ return ENOMEM;
+ *str = p;
+ return 0;
+}
+
+krb5_error_code
+hdb_entry2string(krb5_context context, hdb_entry *ent, char **str)
+{
+ char *p;
+ char buf[1024] = "";
+ int i;
+ krb5_error_code ret;
+
+ /* --- principal */
+ ret = krb5_unparse_name(context, ent->principal, &p);
+ if(ret)
+ return ret;
+ strlcat(buf, p, sizeof(buf));
+ strlcat(buf, " ", sizeof(buf));
+ free(p);
+ /* --- kvno */
+ asprintf(&p, "%d", ent->kvno);
+ strlcat(buf, p, sizeof(buf));
+ free(p);
+ /* --- keys */
+ for(i = 0; i < ent->keys.len; i++){
+ /* --- mkvno, keytype */
+ if(ent->keys.val[i].mkvno)
+ asprintf(&p, ":%d:%d:",
+ *ent->keys.val[i].mkvno,
+ ent->keys.val[i].key.keytype);
+ else
+ asprintf(&p, "::%d:",
+ ent->keys.val[i].key.keytype);
+ strlcat(buf, p, sizeof(buf));
+ free(p);
+ /* --- keydata */
+ append_hex(buf, &ent->keys.val[i].key.keyvalue);
+ strlcat(buf, ":", sizeof(buf));
+ /* --- salt */
+ if(ent->keys.val[i].salt){
+ asprintf(&p, "%u/", ent->keys.val[i].salt->type);
+ strlcat(buf, p, sizeof(buf));
+ free(p);
+ append_hex(buf, &ent->keys.val[i].salt->salt);
+ }else
+ strlcat(buf, "-", sizeof(buf));
+ }
+ strlcat(buf, " ", sizeof(buf));
+ /* --- created by */
+ event2string(context, &ent->created_by, &p);
+ strlcat(buf, p, sizeof(buf));
+ strlcat(buf, " ", sizeof(buf));
+ free(p);
+ /* --- modified by */
+ event2string(context, ent->modified_by, &p);
+ strlcat(buf, p, sizeof(buf));
+ strlcat(buf, " ", sizeof(buf));
+ free(p);
+
+ /* --- valid start */
+ if(ent->valid_start)
+ strlcat(buf, time2str(*ent->valid_start), sizeof(buf));
+ else
+ strlcat(buf, "-", sizeof(buf));
+ strlcat(buf, " ", sizeof(buf));
+
+ /* --- valid end */
+ if(ent->valid_end)
+ strlcat(buf, time2str(*ent->valid_end), sizeof(buf));
+ else
+ strlcat(buf, "-", sizeof(buf));
+ strlcat(buf, " ", sizeof(buf));
+
+ /* --- password ends */
+ if(ent->pw_end)
+ strlcat(buf, time2str(*ent->pw_end), sizeof(buf));
+ else
+ strlcat(buf, "-", sizeof(buf));
+ strlcat(buf, " ", sizeof(buf));
+
+ /* --- max life */
+ if(ent->max_life){
+ asprintf(&p, "%d", *ent->max_life);
+ strlcat(buf, p, sizeof(buf));
+ free(p);
+ }else
+ strlcat(buf, "-", sizeof(buf));
+ strlcat(buf, " ", sizeof(buf));
+
+ /* --- max renewable life */
+ if(ent->max_renew){
+ asprintf(&p, "%d", *ent->max_renew);
+ strlcat(buf, p, sizeof(buf));
+ free(p);
+ }else
+ strlcat(buf, "-", sizeof(buf));
+
+ strlcat(buf, " ", sizeof(buf));
+
+ /* --- flags */
+ asprintf(&p, "%d", HDBFlags2int(ent->flags));
+ strlcat(buf, p, sizeof(buf));
+ free(p);
+
+ *str = strdup(buf);
+
+ return 0;
+}
+
+/* print a hdb_entry to (FILE*)data; suitable for hdb_foreach */
+
+krb5_error_code
+hdb_print_entry(krb5_context context, HDB *db, hdb_entry *entry, void *data)
+{
+ char *p;
+ hdb_entry2string(context, entry, &p);
+ fprintf((FILE*)data, "%s\n", p);
+ free(p);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/ChangeLog b/crypto/heimdal/lib/kadm5/ChangeLog
new file mode 100644
index 000000000000..8c04ecbf1038
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/ChangeLog
@@ -0,0 +1,306 @@
+2000-01-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libkadm5srv.la): bump version to 5:1:0
+
+ * context_s.c (_kadm5_s_init_context): handle params == NULL
+
+1999-12-26 Assar Westerlund <assar@sics.se>
+
+ * get_s.c (kadm5_s_get_principal): handle modified_by->principal
+ == NULL
+
+1999-12-20 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libkadm5clnt_la_LDFLAGS): bump version to 4:1:0
+
+ * init_c.c (_kadm5_c_init_context): handle getting back port
+ number from admin host
+ (kadm5_c_init_with_context): remove `proto/' part before doing
+ getaddrinfo()
+
+1999-12-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 5:0:0 and 4:0:0
+
+ * init_c.c (kadm5_c_init_with_context): don't use unitialized
+ stuff
+
+1999-12-04 Assar Westerlund <assar@sics.se>
+
+ * replay_log.c: adapt to changed kadm5_log_foreach
+
+ * log.c (kadm5_log_foreach): change to take a
+ `kadm5_server_context'
+
+ * init_c.c: use krb5_warn{,x}
+
+ * dump_log.c: adapt to changed kadm5_log_foreach
+
+ * init_c.c: re-write to use getaddrinfo
+ * Makefile.am (install-build-headers): add dependency
+
+1999-12-03 Johan Danielsson <joda@pdc.kth.se>
+
+ * log.c (kadm5_log_foreach): pass context
+
+ * dump_log.c: print more interesting things
+
+1999-12-02 Johan Danielsson <joda@pdc.kth.se>
+
+ * ipropd_master.c (process_msg): check for short reads
+
+1999-11-25 Assar Westerlund <assar@sics.se>
+
+ * modify_s.c (kadm5_s_modify_principal): support key_data
+ (kadm5_s_modify_principal_with_key): remove
+
+ * admin.h (kadm5_s_modify_principal_with_key): remove
+
+1999-11-20 Assar Westerlund <assar@sics.se>
+
+ * context_s.c (find_db_spec): ugly cast work-around.
+
+1999-11-14 Assar Westerlund <assar@sics.se>
+
+ * context_s.c (_kadm5_s_init_context): call krb5_add_et_list so
+ that we aren't dependent on the layout of krb5_context_data
+ * init_c.c (_kadm5_c_init_context): call krb5_add_et_list so that
+ we aren't dependent on the layout of krb5_context_data
+
+1999-11-13 Assar Westerlund <assar@sics.se>
+
+ * password_quality.c (kadm5_setup_passwd_quality_check): use
+ correct types for function pointers
+
+1999-11-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * randkey_s.c: always bail out if the fetch fails
+
+ * admin.h (kadm5_config_params): remove fields we're not using
+
+ * ipropd_slave.c: allow passing a realm
+
+ * ipropd_master.c: allow passing a realm
+
+ * dump_log.c: allow passing a realm
+
+ * acl.c: correctly get acl file
+
+ * private.h (kadm5_server_context): add config_params struct and
+ remove acl_file; bump protocol version number
+
+ * marshall.c: marshalling of config parameters
+
+ * init_c.c (kadm5_c_init_with_context): try to cope with old
+ servers
+
+ * init_s.c (kadm5_s_init_with_context): actually use some passed
+ values
+
+ * context_s.c (_kadm5_s_init_context): get dbname, acl_file, and
+ stash_file from the config parameters, try to figure out these if
+ they're not provided
+
+1999-11-05 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (install-build-headers): use `cp' instead of
+ INSTALL_DATA
+
+1999-11-04 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 4:0:0 and 3:0:0 (they access fields
+ directly in libkrb5's context - bad functions)
+
+ * set_keys.c (_kadm5_set_keys_randomly): set enctypes correctly in
+ the copied keys
+
+1999-10-20 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version of kadm5srv to 3:0:2 (new password
+ quality functions).
+ set version of kdam5clnt to 2:1:1 (no interface changes)
+
+ * Makefile.am (LDADD): add $(LIB_dlopen)
+
+1999-10-17 Assar Westerlund <assar@sics.se>
+
+ * randkey_s.c (kadm5_s_randkey_principal): use
+ _kadm5_set_keys_randomly
+
+ * set_keys.c (free_keys): free more memory
+ (_kadm5_set_keys): a little bit more generic
+ (_kadm5_set_keys_randomly): new function for setting random keys.
+
+1999-10-14 Assar Westerlund <assar@sics.se>
+
+ * set_keys.c (_kadm5_set_keys): ignore old keys when setting new
+ ones and always add 3 DES keys and one 3DES key
+
+1999-10-03 Assar Westerlund <assar@sics.se>
+
+ * init_c.c (_kadm5_c_init_context): use `krb5_get_krb_admin_hst'.
+ check return value from strdup
+
+1999-09-26 Assar Westerlund <assar@sics.se>
+
+ * acl.c (_kadm5_privs_to_string): forgot one strcpy_truncate ->
+ strlcpy
+
+1999-09-24 Johan Danielsson <joda@pdc.kth.se>
+
+ * dump_log.c: remove unused `optind'
+
+ * replay_log.c: remove unused `optind'
+
+1999-09-13 Assar Westerlund <assar@sics.se>
+
+ * chpass_c.c (kadm5_c_chpass_principal): new _kadm5_client_recv
+
+ * send_recv.c (_kadm5_client_recv): return result in a `krb5_data'
+ so that we avoid copying it and don't need to dimension in
+ advance. change all callers.
+
+1999-09-10 Assar Westerlund <assar@sics.se>
+
+ * password_quality.c: new file
+
+ * admin.h
+ (kadm5_setup_passwd_quality_check,kadm5_check_password_quality):
+ add prototypes
+
+ * Makefile.am (S_SOURCES): add password_quality.c
+
+1999-07-26 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: update versions to 2:0:1
+
+1999-07-24 Assar Westerlund <assar@sics.se>
+
+ * ent_setup.c (_kadm5_setup_entry): make princ_expire_time == 0
+ and pw_expiration == 0 mean never
+
+1999-07-22 Assar Westerlund <assar@sics.se>
+
+ * log.c (kadm5_log_flush): extra cast
+
+1999-07-07 Assar Westerlund <assar@sics.se>
+
+ * marshall.c (store_principal_ent): encoding princ_expire_time and
+ pw_expiration in correct order
+
+1999-06-28 Assar Westerlund <assar@sics.se>
+
+ * randkey_s.c (kadm5_s_randkey_principal): nuke old mkvno,
+ otherwise hdb will think that the new random keys are already
+ encrypted which will cause lots of confusion later.
+
+1999-06-23 Assar Westerlund <assar@sics.se>
+
+ * ent_setup.c (_kadm5_setup_entry): handle 0 == unlimited
+ correctly. From Michal Vocu <michal@karlin.mff.cuni.cz>
+
+1999-06-15 Assar Westerlund <assar@sics.se>
+
+ * init_c.c (get_cred_cache): use get_default_username
+
+1999-05-23 Assar Westerlund <assar@sics.se>
+
+ * create_s.c (create_principal): if there's no default entry the
+ mask should be zero.
+
+1999-05-21 Assar Westerlund <assar@sics.se>
+
+ * init_c.c (get_cred_cache): use $USERNAME
+
+1999-05-17 Johan Danielsson <joda@pdc.kth.se>
+
+ * init_c.c (get_cred_cache): figure out principal
+
+1999-05-05 Johan Danielsson <joda@pdc.kth.se>
+
+ * send_recv.c: cleanup _kadm5_client_{send,recv}
+
+1999-05-04 Assar Westerlund <assar@sics.se>
+
+ * set_keys.c (_kadm5_set_keys2): don't check the recently created
+ memory for NULL pointers
+
+ * private.h (_kadm5_setup_entry): change prototype
+
+ * modify_s.c: call new _kadm5_setup_entry
+
+ * ent_setup.c (_kadm5_setup_entry): change so that it takes three
+ masks, one for what bits to set and one for each of principal and
+ def containing the bits that are set there.
+
+ * create_s.c: call new _kadm5_setup_entry
+
+ * create_s.c (get_default): check return value
+ (create_principal): send wider mask to _kadm5_setup_entry
+
+1999-05-04 Johan Danielsson <joda@pdc.kth.se>
+
+ * send_recv.c (_kadm5_client_recv): handle arbitrarily sized
+ packets, check for errors
+
+ * get_c.c: check for failure from _kadm5_client_{send,recv}
+
+1999-05-04 Assar Westerlund <assar@sics.se>
+
+ * init_c.c (get_new_cache): don't abort when interrupted from
+ password prompt
+
+ * destroy_c.c (kadm5_c_destroy): check if we should destroy the
+ auth context
+
+1999-05-03 Johan Danielsson <joda@pdc.kth.se>
+
+ * chpass_s.c: fix arguments to _kadm5_set_keys2
+
+ * private.h: proto
+
+ * set_keys.c: clear mkvno
+
+ * rename_s.c: add flags to fetch and store; seal keys before
+ logging
+
+ * randkey_s.c: add flags to fetch and store; seal keys before
+ logging
+
+ * modify_s.c: add flags to fetch and store; seal keys before
+ logging
+
+ * log.c: add flags to fetch and store; seal keys before logging
+
+ * get_s.c: add flags to fetch and store; seal keys before logging
+
+ * get_princs_s.c: add flags to fetch and store; seal keys before
+ logging
+
+ * delete_s.c: add flags to fetch and store; seal keys before
+ logging
+
+ * create_s.c: add flags to fetch and store; seal keys before
+ logging
+
+ * chpass_s.c: add flags to fetch and store; seal keys before
+ logging
+
+ * Makefile.am: remove server.c
+
+ * admin.h: add prototypes
+
+ * ent_setup.c (_kadm5_setup_entry): set key_data
+
+ * set_keys.c: add _kadm5_set_keys2 to sey keys from key_data
+
+ * modify_s.c: add kadm5_s_modify_principal_with_key
+
+ * create_s.c: add kadm5_s_create_principal_with_key
+
+ * chpass_s.c: add kadm5_s_chpass_principal_with_key
+
+ * kadm5_locl.h: move stuff to private.h
+
+ * private.h: move stuff from kadm5_locl.h
+ \ No newline at end of file
diff --git a/crypto/heimdal/lib/kadm5/Makefile.am b/crypto/heimdal/lib/kadm5/Makefile.am
new file mode 100644
index 000000000000..4e043f7b8201
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/Makefile.am
@@ -0,0 +1,110 @@
+# $Id: Makefile.am,v 1.32 2000/01/06 21:53:30 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+lib_LTLIBRARIES = libkadm5srv.la libkadm5clnt.la
+libkadm5srv_la_LDFLAGS = -version-info 5:1:0
+libkadm5clnt_la_LDFLAGS = -version-info 4:1:0
+sbin_PROGRAMS = dump_log replay_log
+
+libexec_PROGRAMS = ipropd-master ipropd-slave
+
+kadm5includedir = $(includedir)/kadm5
+buildkadm5include = $(buildinclude)/kadm5
+
+kadm5include_HEADERS = kadm5_err.h admin.h private.h
+
+install-build-headers:: $(kadm5include_HEADERS)
+ @foo='$(kadm5include_HEADERS)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildkadm5include)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo "cp $$file $(buildkadm5include)/$$f";\
+ cp $$file $(buildkadm5include)/$$f; \
+ fi ; \
+ done
+
+C_SOURCES = \
+ admin.h \
+ chpass_c.c \
+ common_glue.c \
+ create_c.c \
+ delete_c.c \
+ destroy_c.c \
+ flush_c.c \
+ free.c \
+ get_c.c \
+ get_princs_c.c \
+ init_c.c \
+ kadm5_err.c \
+ kadm5_locl.h \
+ marshall.c \
+ modify_c.c \
+ private.h \
+ privs_c.c \
+ randkey_c.c \
+ rename_c.c \
+ send_recv.c
+
+S_SOURCES = \
+ acl.c \
+ admin.h \
+ chpass_s.c \
+ common_glue.c \
+ context_s.c \
+ create_s.c \
+ delete_s.c \
+ destroy_s.c \
+ ent_setup.c \
+ error.c \
+ flush_s.c \
+ free.c \
+ get_princs_s.c \
+ get_s.c \
+ init_s.c \
+ kadm5_err.c \
+ kadm5_locl.h \
+ log.c \
+ marshall.c \
+ modify_s.c \
+ private.h \
+ privs_s.c \
+ randkey_s.c \
+ rename_s.c \
+ set_keys.c \
+ set_modifier.c \
+ password_quality.c
+
+libkadm5srv_la_SOURCES = $(S_SOURCES) server_glue.c
+libkadm5clnt_la_SOURCES = $(C_SOURCES) client_glue.c
+
+dump_log_SOURCES = dump_log.c kadm5_locl.h
+
+replay_log_SOURCES = replay_log.c kadm5_locl.h
+
+ipropd_master_SOURCES = ipropd_master.c iprop.h kadm5_locl.h
+
+ipropd_slave_SOURCES = ipropd_slave.c iprop.h kadm5_locl.h
+
+LDADD = \
+ libkadm5srv.la \
+ $(top_builddir)/lib/hdb/libhdb.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(top_builddir)/lib/des/libdes.la \
+ $(LIB_roken) \
+ $(DBLIB) \
+ $(LIB_dlopen)
+
+CLEANFILES = kadm5_err.c kadm5_err.h
+
+$(libkadm5srv_la_OBJECTS): kadm5_err.h
+
+client_glue.lo server_glue.lo: $(srcdir)/common_glue.c
+
+# to help stupid solaris make
+
+kadm5_err.h: kadm5_err.et
diff --git a/crypto/heimdal/lib/kadm5/Makefile.in b/crypto/heimdal/lib/kadm5/Makefile.in
new file mode 100644
index 000000000000..0872ca9b498e
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/Makefile.in
@@ -0,0 +1,812 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.32 2000/01/06 21:53:30 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+lib_LTLIBRARIES = libkadm5srv.la libkadm5clnt.la
+libkadm5srv_la_LDFLAGS = -version-info 5:1:0
+libkadm5clnt_la_LDFLAGS = -version-info 4:1:0
+sbin_PROGRAMS = dump_log replay_log
+
+libexec_PROGRAMS = ipropd-master ipropd-slave
+
+kadm5includedir = $(includedir)/kadm5
+buildkadm5include = $(buildinclude)/kadm5
+
+kadm5include_HEADERS = kadm5_err.h admin.h private.h
+
+C_SOURCES = admin.h chpass_c.c common_glue.c create_c.c delete_c.c destroy_c.c flush_c.c free.c get_c.c get_princs_c.c init_c.c kadm5_err.c kadm5_locl.h marshall.c modify_c.c private.h privs_c.c randkey_c.c rename_c.c send_recv.c
+
+
+S_SOURCES = acl.c admin.h chpass_s.c common_glue.c context_s.c create_s.c delete_s.c destroy_s.c ent_setup.c error.c flush_s.c free.c get_princs_s.c get_s.c init_s.c kadm5_err.c kadm5_locl.h log.c marshall.c modify_s.c private.h privs_s.c randkey_s.c rename_s.c set_keys.c set_modifier.c password_quality.c
+
+
+libkadm5srv_la_SOURCES = $(S_SOURCES) server_glue.c
+libkadm5clnt_la_SOURCES = $(C_SOURCES) client_glue.c
+
+dump_log_SOURCES = dump_log.c kadm5_locl.h
+
+replay_log_SOURCES = replay_log.c kadm5_locl.h
+
+ipropd_master_SOURCES = ipropd_master.c iprop.h kadm5_locl.h
+
+ipropd_slave_SOURCES = ipropd_slave.c iprop.h kadm5_locl.h
+
+LDADD = libkadm5srv.la $(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la $(top_builddir)/lib/des/libdes.la $(LIB_roken) $(DBLIB) $(LIB_dlopen)
+
+
+CLEANFILES = kadm5_err.c kadm5_err.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libkadm5srv_la_LIBADD =
+libkadm5srv_la_OBJECTS = acl.lo chpass_s.lo common_glue.lo context_s.lo \
+create_s.lo delete_s.lo destroy_s.lo ent_setup.lo error.lo flush_s.lo \
+free.lo get_princs_s.lo get_s.lo init_s.lo kadm5_err.lo log.lo \
+marshall.lo modify_s.lo privs_s.lo randkey_s.lo rename_s.lo set_keys.lo \
+set_modifier.lo password_quality.lo server_glue.lo
+libkadm5clnt_la_LIBADD =
+libkadm5clnt_la_OBJECTS = chpass_c.lo common_glue.lo create_c.lo \
+delete_c.lo destroy_c.lo flush_c.lo free.lo get_c.lo get_princs_c.lo \
+init_c.lo kadm5_err.lo marshall.lo modify_c.lo privs_c.lo randkey_c.lo \
+rename_c.lo send_recv.lo client_glue.lo
+libexec_PROGRAMS = ipropd-master$(EXEEXT) ipropd-slave$(EXEEXT)
+sbin_PROGRAMS = dump_log$(EXEEXT) replay_log$(EXEEXT)
+PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS)
+
+ipropd_master_OBJECTS = ipropd_master.$(OBJEXT)
+ipropd_master_LDADD = $(LDADD)
+ipropd_master_DEPENDENCIES = libkadm5srv.la \
+$(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/asn1/libasn1.la $(top_builddir)/lib/des/libdes.la
+ipropd_master_LDFLAGS =
+ipropd_slave_OBJECTS = ipropd_slave.$(OBJEXT)
+ipropd_slave_LDADD = $(LDADD)
+ipropd_slave_DEPENDENCIES = libkadm5srv.la \
+$(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/asn1/libasn1.la $(top_builddir)/lib/des/libdes.la
+ipropd_slave_LDFLAGS =
+dump_log_OBJECTS = dump_log.$(OBJEXT)
+dump_log_LDADD = $(LDADD)
+dump_log_DEPENDENCIES = libkadm5srv.la \
+$(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/asn1/libasn1.la $(top_builddir)/lib/des/libdes.la
+dump_log_LDFLAGS =
+replay_log_OBJECTS = replay_log.$(OBJEXT)
+replay_log_LDADD = $(LDADD)
+replay_log_DEPENDENCIES = libkadm5srv.la \
+$(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la \
+$(top_builddir)/lib/asn1/libasn1.la $(top_builddir)/lib/des/libdes.la
+replay_log_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(kadm5include_HEADERS)
+
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libkadm5srv_la_SOURCES) $(libkadm5clnt_la_SOURCES) $(ipropd_master_SOURCES) $(ipropd_slave_SOURCES) $(dump_log_SOURCES) $(replay_log_SOURCES)
+OBJECTS = $(libkadm5srv_la_OBJECTS) $(libkadm5clnt_la_OBJECTS) $(ipropd_master_OBJECTS) $(ipropd_slave_OBJECTS) $(dump_log_OBJECTS) $(replay_log_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/kadm5/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libkadm5srv.la: $(libkadm5srv_la_OBJECTS) $(libkadm5srv_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libkadm5srv_la_LDFLAGS) $(libkadm5srv_la_OBJECTS) $(libkadm5srv_la_LIBADD) $(LIBS)
+
+libkadm5clnt.la: $(libkadm5clnt_la_OBJECTS) $(libkadm5clnt_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libkadm5clnt_la_LDFLAGS) $(libkadm5clnt_la_OBJECTS) $(libkadm5clnt_la_LIBADD) $(LIBS)
+
+mostlyclean-libexecPROGRAMS:
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+
+distclean-libexecPROGRAMS:
+
+maintainer-clean-libexecPROGRAMS:
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-sbinPROGRAMS:
+
+clean-sbinPROGRAMS:
+ -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
+
+distclean-sbinPROGRAMS:
+
+maintainer-clean-sbinPROGRAMS:
+
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(sbindir)
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+ipropd-master$(EXEEXT): $(ipropd_master_OBJECTS) $(ipropd_master_DEPENDENCIES)
+ @rm -f ipropd-master$(EXEEXT)
+ $(LINK) $(ipropd_master_LDFLAGS) $(ipropd_master_OBJECTS) $(ipropd_master_LDADD) $(LIBS)
+
+ipropd-slave$(EXEEXT): $(ipropd_slave_OBJECTS) $(ipropd_slave_DEPENDENCIES)
+ @rm -f ipropd-slave$(EXEEXT)
+ $(LINK) $(ipropd_slave_LDFLAGS) $(ipropd_slave_OBJECTS) $(ipropd_slave_LDADD) $(LIBS)
+
+dump_log$(EXEEXT): $(dump_log_OBJECTS) $(dump_log_DEPENDENCIES)
+ @rm -f dump_log$(EXEEXT)
+ $(LINK) $(dump_log_LDFLAGS) $(dump_log_OBJECTS) $(dump_log_LDADD) $(LIBS)
+
+replay_log$(EXEEXT): $(replay_log_OBJECTS) $(replay_log_DEPENDENCIES)
+ @rm -f replay_log$(EXEEXT)
+ $(LINK) $(replay_log_LDFLAGS) $(replay_log_OBJECTS) $(replay_log_LDADD) $(LIBS)
+
+install-kadm5includeHEADERS: $(kadm5include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(kadm5includedir)
+ @list='$(kadm5include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(kadm5includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(kadm5includedir)/$$p; \
+ done
+
+uninstall-kadm5includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(kadm5include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(kadm5includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/kadm5
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES install-libexecPROGRAMS \
+ install-sbinPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-kadm5includeHEADERS install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS \
+ uninstall-sbinPROGRAMS uninstall-kadm5includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(libexecdir) \
+ $(DESTDIR)$(sbindir) $(DESTDIR)$(kadm5includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-libexecPROGRAMS \
+ mostlyclean-sbinPROGRAMS mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \
+ clean-libexecPROGRAMS clean-sbinPROGRAMS clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-libexecPROGRAMS \
+ distclean-sbinPROGRAMS distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-libexecPROGRAMS \
+ maintainer-clean-sbinPROGRAMS maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool mostlyclean-libexecPROGRAMS \
+distclean-libexecPROGRAMS clean-libexecPROGRAMS \
+maintainer-clean-libexecPROGRAMS uninstall-libexecPROGRAMS \
+install-libexecPROGRAMS mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS \
+clean-sbinPROGRAMS maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \
+install-sbinPROGRAMS uninstall-kadm5includeHEADERS \
+install-kadm5includeHEADERS tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-local install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+install-build-headers:: $(kadm5include_HEADERS)
+ @foo='$(kadm5include_HEADERS)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildkadm5include)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo "cp $$file $(buildkadm5include)/$$f";\
+ cp $$file $(buildkadm5include)/$$f; \
+ fi ; \
+ done
+
+$(libkadm5srv_la_OBJECTS): kadm5_err.h
+
+client_glue.lo server_glue.lo: $(srcdir)/common_glue.c
+
+# to help stupid solaris make
+
+kadm5_err.h: kadm5_err.et
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/kadm5/acl.c b/crypto/heimdal/lib/kadm5/acl.c
new file mode 100644
index 000000000000..3f42c60d7739
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/acl.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: acl.c,v 1.10 1999/12/02 17:05:05 joda Exp $");
+
+static struct units acl_units[] = {
+ { "all", KADM5_PRIV_ALL },
+ { "change-password",KADM5_PRIV_CPW },
+ { "cpw", KADM5_PRIV_CPW },
+ { "list", KADM5_PRIV_LIST },
+ { "delete", KADM5_PRIV_DELETE },
+ { "modify", KADM5_PRIV_MODIFY },
+ { "add", KADM5_PRIV_ADD },
+ { "get", KADM5_PRIV_GET },
+ { NULL }
+};
+
+kadm5_ret_t
+_kadm5_string_to_privs(const char *s, u_int32_t* privs)
+{
+ int flags;
+ flags = parse_flags(s, acl_units, 0);
+ if(flags < 0)
+ return KADM5_FAILURE;
+ *privs = flags;
+ return 0;
+}
+
+kadm5_ret_t
+_kadm5_privs_to_string(u_int32_t privs, char *string, size_t len)
+{
+ if(privs == 0)
+ strlcpy(string, "none", len);
+ else
+ unparse_flags(privs, acl_units + 1, string, len);
+ return 0;
+}
+
+kadm5_ret_t
+_kadm5_acl_init(kadm5_server_context *context)
+{
+ FILE *f;
+ char buf[128];
+ krb5_principal princ;
+ int flags;
+ krb5_error_code ret;
+
+ krb5_parse_name(context->context, KADM5_ADMIN_SERVICE, &princ);
+ ret = krb5_principal_compare(context->context, context->caller, princ);
+ krb5_free_principal(context->context, princ);
+ if(ret != 0){
+ context->acl_flags = KADM5_PRIV_ALL;
+ return 0;
+ }
+
+ flags = -1;
+ f = fopen(context->config.acl_file, "r");
+ if(f){
+ while(fgets(buf, sizeof(buf), f)){
+ char *foo = NULL, *p;
+ p = strtok_r(buf, " \t\n", &foo);
+ if(p == NULL)
+ continue;
+ ret = krb5_parse_name(context->context, p, &princ);
+ if(ret)
+ continue;
+ if(!krb5_principal_compare(context->context,
+ context->caller, princ)){
+ krb5_free_principal(context->context, princ);
+ continue;
+ }
+ krb5_free_principal(context->context, princ);
+ p = strtok_r(NULL, "\n", &foo);
+ if(p == NULL)
+ continue;
+ ret = _kadm5_string_to_privs(p, &flags);
+ break;
+ }
+ fclose(f);
+ }
+ if(flags == -1)
+ flags = 0;
+ context->acl_flags = flags;
+ return 0;
+}
+
+kadm5_ret_t
+_kadm5_acl_check_permission(kadm5_server_context *context, unsigned op)
+{
+ unsigned res = ~context->acl_flags & op;
+ if(res & KADM5_PRIV_GET)
+ return KADM5_AUTH_GET;
+ if(res & KADM5_PRIV_ADD)
+ return KADM5_AUTH_ADD;
+ if(res & KADM5_PRIV_MODIFY)
+ return KADM5_AUTH_MODIFY;
+ if(res & KADM5_PRIV_DELETE)
+ return KADM5_AUTH_DELETE;
+ if(res & KADM5_PRIV_CPW)
+ return KADM5_AUTH_CHANGEPW;
+ if(res & KADM5_PRIV_LIST)
+ return KADM5_AUTH_LIST;
+ if(res)
+ return KADM5_AUTH_INSUFFICIENT;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/admin.h b/crypto/heimdal/lib/kadm5/admin.h
new file mode 100644
index 000000000000..6cb08a373963
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/admin.h
@@ -0,0 +1,698 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+/* $Id: admin.h,v 1.15 1999/12/02 17:05:05 joda Exp $ */
+
+#ifndef __KADM5_ADMIN_H__
+#define __KADM5_ADMIN_H__
+
+#define KADM5_API_VERSION_1 1
+#define KADM5_API_VERSION_2 2
+
+#ifndef USE_KADM5_API_VERSION
+#define USE_KADM5_API_VERSION KADM5_API_VERSION_2
+#endif
+
+#if USE_KADM5_API_VERSION != KADM5_API_VERSION_2
+#error No support for API versions other than 2
+#endif
+
+#define KADM5_STRUCT_VERSION 0
+
+#include <krb5.h>
+
+#define KRB5_KDB_DISALLOW_POSTDATED 0x00000001
+#define KRB5_KDB_DISALLOW_FORWARDABLE 0x00000002
+#define KRB5_KDB_DISALLOW_TGT_BASED 0x00000004
+#define KRB5_KDB_DISALLOW_RENEWABLE 0x00000008
+#define KRB5_KDB_DISALLOW_PROXIABLE 0x00000010
+#define KRB5_KDB_DISALLOW_DUP_SKEY 0x00000020
+#define KRB5_KDB_DISALLOW_ALL_TIX 0x00000040
+#define KRB5_KDB_REQUIRES_PRE_AUTH 0x00000080
+#define KRB5_KDB_REQUIRES_HW_AUTH 0x00000100
+#define KRB5_KDB_REQUIRES_PWCHANGE 0x00000200
+#define KRB5_KDB_DISALLOW_SVR 0x00001000
+#define KRB5_KDB_PWCHANGE_SERVICE 0x00002000
+#define KRB5_KDB_SUPPORT_DESMD5 0x00004000
+#define KRB5_KDB_NEW_PRINC 0x00008000
+
+#define KADM5_PRINCIPAL 0x000001
+#define KADM5_PRINC_EXPIRE_TIME 0x000002
+#define KADM5_PW_EXPIRATION 0x000004
+#define KADM5_LAST_PWD_CHANGE 0x000008
+#define KADM5_ATTRIBUTES 0x000010
+#define KADM5_MAX_LIFE 0x000020
+#define KADM5_MOD_TIME 0x000040
+#define KADM5_MOD_NAME 0x000080
+#define KADM5_KVNO 0x000100
+#define KADM5_MKVNO 0x000200
+#define KADM5_AUX_ATTRIBUTES 0x000400
+#define KADM5_POLICY 0x000800
+#define KADM5_POLICY_CLR 0x001000
+#define KADM5_MAX_RLIFE 0x002000
+#define KADM5_LAST_SUCCESS 0x004000
+#define KADM5_LAST_FAILED 0x008000
+#define KADM5_FAIL_AUTH_COUNT 0x010000
+#define KADM5_KEY_DATA 0x020000
+#define KADM5_TL_DATA 0x040000
+
+#define KADM5_PRINCIPAL_NORMAL_MASK (~(KADM5_KEY_DATA | KADM5_TL_DATA))
+
+#define KADM5_PW_MAX_LIFE 0x004000
+#define KADM5_PW_MIN_LIFE 0x008000
+#define KADM5_PW_MIN_LENGTH 0x010000
+#define KADM5_PW_MIN_CLASSES 0x020000
+#define KADM5_PW_HISTORY_NUM 0x040000
+#define KADM5_REF_COUNT 0x080000
+
+#define KADM5_POLICY_NORMAL_MASK (~0)
+
+#define KADM5_ADMIN_SERVICE "kadmin/admin"
+#define KADM5_HIST_PRINCIPAL "kadmin/history"
+#define KADM5_CHANGEPW_SERVICE "kadmin/changepw"
+
+typedef struct _krb5_key_data {
+ int16_t key_data_ver; /* Version */
+ int16_t key_data_kvno; /* Key Version */
+ int16_t key_data_type[2]; /* Array of types */
+ int16_t key_data_length[2]; /* Array of lengths */
+ void** key_data_contents[2];/* Array of pointers */
+} krb5_key_data;
+
+typedef struct _krb5_tl_data {
+ struct _krb5_tl_data* tl_data_next;
+ int16_t tl_data_type;
+ int16_t tl_data_length;
+ void **tl_data_contents;
+} krb5_tl_data;
+
+typedef struct _kadm5_principal_ent_t {
+ krb5_principal principal;
+
+ krb5_timestamp princ_expire_time;
+ krb5_timestamp last_pwd_change;
+ krb5_timestamp pw_expiration;
+ krb5_deltat max_life;
+ krb5_principal mod_name;
+ krb5_timestamp mod_date;
+ krb5_flags attributes;
+ krb5_kvno kvno;
+ krb5_kvno mkvno;
+
+ char * policy;
+ u_int32_t aux_attributes;
+
+ krb5_deltat max_renewable_life;
+ krb5_timestamp last_success;
+ krb5_timestamp last_failed;
+ krb5_kvno fail_auth_count;
+ int16_t n_key_data;
+ int16_t n_tl_data;
+ krb5_tl_data *tl_data;
+ krb5_key_data *key_data;
+} kadm5_principal_ent_rec, *kadm5_principal_ent_t;
+
+typedef struct _kadm5_policy_ent_t {
+ char *policy;
+
+ u_int32_t pw_min_life;
+ u_int32_t pw_max_life;
+ u_int32_t pw_min_length;
+ u_int32_t pw_min_classes;
+ u_int32_t pw_history_num;
+ u_int32_t policy_refcnt;
+} kadm5_policy_ent_rec, *kadm5_policy_ent_t;
+
+#define KADM5_CONFIG_REALM (1 << 0)
+#define KADM5_CONFIG_PROFILE (1 << 1)
+#define KADM5_CONFIG_KADMIND_PORT (1 << 2)
+#define KADM5_CONFIG_ADMIN_SERVER (1 << 3)
+#define KADM5_CONFIG_DBNAME (1 << 4)
+#define KADM5_CONFIG_ADBNAME (1 << 5)
+#define KADM5_CONFIG_ADB_LOCKFILE (1 << 6)
+#define KADM5_CONFIG_ACL_FILE (1 << 7)
+#define KADM5_CONFIG_DICT_FILE (1 << 8)
+#define KADM5_CONFIG_ADMIN_KEYTAB (1 << 9)
+#define KADM5_CONFIG_MKEY_FROM_KEYBOARD (1 << 10)
+#define KADM5_CONFIG_STASH_FILE (1 << 11)
+#define KADM5_CONFIG_MKEY_NAME (1 << 12)
+#define KADM5_CONFIG_ENCTYPE (1 << 13)
+#define KADM5_CONFIG_MAX_LIFE (1 << 14)
+#define KADM5_CONFIG_MAX_RLIFE (1 << 15)
+#define KADM5_CONFIG_EXPIRATION (1 << 16)
+#define KADM5_CONFIG_FLAGS (1 << 17)
+#define KADM5_CONFIG_ENCTYPES (1 << 18)
+
+#define KADM5_PRIV_GET (1 << 0)
+#define KADM5_PRIV_ADD (1 << 1)
+#define KADM5_PRIV_MODIFY (1 << 2)
+#define KADM5_PRIV_DELETE (1 << 3)
+#define KADM5_PRIV_LIST (1 << 4)
+#define KADM5_PRIV_CPW (1 << 5)
+#define KADM5_PRIV_ALL (KADM5_PRIV_GET | KADM5_PRIV_ADD | KADM5_PRIV_MODIFY | KADM5_PRIV_DELETE | KADM5_PRIV_LIST | KADM5_PRIV_CPW)
+
+typedef struct {
+ int XXX;
+}krb5_key_salt_tuple;
+
+typedef struct _kadm5_config_params {
+ u_int32_t mask;
+
+ /* Client and server fields */
+ char *realm;
+ int kadmind_port;
+
+ /* client fields */
+ char *admin_server;
+
+ /* server fields */
+ char *dbname;
+ char *acl_file;
+
+ /* server library (database) fields */
+ char *stash_file;
+} kadm5_config_params;
+
+typedef krb5_error_code kadm5_ret_t;
+
+kadm5_ret_t
+kadm5_c_chpass_principal __P((
+ void *server_handle,
+ krb5_principal princ,
+ char *password));
+
+kadm5_ret_t
+kadm5_c_create_principal __P((
+ void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask,
+ char *password));
+
+kadm5_ret_t
+kadm5_c_delete_principal __P((
+ void *server_handle,
+ krb5_principal princ));
+
+kadm5_ret_t
+kadm5_c_destroy __P((void *server_handle));
+
+kadm5_ret_t
+kadm5_c_flush __P((void *server_handle));
+
+kadm5_ret_t
+kadm5_c_get_principal __P((
+ void *server_handle,
+ krb5_principal princ,
+ kadm5_principal_ent_t out,
+ u_int32_t mask));
+
+kadm5_ret_t
+kadm5_c_get_principals __P((
+ void *server_handle,
+ const char *exp,
+ char ***princs,
+ int *count));
+
+kadm5_ret_t
+kadm5_c_get_privs __P((
+ void *server_handle,
+ u_int32_t *privs));
+
+kadm5_ret_t
+kadm5_c_init_with_creds __P((
+ const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_c_init_with_creds_ctx __P((
+ krb5_context context,
+ const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_c_init_with_password __P((
+ const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_c_init_with_password_ctx __P((
+ krb5_context context,
+ const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_c_init_with_skey __P((
+ const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_c_init_with_skey_ctx __P((
+ krb5_context context,
+ const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_c_modify_principal __P((
+ void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask));
+
+kadm5_ret_t
+kadm5_c_randkey_principal __P((
+ void *server_handle,
+ krb5_principal princ,
+ krb5_keyblock **new_keys,
+ int *n_keys));
+
+kadm5_ret_t
+kadm5_c_rename_principal __P((
+ void *server_handle,
+ krb5_principal source,
+ krb5_principal target));
+
+kadm5_ret_t
+kadm5_chpass_principal __P((
+ void *server_handle,
+ krb5_principal princ,
+ char *password));
+
+kadm5_ret_t
+kadm5_create_principal __P((
+ void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask,
+ char *password));
+
+kadm5_ret_t
+kadm5_delete_principal __P((
+ void *server_handle,
+ krb5_principal princ));
+
+kadm5_ret_t
+kadm5_destroy __P((void *server_handle));
+
+kadm5_ret_t
+kadm5_flush __P((void *server_handle));
+
+void
+kadm5_free_key_data __P((
+ void *server_handle,
+ int16_t *n_key_data,
+ krb5_key_data *key_data));
+
+void
+kadm5_free_name_list __P((
+ void *server_handle,
+ char **names,
+ int *count));
+
+void
+kadm5_free_principal_ent __P((
+ void *server_handle,
+ kadm5_principal_ent_t princ));
+
+kadm5_ret_t
+kadm5_get_principal __P((
+ void *server_handle,
+ krb5_principal princ,
+ kadm5_principal_ent_t out,
+ u_int32_t mask));
+
+kadm5_ret_t
+kadm5_get_principals __P((
+ void *server_handle,
+ const char *exp,
+ char ***princs,
+ int *count));
+
+kadm5_ret_t
+kadm5_get_privs __P((
+ void *server_handle,
+ u_int32_t *privs));
+
+kadm5_ret_t
+kadm5_init_with_creds __P((
+ const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_init_with_creds_ctx __P((
+ krb5_context context,
+ const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_init_with_password __P((
+ const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_init_with_password_ctx __P((
+ krb5_context context,
+ const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_init_with_skey __P((
+ const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_init_with_skey_ctx __P((
+ krb5_context context,
+ const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_modify_principal __P((
+ void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask));
+
+kadm5_ret_t
+kadm5_randkey_principal __P((
+ void *server_handle,
+ krb5_principal princ,
+ krb5_keyblock **new_keys,
+ int *n_keys));
+
+kadm5_ret_t
+kadm5_rename_principal __P((
+ void *server_handle,
+ krb5_principal source,
+ krb5_principal target));
+
+kadm5_ret_t
+kadm5_ret_key_data __P((
+ krb5_storage *sp,
+ krb5_key_data *key));
+
+kadm5_ret_t
+kadm5_ret_principal_ent __P((
+ krb5_storage *sp,
+ kadm5_principal_ent_t princ));
+
+kadm5_ret_t
+kadm5_ret_principal_ent_mask __P((
+ krb5_storage *sp,
+ kadm5_principal_ent_t princ,
+ u_int32_t *mask));
+
+kadm5_ret_t
+kadm5_ret_tl_data __P((
+ krb5_storage *sp,
+ krb5_tl_data *tl));
+
+kadm5_ret_t
+kadm5_s_chpass_principal __P((
+ void *server_handle,
+ krb5_principal princ,
+ char *password));
+
+kadm5_ret_t
+kadm5_s_chpass_principal_with_key __P((
+ void *server_handle,
+ krb5_principal princ,
+ int n_key_data,
+ krb5_key_data *key_data));
+
+kadm5_ret_t
+kadm5_s_create_principal __P((
+ void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask,
+ char *password));
+
+kadm5_ret_t
+kadm5_s_create_principal_with_key __P((
+ void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask));
+
+kadm5_ret_t
+kadm5_s_delete_principal __P((
+ void *server_handle,
+ krb5_principal princ));
+
+kadm5_ret_t
+kadm5_s_destroy __P((void *server_handle));
+
+kadm5_ret_t
+kadm5_s_flush __P((void *server_handle));
+
+kadm5_ret_t
+kadm5_s_get_principal __P((
+ void *server_handle,
+ krb5_principal princ,
+ kadm5_principal_ent_t out,
+ u_int32_t mask));
+
+kadm5_ret_t
+kadm5_s_get_principals __P((
+ void *server_handle,
+ const char *exp,
+ char ***princs,
+ int *count));
+
+kadm5_ret_t
+kadm5_s_get_privs __P((
+ void *server_handle,
+ u_int32_t *privs));
+
+kadm5_ret_t
+kadm5_s_init_with_creds __P((
+ const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_s_init_with_creds_ctx __P((
+ krb5_context context,
+ const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_s_init_with_password __P((
+ const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_s_init_with_password_ctx __P((
+ krb5_context context,
+ const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_s_init_with_skey __P((
+ const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_s_init_with_skey_ctx __P((
+ krb5_context context,
+ const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle));
+
+kadm5_ret_t
+kadm5_s_modify_principal __P((
+ void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask));
+
+kadm5_ret_t
+kadm5_s_randkey_principal __P((
+ void *server_handle,
+ krb5_principal princ,
+ krb5_keyblock **new_keys,
+ int *n_keys));
+
+kadm5_ret_t
+kadm5_s_rename_principal __P((
+ void *server_handle,
+ krb5_principal source,
+ krb5_principal target));
+
+kadm5_ret_t
+kadm5_store_key_data __P((
+ krb5_storage *sp,
+ krb5_key_data *key));
+
+kadm5_ret_t
+kadm5_store_principal_ent __P((
+ krb5_storage *sp,
+ kadm5_principal_ent_t princ));
+
+kadm5_ret_t
+kadm5_store_principal_ent_mask __P((
+ krb5_storage *sp,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask));
+
+kadm5_ret_t
+kadm5_store_tl_data __P((
+ krb5_storage *sp,
+ krb5_tl_data *tl));
+
+void
+kadm5_setup_passwd_quality_check(krb5_context context,
+ const char *check_library,
+ const char *check_function);
+
+const char *
+kadm5_check_password_quality (krb5_context context,
+ krb5_principal principal,
+ krb5_data *pwd_data);
+
+#if 0
+/* unimplemented functions */
+kadm5_ret_t
+kadm5_decrypt_key(void *server_handle,
+ kadm5_principal_ent_t entry, int32_t
+ ktype, int32_t stype, int32_t
+ kvno, krb5_keyblock *keyblock,
+ krb5_keysalt *keysalt, int *kvnop);
+
+kadm5_ret_t
+kadm5_create_policy(void *server_handle,
+ kadm5_policy_ent_t policy, u_int32_t mask);
+
+kadm5_ret_t
+kadm5_delete_policy(void *server_handle, char *policy);
+
+
+kadm5_ret_t
+kadm5_modify_policy(void *server_handle,
+ kadm5_policy_ent_t policy,
+ u_int32_t mask);
+
+kadm5_ret_t
+kadm5_get_policy(void *server_handle, char *policy, kadm5_policy_ent_t ent);
+
+kadm5_ret_t
+kadm5_get_policies(void *server_handle, char *exp,
+ char ***pols, int *count);
+
+void
+kadm5_free_policy_ent(kadm5_policy_ent_t policy);
+
+#endif
+
+#endif /* __KADM5_ADMIN_H__ */
diff --git a/crypto/heimdal/lib/kadm5/chpass_c.c b/crypto/heimdal/lib/kadm5/chpass_c.c
new file mode 100644
index 000000000000..aaec48f65d62
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/chpass_c.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: chpass_c.c,v 1.3 1999/12/02 17:05:05 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_chpass_principal(void *server_handle,
+ krb5_principal princ,
+ char *password)
+{
+ kadm5_client_context *context = server_handle;
+ kadm5_ret_t ret;
+ krb5_storage *sp;
+ unsigned char buf[1024];
+ int32_t tmp;
+ krb5_data reply;
+
+ sp = krb5_storage_from_mem(buf, sizeof(buf));
+ if (sp == NULL)
+ return ENOMEM;
+ krb5_store_int32(sp, kadm_chpass);
+ krb5_store_principal(sp, princ);
+ krb5_store_string(sp, password);
+ ret = _kadm5_client_send(context, sp);
+ krb5_storage_free(sp);
+ ret = _kadm5_client_recv(context, &reply);
+ if(ret)
+ return ret;
+ sp = krb5_storage_from_data (&reply);
+ if (sp == NULL) {
+ krb5_data_free (&reply);
+ return ENOMEM;
+ }
+ krb5_ret_int32(sp, &tmp);
+ krb5_storage_free(sp);
+ krb5_data_free (&reply);
+ return tmp;
+}
diff --git a/crypto/heimdal/lib/kadm5/chpass_s.c b/crypto/heimdal/lib/kadm5/chpass_s.c
new file mode 100644
index 000000000000..e915124e6e59
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/chpass_s.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: chpass_s.c,v 1.8 1999/12/02 17:05:05 joda Exp $");
+
+kadm5_ret_t
+kadm5_s_chpass_principal(void *server_handle,
+ krb5_principal princ,
+ char *password)
+{
+ kadm5_server_context *context = server_handle;
+ hdb_entry ent;
+ kadm5_ret_t ret;
+ ent.principal = princ;
+ ret = context->db->open(context->context, context->db, O_RDWR, 0);
+ if(ret)
+ return ret;
+ ret = context->db->fetch(context->context, context->db,
+ 0, &ent);
+ if(ret == HDB_ERR_NOENTRY)
+ goto out;
+ ret = _kadm5_set_keys(context, &ent, password);
+ if(ret)
+ goto out2;
+ ret = _kadm5_set_modifier(context, &ent);
+ if(ret)
+ goto out2;
+
+ hdb_seal_keys(context->db, &ent);
+
+ kadm5_log_modify (context,
+ &ent,
+ KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME |
+ KADM5_KEY_DATA | KADM5_KVNO);
+
+ ret = context->db->store(context->context, context->db,
+ HDB_F_REPLACE, &ent);
+out2:
+ hdb_free_entry(context->context, &ent);
+out:
+ context->db->close(context->context, context->db);
+ return _kadm5_error_code(ret);
+}
+
+kadm5_ret_t
+kadm5_s_chpass_principal_with_key(void *server_handle,
+ krb5_principal princ,
+ int n_key_data,
+ krb5_key_data *key_data)
+{
+ kadm5_server_context *context = server_handle;
+ hdb_entry ent;
+ kadm5_ret_t ret;
+ ent.principal = princ;
+ ret = context->db->open(context->context, context->db, O_RDWR, 0);
+ if(ret)
+ return ret;
+ ret = context->db->fetch(context->context, context->db, 0, &ent);
+ if(ret == HDB_ERR_NOENTRY)
+ goto out;
+ ret = _kadm5_set_keys2(&ent, n_key_data, key_data);
+ if(ret)
+ goto out2;
+ ret = _kadm5_set_modifier(context, &ent);
+ if(ret)
+ goto out2;
+
+ hdb_seal_keys(context->db, &ent);
+
+ kadm5_log_modify (context,
+ &ent,
+ KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME |
+ KADM5_KEY_DATA | KADM5_KVNO);
+
+ ret = context->db->store(context->context, context->db,
+ HDB_F_REPLACE, &ent);
+out2:
+ hdb_free_entry(context->context, &ent);
+out:
+ context->db->close(context->context, context->db);
+ return _kadm5_error_code(ret);
+}
diff --git a/crypto/heimdal/lib/kadm5/client_glue.c b/crypto/heimdal/lib/kadm5/client_glue.c
new file mode 100644
index 000000000000..395577ddb303
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/client_glue.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: client_glue.c,v 1.5 1999/12/02 17:05:05 joda Exp $");
+
+kadm5_ret_t
+kadm5_init_with_password(const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_c_init_with_password(client_name,
+ password,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_init_with_password_ctx(krb5_context context,
+ const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_c_init_with_password_ctx(context,
+ client_name,
+ password,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_init_with_skey(const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_c_init_with_skey(client_name,
+ keytab,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_init_with_skey_ctx(krb5_context context,
+ const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_c_init_with_skey_ctx(context,
+ client_name,
+ keytab,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_init_with_creds(const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_c_init_with_creds(client_name,
+ ccache,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_init_with_creds_ctx(krb5_context context,
+ const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_c_init_with_creds_ctx(context,
+ client_name,
+ ccache,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
diff --git a/crypto/heimdal/lib/kadm5/common_glue.c b/crypto/heimdal/lib/kadm5/common_glue.c
new file mode 100644
index 000000000000..38c551c29e7a
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/common_glue.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: common_glue.c,v 1.4 1999/12/02 17:05:05 joda Exp $");
+
+#define __CALL(F, P) (*((kadm5_common_context*)server_handle)->funcs.F)P;
+
+kadm5_ret_t
+kadm5_chpass_principal(void *server_handle,
+ krb5_principal princ,
+ char *password)
+{
+ return __CALL(chpass_principal, (server_handle, princ, password));
+}
+
+kadm5_ret_t
+kadm5_create_principal(void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask,
+ char *password)
+{
+ return __CALL(create_principal, (server_handle, princ, mask, password));
+}
+
+kadm5_ret_t
+kadm5_delete_principal(void *server_handle,
+ krb5_principal princ)
+{
+ return __CALL(delete_principal, (server_handle, princ));
+}
+
+kadm5_ret_t
+kadm5_destroy (void *server_handle)
+{
+ return __CALL(destroy, (server_handle));
+}
+
+kadm5_ret_t
+kadm5_flush (void *server_handle)
+{
+ return __CALL(flush, (server_handle));
+}
+
+kadm5_ret_t
+kadm5_get_principal(void *server_handle,
+ krb5_principal princ,
+ kadm5_principal_ent_t out,
+ u_int32_t mask)
+{
+ return __CALL(get_principal, (server_handle, princ, out, mask));
+}
+
+kadm5_ret_t
+kadm5_modify_principal(void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask)
+{
+ return __CALL(modify_principal, (server_handle, princ, mask));
+}
+
+kadm5_ret_t
+kadm5_randkey_principal(void *server_handle,
+ krb5_principal princ,
+ krb5_keyblock **new_keys,
+ int *n_keys)
+{
+ return __CALL(randkey_principal, (server_handle, princ, new_keys, n_keys));
+}
+
+kadm5_ret_t
+kadm5_rename_principal(void *server_handle,
+ krb5_principal source,
+ krb5_principal target)
+{
+ return __CALL(rename_principal, (server_handle, source, target));
+}
+
+kadm5_ret_t
+kadm5_get_principals(void *server_handle,
+ const char *exp,
+ char ***princs,
+ int *count)
+{
+ return __CALL(get_principals, (server_handle, exp, princs, count));
+}
+
+kadm5_ret_t
+kadm5_get_privs(void *server_handle,
+ u_int32_t *privs)
+{
+ return __CALL(get_privs, (server_handle, privs));
+}
diff --git a/crypto/heimdal/lib/kadm5/context_s.c b/crypto/heimdal/lib/kadm5/context_s.c
new file mode 100644
index 000000000000..fc525767e9d2
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/context_s.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: context_s.c,v 1.13 2000/01/06 21:40:08 assar Exp $");
+
+static void
+set_funcs(kadm5_server_context *c)
+{
+#define SET(C, F) (C)->funcs.F = kadm5_s_ ## F
+ SET(c, chpass_principal);
+ SET(c, chpass_principal);
+ SET(c, create_principal);
+ SET(c, delete_principal);
+ SET(c, destroy);
+ SET(c, flush);
+ SET(c, get_principal);
+ SET(c, get_principals);
+ SET(c, get_privs);
+ SET(c, modify_principal);
+ SET(c, randkey_principal);
+ SET(c, rename_principal);
+}
+
+struct database_spec {
+ char *dbpath;
+ char *logfile;
+ char *mkeyfile;
+ char *aclfile;
+};
+
+static void
+set_field(krb5_context context, krb5_config_binding *binding,
+ const char *dbname, const char *name, const char *ext,
+ char **variable)
+{
+ const char *p;
+ p = krb5_config_get_string(context, binding, name, NULL);
+ if(p)
+ *variable = strdup(p);
+ else {
+ p = strrchr(dbname, '.');
+ if(p == NULL)
+ asprintf(variable, "%s.%s", dbname, ext);
+ else
+ asprintf(variable, "%.*s.%s", (int)(p - dbname), dbname, ext);
+ }
+}
+
+static void
+set_socket_name(const char *dbname, struct sockaddr_un *un)
+{
+ const char *p;
+ memset(un, 0, sizeof(*un));
+ un->sun_family = AF_UNIX;
+ p = strrchr(dbname, '.');
+ if(p == NULL)
+ snprintf(un->sun_path, sizeof(un->sun_path), "%s.signal",
+ dbname);
+ else
+ snprintf(un->sun_path, sizeof(un->sun_path), "%.*s.signal",
+ (int)(p - dbname), dbname);
+}
+
+static void
+set_config(kadm5_server_context *ctx,
+ krb5_config_binding *binding)
+{
+ const char *p;
+ if(ctx->config.dbname == NULL) {
+ p = krb5_config_get_string(ctx->context, binding, "dbname", NULL);
+ if(p)
+ ctx->config.dbname = strdup(p);
+ else
+ ctx->config.dbname = strdup(HDB_DEFAULT_DB);
+ }
+ if(ctx->log_context.log_file == NULL)
+ set_field(ctx->context, binding, ctx->config.dbname,
+ "log_file", "log", &ctx->log_context.log_file);
+ set_socket_name(ctx->config.dbname, &ctx->log_context.socket_name);
+ if(ctx->config.acl_file == NULL)
+ set_field(ctx->context, binding, ctx->config.dbname,
+ "acl_file", "acl", &ctx->config.acl_file);
+ /* XXX calling a file a `stash file' isn't very clever */
+ if(ctx->config.stash_file == NULL)
+ set_field(ctx->context, binding, ctx->config.dbname,
+ "mkey_file", "mkey", &ctx->config.stash_file);
+}
+
+static kadm5_ret_t
+find_db_spec(kadm5_server_context *ctx)
+{
+ krb5_config_binding *top_binding = NULL;
+ krb5_config_binding *db_binding;
+ krb5_config_binding *default_binding = NULL;
+ krb5_context context = ctx->context;
+
+ while((db_binding = (krb5_config_binding *)
+ krb5_config_get_next(context,
+ NULL, &top_binding,
+ krb5_config_list,
+ "kdc",
+ "database",
+ NULL))) {
+ const char *p;
+ p = krb5_config_get_string(context, db_binding, "realm", NULL);
+ if(p == NULL) {
+ if(default_binding) {
+ krb5_warnx(context, "WARNING: more than one realm-less "
+ "database specification");
+ krb5_warnx(context, "WARNING: using the first encountered");
+ } else
+ default_binding = db_binding;
+ continue;
+ }
+ if(strcmp(ctx->config.realm, p) != 0)
+ continue;
+
+ set_config(ctx, db_binding);
+ return 0;
+ }
+ if(default_binding)
+ set_config(ctx, default_binding);
+ else {
+ ctx->config.dbname = strdup(HDB_DEFAULT_DB);
+ ctx->config.acl_file = HDB_DB_DIR "/kadmind.acl";
+ ctx->config.stash_file = HDB_DB_DIR "/m-key";
+ ctx->log_context.log_file = HDB_DB_DIR "/log";
+ memset(&ctx->log_context.socket_name, 0,
+ sizeof(ctx->log_context.socket_name));
+ ctx->log_context.socket_name.sun_family = AF_UNIX;
+ strlcpy(ctx->log_context.socket_name.sun_path,
+ KADM5_LOG_SIGNAL,
+ sizeof(ctx->log_context.socket_name.sun_path));
+ }
+ return 0;
+}
+
+kadm5_ret_t
+_kadm5_s_init_context(kadm5_server_context **ctx,
+ kadm5_config_params *params,
+ krb5_context context)
+{
+ *ctx = malloc(sizeof(**ctx));
+ if(*ctx == NULL)
+ return ENOMEM;
+ memset(*ctx, 0, sizeof(**ctx));
+ set_funcs(*ctx);
+ (*ctx)->context = context;
+ krb5_add_et_list (context, initialize_kadm5_error_table_r);
+#define is_set(M) (params && params->mask & KADM5_CONFIG_ ## M)
+ if(is_set(REALM))
+ (*ctx)->config.realm = strdup(params->realm);
+ else
+ krb5_get_default_realm(context, &(*ctx)->config.realm);
+ if(is_set(DBNAME))
+ (*ctx)->config.dbname = strdup(params->dbname);
+ if(is_set(ACL_FILE))
+ (*ctx)->config.acl_file = strdup(params->acl_file);
+ if(is_set(STASH_FILE))
+ (*ctx)->config.stash_file = strdup(params->stash_file);
+
+ find_db_spec(*ctx);
+
+ /* PROFILE can't be specified for now */
+ /* KADMIND_PORT is supposed to be used on the server also,
+ but this doesn't make sense */
+ /* ADMIN_SERVER is client only */
+ /* ADNAME is not used at all (as far as I can tell) */
+ /* ADB_LOCKFILE ditto */
+ /* DICT_FILE */
+ /* ADMIN_KEYTAB */
+ /* MKEY_FROM_KEYBOARD is not supported */
+ /* MKEY_NAME neither */
+ /* ENCTYPE */
+ /* MAX_LIFE */
+ /* MAX_RLIFE */
+ /* EXPIRATION */
+ /* FLAGS */
+ /* ENCTYPES */
+
+ return 0;
+}
+
+HDB *
+_kadm5_s_get_db(void *server_handle)
+{
+ kadm5_server_context *context = server_handle;
+ return context->db;
+}
diff --git a/crypto/heimdal/lib/kadm5/create_c.c b/crypto/heimdal/lib/kadm5/create_c.c
new file mode 100644
index 000000000000..45eb3e212345
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/create_c.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: create_c.c,v 1.3 1999/12/02 17:05:05 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_create_principal(void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask,
+ char *password)
+{
+ kadm5_client_context *context = server_handle;
+ kadm5_ret_t ret;
+ krb5_storage *sp;
+ unsigned char buf[1024];
+ int32_t tmp;
+ krb5_data reply;
+
+ sp = krb5_storage_from_mem(buf, sizeof(buf));
+ if (sp == NULL)
+ return ENOMEM;
+ krb5_store_int32(sp, kadm_create);
+ kadm5_store_principal_ent(sp, princ);
+ krb5_store_int32(sp, mask);
+ krb5_store_string(sp, password);
+ ret = _kadm5_client_send(context, sp);
+ krb5_storage_free(sp);
+ ret = _kadm5_client_recv(context, &reply);
+ if(ret)
+ return ret;
+ sp = krb5_storage_from_data (&reply);
+ if (sp == NULL) {
+ krb5_data_free (&reply);
+ return ENOMEM;
+ }
+ krb5_ret_int32(sp, &tmp);
+ krb5_storage_free(sp);
+ krb5_data_free (&reply);
+ return tmp;
+}
+
diff --git a/crypto/heimdal/lib/kadm5/create_s.c b/crypto/heimdal/lib/kadm5/create_s.c
new file mode 100644
index 000000000000..6e352f6b9f55
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/create_s.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: create_s.c,v 1.16 1999/12/02 17:05:05 joda Exp $");
+
+static kadm5_ret_t
+get_default(kadm5_server_context *context, krb5_principal princ,
+ kadm5_principal_ent_t def)
+{
+ kadm5_ret_t ret;
+ krb5_principal def_principal;
+ krb5_realm *realm = krb5_princ_realm(context->context, princ);
+
+ ret = krb5_make_principal(context->context, &def_principal,
+ *realm, "default", NULL);
+ if (ret)
+ return ret;
+ ret = kadm5_s_get_principal(context, def_principal, def,
+ KADM5_PRINCIPAL_NORMAL_MASK);
+ krb5_free_principal (context->context, def_principal);
+ return ret;
+}
+
+static kadm5_ret_t
+create_principal(kadm5_server_context *context,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask,
+ hdb_entry *ent,
+ u_int32_t required_mask,
+ u_int32_t forbidden_mask)
+{
+ kadm5_ret_t ret;
+ kadm5_principal_ent_rec defrec, *defent;
+ u_int32_t def_mask;
+
+ if((mask & required_mask) != required_mask)
+ return KADM5_BAD_MASK;
+ if((mask & forbidden_mask))
+ return KADM5_BAD_MASK;
+ if((mask & KADM5_POLICY) && strcmp(princ->policy, "default"))
+ /* XXX no real policies for now */
+ return KADM5_UNK_POLICY;
+ memset(ent, 0, sizeof(*ent));
+ ret = krb5_copy_principal(context->context, princ->principal,
+ &ent->principal);
+ if(ret)
+ return ret;
+
+ defent = &defrec;
+ ret = get_default(context, princ->principal, defent);
+ if(ret) {
+ defent = NULL;
+ def_mask = 0;
+ } else {
+ def_mask = KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_MAX_RLIFE;
+ }
+
+ ret = _kadm5_setup_entry(ent, mask | def_mask,
+ princ, mask,
+ defent, def_mask);
+ if(defent)
+ kadm5_free_principal_ent(context, defent);
+
+ ent->created_by.time = time(NULL);
+ ret = krb5_copy_principal(context->context, context->caller,
+ &ent->created_by.principal);
+
+ return ret;
+}
+
+kadm5_ret_t
+kadm5_s_create_principal_with_key(void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask)
+{
+ kadm5_ret_t ret;
+ hdb_entry ent;
+ kadm5_server_context *context = server_handle;
+
+ ret = create_principal(context, princ, mask, &ent,
+ KADM5_PRINCIPAL | KADM5_KEY_DATA,
+ KADM5_LAST_PWD_CHANGE | KADM5_MOD_TIME
+ | KADM5_MOD_NAME | KADM5_MKVNO
+ | KADM5_AUX_ATTRIBUTES
+ | KADM5_POLICY_CLR | KADM5_LAST_SUCCESS
+ | KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT);
+ if(ret)
+ goto out;
+
+ ret = _kadm5_set_keys2(&ent, princ->n_key_data, princ->key_data);
+ if(ret)
+ goto out;
+
+ hdb_seal_keys(context->db, &ent);
+
+ kadm5_log_create (context, &ent);
+
+ ret = context->db->open(context->context, context->db, O_RDWR, 0);
+ if(ret)
+ goto out;
+ ret = context->db->store(context->context, context->db, 0, &ent);
+ context->db->close(context->context, context->db);
+out:
+ hdb_free_entry(context->context, &ent);
+ return _kadm5_error_code(ret);
+}
+
+
+kadm5_ret_t
+kadm5_s_create_principal(void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask,
+ char *password)
+{
+ kadm5_ret_t ret;
+ hdb_entry ent;
+ kadm5_server_context *context = server_handle;
+
+ ret = create_principal(context, princ, mask, &ent,
+ KADM5_PRINCIPAL,
+ KADM5_LAST_PWD_CHANGE | KADM5_MOD_TIME
+ | KADM5_MOD_NAME | KADM5_MKVNO
+ | KADM5_AUX_ATTRIBUTES | KADM5_KEY_DATA
+ | KADM5_POLICY_CLR | KADM5_LAST_SUCCESS
+ | KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT);
+ if(ret)
+ goto out;
+
+ /* XXX this should be fixed */
+ ent.keys.len = 4;
+ ent.keys.val = calloc(ent.keys.len, sizeof(*ent.keys.val));
+ ent.keys.val[0].key.keytype = ETYPE_DES_CBC_CRC;
+ /* flag as version 4 compatible salt; ignored by _kadm5_set_keys
+ if we don't want to be compatible */
+ ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt));
+ ent.keys.val[0].salt->type = hdb_pw_salt;
+ ent.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
+ ent.keys.val[1].salt = calloc(1, sizeof(*ent.keys.val[1].salt));
+ ent.keys.val[1].salt->type = hdb_pw_salt;
+ ent.keys.val[2].key.keytype = ETYPE_DES_CBC_MD5;
+ ent.keys.val[2].salt = calloc(1, sizeof(*ent.keys.val[2].salt));
+ ent.keys.val[2].salt->type = hdb_pw_salt;
+ ent.keys.val[3].key.keytype = ETYPE_DES3_CBC_SHA1;
+ ret = _kadm5_set_keys(context, &ent, password);
+
+ hdb_seal_keys(context->db, &ent);
+
+ kadm5_log_create (context, &ent);
+
+ ret = context->db->open(context->context, context->db, O_RDWR, 0);
+ if(ret)
+ goto out;
+ ret = context->db->store(context->context, context->db, 0, &ent);
+ context->db->close(context->context, context->db);
+out:
+ hdb_free_entry(context->context, &ent);
+ return _kadm5_error_code(ret);
+}
+
diff --git a/crypto/heimdal/lib/kadm5/delete_c.c b/crypto/heimdal/lib/kadm5/delete_c.c
new file mode 100644
index 000000000000..71a3cf0f9012
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/delete_c.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: delete_c.c,v 1.3 1999/12/02 17:05:05 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_delete_principal(void *server_handle, krb5_principal princ)
+{
+ kadm5_client_context *context = server_handle;
+ kadm5_ret_t ret;
+ krb5_storage *sp;
+ unsigned char buf[1024];
+ int32_t tmp;
+ krb5_data reply;
+
+ sp = krb5_storage_from_mem(buf, sizeof(buf));
+ if (sp == NULL)
+ return ENOMEM;
+ krb5_store_int32(sp, kadm_delete);
+ krb5_store_principal(sp, princ);
+ ret = _kadm5_client_send(context, sp);
+ krb5_storage_free(sp);
+ if (ret)
+ return ret;
+ ret = _kadm5_client_recv(context, &reply);
+ if (ret)
+ return ret;
+ sp = krb5_storage_from_data (&reply);
+ if(sp == NULL) {
+ krb5_data_free (&reply);
+ return ENOMEM;
+ }
+ krb5_ret_int32(sp, &tmp);
+ krb5_storage_free(sp);
+ krb5_data_free (&reply);
+ return tmp;
+}
diff --git a/crypto/heimdal/lib/kadm5/delete_s.c b/crypto/heimdal/lib/kadm5/delete_s.c
new file mode 100644
index 000000000000..ef326587bf02
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/delete_s.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: delete_s.c,v 1.7 1999/12/02 17:05:05 joda Exp $");
+
+kadm5_ret_t
+kadm5_s_delete_principal(void *server_handle, krb5_principal princ)
+{
+ kadm5_server_context *context = server_handle;
+ kadm5_ret_t ret;
+ hdb_entry ent;
+
+ ent.principal = princ;
+ ret = context->db->open(context->context, context->db, O_RDWR, 0);
+ if(ret) {
+ krb5_warn(context->context, ret, "opening database");
+ return ret;
+ }
+ ret = context->db->fetch(context->context, context->db,
+ HDB_F_DECRYPT, &ent);
+ if(ret == HDB_ERR_NOENTRY)
+ goto out2;
+ if(ent.flags.immutable) {
+ ret = KADM5_PROTECT_PRINCIPAL;
+ goto out;
+ }
+
+ hdb_seal_keys(context->db, &ent);
+
+ kadm5_log_delete (context, princ);
+
+ ret = context->db->remove(context->context, context->db, &ent);
+out:
+ hdb_free_entry(context->context, &ent);
+out2:
+ context->db->close(context->context, context->db);
+ return _kadm5_error_code(ret);
+}
diff --git a/crypto/heimdal/lib/kadm5/destroy_c.c b/crypto/heimdal/lib/kadm5/destroy_c.c
new file mode 100644
index 000000000000..b42c84ce796a
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/destroy_c.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: destroy_c.c,v 1.3 1999/12/02 17:05:05 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_destroy(void *server_handle)
+{
+ kadm5_client_context *context = server_handle;
+
+ free(context->realm);
+ free(context->admin_server);
+ close(context->sock);
+ if (context->ac != NULL)
+ krb5_auth_con_free(context->context, context->ac);
+ if(context->my_context)
+ krb5_free_context(context->context);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/destroy_s.c b/crypto/heimdal/lib/kadm5/destroy_s.c
new file mode 100644
index 000000000000..22158d0fa8e5
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/destroy_s.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: destroy_s.c,v 1.5 1999/12/02 17:05:05 joda Exp $");
+
+kadm5_ret_t
+kadm5_s_destroy(void *server_handle)
+{
+ kadm5_ret_t ret;
+ kadm5_server_context *context = server_handle;
+ krb5_context kcontext = context->context;
+
+ ret = context->db->destroy(kcontext, context->db);
+ if(context->my_context)
+ krb5_free_context(kcontext);
+ return ret;
+}
+
diff --git a/crypto/heimdal/lib/kadm5/dump_log.c b/crypto/heimdal/lib/kadm5/dump_log.c
new file mode 100644
index 000000000000..68a3f534dd6a
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/dump_log.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "iprop.h"
+#include "parse_time.h"
+
+RCSID("$Id: dump_log.c,v 1.9 1999/12/04 19:49:43 assar Exp $");
+
+static char *op_names[] = {
+ "get",
+ "delete",
+ "create",
+ "rename",
+ "chpass",
+ "modify",
+ "randkey",
+ "get_privs",
+ "get_princs"
+};
+
+static void
+print_entry(kadm5_server_context *server_context,
+ u_int32_t ver,
+ time_t timestamp,
+ enum kadm_ops op,
+ u_int32_t len,
+ krb5_storage *sp)
+{
+ char t[256];
+ u_int32_t mask;
+ hdb_entry ent;
+ krb5_principal source;
+ char *name1, *name2;
+ krb5_data data;
+ krb5_context context = server_context->context;
+
+ off_t end = sp->seek(sp, 0, SEEK_CUR) + len;
+
+ krb5_error_code ret;
+
+ strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S", localtime(&timestamp));
+
+ if(op < kadm_get || op > kadm_get_princs) {
+ printf("unknown op: %d\n", op);
+ sp->seek(sp, end, SEEK_SET);
+ return;
+ }
+
+ printf ("%s: ver = %u, timestamp = %s, len = %u\n",
+ op_names[op], ver, t, len);
+ switch(op) {
+ case kadm_delete:
+ krb5_ret_principal(sp, &source);
+ krb5_unparse_name(context, source, &name1);
+ printf(" %s\n", name1);
+ free(name1);
+ krb5_free_principal(context, source);
+ break;
+ case kadm_rename:
+ krb5_data_alloc(&data, len);
+ krb5_ret_principal(sp, &source);
+ sp->fetch(sp, data.data, data.length);
+ hdb_value2entry(context, &data, &ent);
+ krb5_unparse_name(context, source, &name1);
+ krb5_unparse_name(context, ent.principal, &name2);
+ printf(" %s -> %s\n", name1, name2);
+ free(name1);
+ free(name2);
+ krb5_free_principal(context, source);
+ hdb_free_entry(context, &ent);
+ break;
+ case kadm_create:
+ krb5_data_alloc(&data, len);
+ sp->fetch(sp, data.data, data.length);
+ ret = hdb_value2entry(context, &data, &ent);
+ if(ret)
+ abort();
+ mask = ~0;
+ goto foo;
+ case kadm_modify:
+ krb5_data_alloc(&data, len);
+ krb5_ret_int32(sp, &mask);
+ sp->fetch(sp, data.data, data.length);
+ ret = hdb_value2entry(context, &data, &ent);
+ if(ret)
+ abort();
+ foo:
+ if(ent.principal /* mask & KADM5_PRINCIPAL */) {
+ krb5_unparse_name(context, ent.principal, &name1);
+ printf(" principal = %s\n", name1);
+ free(name1);
+ }
+ if(mask & KADM5_PRINC_EXPIRE_TIME) {
+ if(ent.valid_end == NULL) {
+ strcpy(t, "never");
+ } else {
+ strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
+ localtime(ent.valid_end));
+ }
+ printf(" expires = %s\n", t);
+ }
+ if(mask & KADM5_PW_EXPIRATION) {
+ if(ent.valid_end == NULL) {
+ strcpy(t, "never");
+ } else {
+ strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
+ localtime(ent.valid_end));
+ }
+ printf(" password exp = %s\n", t);
+ }
+ if(mask & KADM5_LAST_PWD_CHANGE) {
+ }
+ if(mask & KADM5_ATTRIBUTES) {
+ unparse_flags(HDBFlags2int(ent.flags),
+ HDBFlags_units, t, sizeof(t));
+ printf(" attributes = %s\n", t);
+ }
+ if(mask & KADM5_MAX_LIFE) {
+ if(ent.max_life == NULL)
+ strcpy(t, "for ever");
+ else
+ unparse_time(*ent.max_life, t, sizeof(t));
+ printf(" max life = %s\n", t);
+ }
+ if(mask & KADM5_MAX_RLIFE) {
+ if(ent.max_renew == NULL)
+ strcpy(t, "for ever");
+ else
+ unparse_time(*ent.max_renew, t, sizeof(t));
+ printf(" max rlife = %s\n", t);
+ }
+ if(mask & KADM5_MOD_TIME) {
+ printf(" mod time\n");
+ }
+ if(mask & KADM5_MOD_NAME) {
+ printf(" mod name\n");
+ }
+ if(mask & KADM5_KVNO) {
+ printf(" kvno = %d\n", ent.kvno);
+ }
+ if(mask & KADM5_MKVNO) {
+ printf(" mkvno\n");
+ }
+ if(mask & KADM5_AUX_ATTRIBUTES) {
+ printf(" aux attributes\n");
+ }
+ if(mask & KADM5_POLICY) {
+ printf(" policy\n");
+ }
+ if(mask & KADM5_POLICY_CLR) {
+ printf(" mod time\n");
+ }
+ if(mask & KADM5_LAST_SUCCESS) {
+ printf(" last success\n");
+ }
+ if(mask & KADM5_LAST_FAILED) {
+ printf(" last failed\n");
+ }
+ if(mask & KADM5_FAIL_AUTH_COUNT) {
+ printf(" fail auth count\n");
+ }
+ if(mask & KADM5_KEY_DATA) {
+ printf(" key data\n");
+ }
+ if(mask & KADM5_TL_DATA) {
+ printf(" tl data\n");
+ }
+ hdb_free_entry(context, &ent);
+ break;
+ default:
+ abort();
+ }
+ sp->seek(sp, end, SEEK_SET);
+}
+
+char *realm;
+int version_flag;
+int help_flag;
+struct getargs args[] = {
+ { "realm", 'r', arg_string, &realm },
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+int num_args = sizeof(args) / sizeof(args[0]);
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ void *kadm_handle;
+ kadm5_server_context *server_context;
+ kadm5_config_params conf;
+
+ krb5_program_setup(&context, argc, argv, args, num_args, NULL);
+
+ if(help_flag)
+ krb5_std_usage(0, args, num_args);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ memset(&conf, 0, sizeof(conf));
+ if(realm) {
+ conf.mask |= KADM5_CONFIG_REALM;
+ conf.realm = realm;
+ }
+ ret = kadm5_init_with_password_ctx (context,
+ KADM5_ADMIN_SERVICE,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm_handle);
+ if (ret)
+ krb5_err (context, 1, ret, "kadm5_init_with_password_ctx");
+
+ server_context = (kadm5_server_context *)kadm_handle;
+
+ ret = kadm5_log_init (server_context);
+ if (ret)
+ krb5_err (context, 1, ret, "kadm5_log_init");
+
+ ret = kadm5_log_foreach (server_context, print_entry);
+ if(ret)
+ krb5_warn(context, ret, "kadm5_log_foreach");
+
+ ret = kadm5_log_end (server_context);
+ if (ret)
+ krb5_warn(context, ret, "kadm5_log_end");
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/ent_setup.c b/crypto/heimdal/lib/kadm5/ent_setup.c
new file mode 100644
index 000000000000..46653c7cbbd6
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/ent_setup.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: ent_setup.c,v 1.11 1999/12/02 17:05:06 joda Exp $");
+
+#define set_value(X, V) do { if((X) == NULL) (X) = malloc(sizeof(*(X))); *(X) = V; } while(0)
+#define set_null(X) do { if((X) != NULL) free((X)); (X) = NULL; } while (0)
+
+static void
+attr_to_flags(unsigned attr, HDBFlags *flags)
+{
+ flags->postdate = !(attr & KRB5_KDB_DISALLOW_POSTDATED);
+ flags->forwardable = !(attr & KRB5_KDB_DISALLOW_FORWARDABLE);
+ flags->initial = !!(attr & KRB5_KDB_DISALLOW_TGT_BASED);
+ flags->renewable = !(attr & KRB5_KDB_DISALLOW_RENEWABLE);
+ flags->proxiable = !(attr & KRB5_KDB_DISALLOW_PROXIABLE);
+ /* DUP_SKEY */
+ flags->invalid = !!(attr & KRB5_KDB_DISALLOW_ALL_TIX);
+ flags->require_preauth = !!(attr & KRB5_KDB_REQUIRES_PRE_AUTH);
+ /* HW_AUTH */
+ flags->server = !(attr & KRB5_KDB_DISALLOW_SVR);
+ flags->change_pw = !!(attr & KRB5_KDB_PWCHANGE_SERVICE);
+ flags->client = 1; /* XXX */
+}
+
+/*
+ * Create the hdb entry `ent' based on data from `princ' with
+ * `princ_mask' specifying what fields to be gotten from there and
+ * `mask' specifying what fields we want filled in.
+ */
+
+kadm5_ret_t
+_kadm5_setup_entry(hdb_entry *ent,
+ u_int32_t mask,
+ kadm5_principal_ent_t princ,
+ u_int32_t princ_mask,
+ kadm5_principal_ent_t def,
+ u_int32_t def_mask)
+{
+ if(mask & KADM5_PRINC_EXPIRE_TIME
+ && princ_mask & KADM5_PRINC_EXPIRE_TIME) {
+ if (princ->princ_expire_time)
+ set_value(ent->valid_end, princ->princ_expire_time);
+ else
+ set_null(ent->valid_end);
+ }
+ if(mask & KADM5_PW_EXPIRATION
+ && princ_mask & KADM5_PW_EXPIRATION) {
+ if (princ->pw_expiration)
+ set_value(ent->pw_end, princ->pw_expiration);
+ else
+ set_null(ent->pw_end);
+ }
+ if(mask & KADM5_ATTRIBUTES) {
+ if (princ_mask & KADM5_ATTRIBUTES) {
+ attr_to_flags(princ->attributes, &ent->flags);
+ } else if(def_mask & KADM5_ATTRIBUTES) {
+ attr_to_flags(def->attributes, &ent->flags);
+ ent->flags.invalid = 0;
+ } else {
+ ent->flags.client = 1;
+ ent->flags.server = 1;
+ ent->flags.forwardable = 1;
+ ent->flags.proxiable = 1;
+ ent->flags.renewable = 1;
+ ent->flags.postdate = 1;
+ }
+ }
+ if(mask & KADM5_MAX_LIFE) {
+ if(princ_mask & KADM5_MAX_LIFE) {
+ if(princ->max_life)
+ set_value(ent->max_life, princ->max_life);
+ else
+ set_null(ent->max_life);
+ } else if(def_mask & KADM5_MAX_LIFE) {
+ if(def->max_life)
+ set_value(ent->max_life, def->max_life);
+ else
+ set_null(ent->max_life);
+ }
+ }
+ if(mask & KADM5_KVNO
+ && princ_mask & KADM5_KVNO)
+ ent->kvno = princ->kvno;
+ if(mask & KADM5_MAX_RLIFE) {
+ if(princ_mask & KADM5_MAX_RLIFE) {
+ if(princ->max_renewable_life)
+ set_value(ent->max_renew, princ->max_renewable_life);
+ else
+ set_null(ent->max_renew);
+ } else if(def_mask & KADM5_MAX_RLIFE) {
+ if(def->max_renewable_life)
+ set_value(ent->max_renew, def->max_renewable_life);
+ else
+ set_null(ent->max_renew);
+ }
+ }
+ if(mask & KADM5_KEY_DATA
+ && princ_mask & KADM5_KEY_DATA) {
+ _kadm5_set_keys2(ent, princ->n_key_data, princ->key_data);
+ }
+ if(mask & KADM5_TL_DATA) {
+ /* XXX */
+ }
+ if(mask & KADM5_FAIL_AUTH_COUNT) {
+ /* XXX */
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/error.c b/crypto/heimdal/lib/kadm5/error.c
new file mode 100644
index 000000000000..11b1ded7d875
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/error.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: error.c,v 1.3 1999/12/02 17:05:06 joda Exp $");
+
+kadm5_ret_t
+_kadm5_error_code(kadm5_ret_t code)
+{
+ switch(code){
+ case HDB_ERR_EXISTS:
+ return KADM5_DUP;
+ case HDB_ERR_NOENTRY:
+ return KADM5_UNK_PRINC;
+ }
+ return code;
+}
diff --git a/crypto/heimdal/lib/kadm5/flush.c b/crypto/heimdal/lib/kadm5/flush.c
new file mode 100644
index 000000000000..4808259de7f8
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/flush.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: flush.c,v 1.2 1999/12/02 17:05:06 joda Exp $");
+
+kadm5_ret_t
+kadm5_s_flush(void *server_handle)
+{
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_c_flush(void *server_handle)
+{
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/flush_c.c b/crypto/heimdal/lib/kadm5/flush_c.c
new file mode 100644
index 000000000000..01cdcf723aa1
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/flush_c.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: flush_c.c,v 1.1 1999/03/23 18:23:36 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_flush(void *server_handle)
+{
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/flush_s.c b/crypto/heimdal/lib/kadm5/flush_s.c
new file mode 100644
index 000000000000..dffbe2f2ca9b
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/flush_s.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: flush_s.c,v 1.1 1999/03/23 18:23:37 joda Exp $");
+
+kadm5_ret_t
+kadm5_s_flush(void *server_handle)
+{
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/free.c b/crypto/heimdal/lib/kadm5/free.c
new file mode 100644
index 000000000000..fcc1e70f0d8e
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/free.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: free.c,v 1.4 1999/12/02 17:05:06 joda Exp $");
+
+void
+kadm5_free_key_data(void *server_handle,
+ int16_t *n_key_data,
+ krb5_key_data *key_data)
+{
+ int i;
+ for(i = 0; i < *n_key_data; i++){
+ if(key_data[i].key_data_contents[0]){
+ memset(key_data[i].key_data_contents[0],
+ 0,
+ key_data[i].key_data_length[0]);
+ free(key_data[i].key_data_contents[0]);
+ }
+ if(key_data[i].key_data_contents[1])
+ free(key_data[i].key_data_contents[1]);
+ }
+ *n_key_data = 0;
+}
+
+
+void
+kadm5_free_principal_ent(void *server_handle,
+ kadm5_principal_ent_t princ)
+{
+ kadm5_server_context *context = server_handle;
+ if(princ->principal)
+ krb5_free_principal(context->context, princ->principal);
+ if(princ->mod_name)
+ krb5_free_principal(context->context, princ->mod_name);
+ kadm5_free_key_data(server_handle, &princ->n_key_data, princ->key_data);
+ while(princ->n_tl_data && princ->tl_data) {
+ krb5_tl_data *tp;
+ tp = princ->tl_data;
+ princ->tl_data = tp->tl_data_next;
+ princ->n_tl_data--;
+ memset(tp->tl_data_contents, 0, tp->tl_data_length);
+ free(tp->tl_data_contents);
+ free(tp);
+ }
+ if (princ->key_data != NULL)
+ free (princ->key_data);
+}
+
+void
+kadm5_free_name_list(void *server_handle,
+ char **names,
+ int *count)
+{
+ int i;
+ for(i = 0; i < *count; i++)
+ free(names[i]);
+ free(names);
+ *count = 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/get_c.c b/crypto/heimdal/lib/kadm5/get_c.c
new file mode 100644
index 000000000000..9ca672a5e7e1
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/get_c.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: get_c.c,v 1.5 1999/12/02 17:05:06 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_get_principal(void *server_handle,
+ krb5_principal princ,
+ kadm5_principal_ent_t out,
+ u_int32_t mask)
+{
+ kadm5_client_context *context = server_handle;
+ kadm5_ret_t ret;
+ krb5_storage *sp;
+ unsigned char buf[1024];
+ int32_t tmp;
+ krb5_data reply;
+
+ sp = krb5_storage_from_mem(buf, sizeof(buf));
+ if (sp == NULL)
+ return ENOMEM;
+ krb5_store_int32(sp, kadm_get);
+ krb5_store_principal(sp, princ);
+ krb5_store_int32(sp, mask);
+ ret = _kadm5_client_send(context, sp);
+ krb5_storage_free(sp);
+ if(ret)
+ return ret;
+ ret = _kadm5_client_recv(context, &reply);
+ if (ret)
+ return ret;
+ sp = krb5_storage_from_data (&reply);
+ if (sp == NULL) {
+ krb5_data_free (&reply);
+ return ENOMEM;
+ }
+ krb5_ret_int32(sp, &tmp);
+ ret = tmp;
+ if(ret == 0)
+ kadm5_ret_principal_ent(sp, out);
+ krb5_storage_free(sp);
+ krb5_data_free (&reply);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/kadm5/get_princs_c.c b/crypto/heimdal/lib/kadm5/get_princs_c.c
new file mode 100644
index 000000000000..0956052272d9
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/get_princs_c.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: get_princs_c.c,v 1.3 1999/12/02 17:05:06 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_get_principals(void *server_handle,
+ const char *exp,
+ char ***princs,
+ int *count)
+{
+ kadm5_client_context *context = server_handle;
+ kadm5_ret_t ret;
+ krb5_storage *sp;
+ unsigned char buf[1024];
+ int32_t tmp;
+ krb5_data reply;
+
+ sp = krb5_storage_from_mem(buf, sizeof(buf));
+ if (sp == NULL)
+ return ENOMEM;
+ krb5_store_int32(sp, kadm_get_princs);
+ krb5_store_int32(sp, exp != NULL);
+ if(exp)
+ krb5_store_string(sp, exp);
+ ret = _kadm5_client_send(context, sp);
+ krb5_storage_free(sp);
+ ret = _kadm5_client_recv(context, &reply);
+ if(ret)
+ return ret;
+ sp = krb5_storage_from_data (&reply);
+ if (sp == NULL) {
+ krb5_data_free (&reply);
+ return ENOMEM;
+ }
+ krb5_ret_int32(sp, &tmp);
+ ret = tmp;
+ if(ret == 0) {
+ int i;
+ krb5_ret_int32(sp, &tmp);
+ *princs = calloc(tmp + 1, sizeof(**princs));
+ if (*princs == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ for(i = 0; i < tmp; i++)
+ krb5_ret_string(sp, &(*princs)[i]);
+ *count = tmp;
+ }
+out:
+ krb5_storage_free(sp);
+ krb5_data_free (&reply);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/kadm5/get_princs_s.c b/crypto/heimdal/lib/kadm5/get_princs_s.c
new file mode 100644
index 000000000000..2702bae46131
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/get_princs_s.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: get_princs_s.c,v 1.5 1999/12/02 17:05:06 joda Exp $");
+
+struct foreach_data {
+ const char *exp;
+ char *exp2;
+ char **princs;
+ int count;
+};
+
+static krb5_error_code
+add_princ(struct foreach_data *d, char *princ)
+{
+ char **tmp;
+ tmp = realloc(d->princs, (d->count + 1) * sizeof(*tmp));
+ if(tmp == NULL)
+ return ENOMEM;
+ d->princs = tmp;
+ d->princs[d->count++] = princ;
+ return 0;
+}
+
+static krb5_error_code
+foreach(krb5_context context, HDB *db, hdb_entry *ent, void *data)
+{
+ struct foreach_data *d = data;
+ char *princ;
+ krb5_error_code ret;
+ ret = krb5_unparse_name(context, ent->principal, &princ);
+ if(ret)
+ return ret;
+ if(d->exp){
+ if(fnmatch(d->exp, princ, 0) == 0 || fnmatch(d->exp2, princ, 0) == 0)
+ ret = add_princ(d, princ);
+ else
+ free(princ);
+ }else{
+ ret = add_princ(d, princ);
+ }
+ if(ret)
+ free(princ);
+ return ret;
+}
+
+kadm5_ret_t
+kadm5_s_get_principals(void *server_handle,
+ const char *exp,
+ char ***princs,
+ int *count)
+{
+ struct foreach_data d;
+ kadm5_server_context *context = server_handle;
+ kadm5_ret_t ret;
+ ret = context->db->open(context->context, context->db, O_RDWR, 0);
+ if(ret) {
+ krb5_warn(context->context, ret, "opening database");
+ return ret;
+ }
+ d.exp = exp;
+ {
+ krb5_realm r;
+ krb5_get_default_realm(context->context, &r);
+ asprintf(&d.exp2, "%s@%s", exp, r);
+ free(r);
+ }
+ d.princs = NULL;
+ d.count = 0;
+ ret = hdb_foreach(context->context, context->db, 0, foreach, &d);
+ context->db->close(context->context, context->db);
+ if(ret == 0)
+ ret = add_princ(&d, NULL);
+ if(ret == 0){
+ *princs = d.princs;
+ *count = d.count - 1;
+ }else
+ kadm5_free_name_list(context, d.princs, &d.count);
+ free(d.exp2);
+ return _kadm5_error_code(ret);
+}
diff --git a/crypto/heimdal/lib/kadm5/get_s.c b/crypto/heimdal/lib/kadm5/get_s.c
new file mode 100644
index 000000000000..12613b6b6d46
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/get_s.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: get_s.c,v 1.11 1999/12/26 19:38:23 assar Exp $");
+
+kadm5_ret_t
+kadm5_s_get_principal(void *server_handle,
+ krb5_principal princ,
+ kadm5_principal_ent_t out,
+ u_int32_t mask)
+{
+ kadm5_server_context *context = server_handle;
+ kadm5_ret_t ret;
+ hdb_entry ent;
+
+ ent.principal = princ;
+ ret = context->db->open(context->context, context->db, O_RDONLY, 0);
+ if(ret)
+ return ret;
+ ret = context->db->fetch(context->context, context->db,
+ HDB_F_DECRYPT, &ent);
+ context->db->close(context->context, context->db);
+ if(ret)
+ return _kadm5_error_code(ret);
+
+ memset(out, 0, sizeof(*out));
+ if(mask & KADM5_PRINCIPAL)
+ ret = krb5_copy_principal(context->context, ent.principal,
+ &out->principal);
+ if(ret)
+ goto out;
+ if(mask & KADM5_PRINC_EXPIRE_TIME && ent.valid_end)
+ out->princ_expire_time = *ent.valid_end;
+ if(mask & KADM5_PW_EXPIRATION && ent.pw_end)
+ out->pw_expiration = *ent.pw_end;
+ if(mask & KADM5_LAST_PWD_CHANGE)
+ /* XXX implement */;
+ if(mask & KADM5_ATTRIBUTES){
+ out->attributes |= ent.flags.postdate ? 0 : KRB5_KDB_DISALLOW_POSTDATED;
+ out->attributes |= ent.flags.forwardable ? 0 : KRB5_KDB_DISALLOW_FORWARDABLE;
+ out->attributes |= ent.flags.initial ? KRB5_KDB_DISALLOW_TGT_BASED : 0;
+ out->attributes |= ent.flags.renewable ? 0 : KRB5_KDB_DISALLOW_RENEWABLE;
+ out->attributes |= ent.flags.proxiable ? 0 : KRB5_KDB_DISALLOW_PROXIABLE;
+ out->attributes |= ent.flags.invalid ? KRB5_KDB_DISALLOW_ALL_TIX : 0;
+ out->attributes |= ent.flags.require_preauth ? KRB5_KDB_REQUIRES_PRE_AUTH : 0;
+ out->attributes |= ent.flags.server ? 0 : KRB5_KDB_DISALLOW_SVR;
+ out->attributes |= ent.flags.change_pw ? KRB5_KDB_PWCHANGE_SERVICE : 0;
+ }
+ if(mask & KADM5_MAX_LIFE && ent.max_life)
+ out->max_life = *ent.max_life;
+ if(mask & KADM5_MOD_TIME) {
+ if(ent.modified_by)
+ out->mod_date = ent.modified_by->time;
+ else
+ out->mod_date = ent.created_by.time;
+ }
+ if(mask & KADM5_MOD_NAME) {
+ if(ent.modified_by) {
+ if (ent.modified_by->principal != NULL)
+ ret = krb5_copy_principal(context->context,
+ ent.modified_by->principal,
+ &out->mod_name);
+ } else
+ ret = krb5_copy_principal(context->context,
+ ent.created_by.principal,
+ &out->mod_name);
+ }
+ if(ret)
+ goto out;
+
+ if(mask & KADM5_KVNO)
+ out->kvno = ent.kvno;
+ if(mask & KADM5_MKVNO) {
+ int n;
+ out->mkvno = 0; /* XXX */
+ for(n = 0; n < ent.keys.len; n++)
+ if(ent.keys.val[n].mkvno) {
+ out->mkvno = *ent.keys.val[n].mkvno; /* XXX this isn't right */
+ break;
+ }
+ }
+ if(mask & KADM5_AUX_ATTRIBUTES)
+ /* XXX implement */;
+ if(mask & KADM5_POLICY)
+ out->policy = NULL;
+ if(mask & KADM5_MAX_RLIFE && ent.max_renew)
+ out->max_renewable_life = *ent.max_renew;
+ if(mask & KADM5_LAST_SUCCESS)
+ /* XXX implement */;
+ if(mask & KADM5_LAST_FAILED)
+ /* XXX implement */;
+ if(mask & KADM5_FAIL_AUTH_COUNT)
+ /* XXX implement */;
+ if(mask & KADM5_KEY_DATA){
+ int i;
+ Key *key;
+ krb5_key_data *kd;
+ krb5_salt salt;
+ krb5_data *sp;
+ krb5_get_pw_salt(context->context, ent.principal, &salt);
+ out->key_data = malloc(ent.keys.len * sizeof(*out->key_data));
+ for(i = 0; i < ent.keys.len; i++){
+ key = &ent.keys.val[i];
+ kd = &out->key_data[i];
+ kd->key_data_ver = 2;
+ kd->key_data_kvno = ent.kvno;
+ kd->key_data_type[0] = key->key.keytype;
+ if(key->salt)
+ kd->key_data_type[1] = key->salt->type;
+ else
+ kd->key_data_type[1] = pa_pw_salt;
+ /* setup key */
+ kd->key_data_length[0] = key->key.keyvalue.length;
+ kd->key_data_contents[0] = malloc(kd->key_data_length[0]);
+ if(kd->key_data_contents[0] == NULL){
+ ret = ENOMEM;
+ break;
+ }
+ memcpy(kd->key_data_contents[0], key->key.keyvalue.data,
+ kd->key_data_length[0]);
+ /* setup salt */
+ if(key->salt)
+ sp = &key->salt->salt;
+ else
+ sp = &salt.saltvalue;
+ kd->key_data_length[1] = sp->length;
+ kd->key_data_contents[1] = malloc(kd->key_data_length[1]);
+ if(kd->key_data_length[1] != 0
+ && kd->key_data_contents[1] == NULL) {
+ memset(kd->key_data_contents[0], 0, kd->key_data_length[0]);
+ ret = ENOMEM;
+ break;
+ }
+ memcpy(kd->key_data_contents[1], sp->data, kd->key_data_length[1]);
+ out->n_key_data = i + 1;
+ }
+ krb5_free_salt(context->context, salt);
+ }
+ if(ret){
+ kadm5_free_principal_ent(context, out);
+ goto out;
+ }
+ if(mask & KADM5_TL_DATA)
+ /* XXX implement */;
+out:
+ hdb_free_entry(context->context, &ent);
+
+ return _kadm5_error_code(ret);
+}
diff --git a/crypto/heimdal/lib/kadm5/init_c.c b/crypto/heimdal/lib/kadm5/init_c.c
new file mode 100644
index 000000000000..f6429df48199
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/init_c.c
@@ -0,0 +1,602 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+RCSID("$Id: init_c.c,v 1.34 1999/12/20 14:05:49 assar Exp $");
+
+static void
+set_funcs(kadm5_client_context *c)
+{
+#define SET(C, F) (C)->funcs.F = kadm5 ## _c_ ## F
+ SET(c, chpass_principal);
+ SET(c, chpass_principal);
+ SET(c, create_principal);
+ SET(c, delete_principal);
+ SET(c, destroy);
+ SET(c, flush);
+ SET(c, get_principal);
+ SET(c, get_principals);
+ SET(c, get_privs);
+ SET(c, modify_principal);
+ SET(c, randkey_principal);
+ SET(c, rename_principal);
+}
+
+kadm5_ret_t
+_kadm5_c_init_context(kadm5_client_context **ctx,
+ kadm5_config_params *params,
+ krb5_context context)
+{
+ krb5_error_code ret;
+ char *colon;
+
+ *ctx = malloc(sizeof(**ctx));
+ if(*ctx == NULL)
+ return ENOMEM;
+ memset(*ctx, 0, sizeof(**ctx));
+ krb5_add_et_list (context, initialize_kadm5_error_table_r);
+ set_funcs(*ctx);
+ (*ctx)->context = context;
+ if(params->mask & KADM5_CONFIG_REALM)
+ (*ctx)->realm = strdup(params->realm);
+ else
+ krb5_get_default_realm((*ctx)->context, &(*ctx)->realm);
+ if(params->mask & KADM5_CONFIG_ADMIN_SERVER)
+ (*ctx)->admin_server = strdup(params->admin_server);
+ else {
+ char **hostlist;
+
+ ret = krb5_get_krb_admin_hst (context, &(*ctx)->realm, &hostlist);
+ if (ret)
+ return ret;
+ (*ctx)->admin_server = strdup(*hostlist);
+ krb5_free_krbhst (context, hostlist);
+ }
+
+ if ((*ctx)->admin_server == NULL)
+ return ENOMEM;
+ colon = strchr ((*ctx)->admin_server, ':');
+ if (colon != NULL)
+ *colon++ = '\0';
+
+ (*ctx)->kadmind_port = 0;
+
+ if(params->mask & KADM5_CONFIG_KADMIND_PORT)
+ (*ctx)->kadmind_port = params->kadmind_port;
+ else if (colon != NULL) {
+ char *end;
+
+ (*ctx)->kadmind_port = htons(strtol (colon, &end, 0));
+ }
+ if ((*ctx)->kadmind_port == 0)
+ (*ctx)->kadmind_port = krb5_getportbyname (context, "kerberos-adm",
+ "tcp", 749);
+ return 0;
+}
+
+static krb5_error_code
+get_kadm_ticket(krb5_context context,
+ krb5_ccache id,
+ krb5_principal client,
+ const char *server_name)
+{
+ krb5_error_code ret;
+ krb5_creds in, *out;
+
+ memset(&in, 0, sizeof(in));
+ in.client = client;
+ ret = krb5_parse_name(context, server_name, &in.server);
+ if(ret)
+ return ret;
+ ret = krb5_get_credentials(context, 0, id, &in, &out);
+ if(ret == 0)
+ krb5_free_creds(context, out);
+ krb5_free_principal(context, in.server);
+ return ret;
+}
+
+static krb5_error_code
+get_new_cache(krb5_context context,
+ krb5_principal client,
+ const char *password,
+ krb5_prompter_fct prompter,
+ const char *keytab,
+ const char *server_name,
+ krb5_ccache *ret_cache)
+{
+ krb5_error_code ret;
+ krb5_creds cred;
+ krb5_get_init_creds_opt opt;
+ krb5_ccache id;
+
+ krb5_get_init_creds_opt_init (&opt);
+ if(password == NULL && prompter == NULL) {
+ krb5_keytab kt;
+ if(keytab == NULL)
+ ret = krb5_kt_default(context, &kt);
+ else
+ ret = krb5_kt_resolve(context, keytab, &kt);
+ if(ret)
+ return ret;
+ ret = krb5_get_init_creds_keytab (context,
+ &cred,
+ client,
+ kt,
+ 0,
+ server_name,
+ &opt);
+ krb5_kt_close(context, kt);
+ } else {
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ client,
+ password,
+ prompter,
+ NULL,
+ 0,
+ server_name,
+ &opt);
+ }
+ switch(ret){
+ case 0:
+ break;
+ case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */
+ case KRB5KRB_AP_ERR_BAD_INTEGRITY:
+ case KRB5KRB_AP_ERR_MODIFIED:
+ return KADM5_BAD_PASSWORD;
+ default:
+ return ret;
+ }
+ ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &id);
+ if(ret)
+ return ret;
+ ret = krb5_cc_initialize (context, id, cred.client);
+ if (ret)
+ return ret;
+ ret = krb5_cc_store_cred (context, id, &cred);
+ if (ret)
+ return ret;
+ krb5_free_creds_contents (context, &cred);
+ *ret_cache = id;
+ return 0;
+}
+
+static krb5_error_code
+get_cred_cache(krb5_context context,
+ const char *client_name,
+ const char *server_name,
+ const char *password,
+ krb5_prompter_fct prompter,
+ const char *keytab,
+ krb5_ccache ccache,
+ krb5_ccache *ret_cache)
+{
+ krb5_error_code ret;
+ krb5_ccache id = NULL;
+ krb5_principal default_client = NULL, client = NULL;
+
+ /* treat empty password as NULL */
+ if(password && *password == '\0')
+ password = NULL;
+ if(server_name == NULL)
+ server_name = KADM5_ADMIN_SERVICE;
+
+ if(client_name != NULL) {
+ ret = krb5_parse_name(context, client_name, &client);
+ if(ret)
+ return ret;
+ }
+
+ if(password != NULL || prompter != NULL) {
+ /* get principal from default cache, ok if this doesn't work */
+ ret = krb5_cc_default(context, &id);
+ if(ret == 0) {
+ ret = krb5_cc_get_principal(context, id, &default_client);
+ if(ret) {
+ krb5_cc_close(context, id);
+ id = NULL;
+ }
+ }
+
+ if(client == NULL)
+ client = default_client;
+ if(client == NULL) {
+ const char *user;
+
+ user = get_default_username ();
+
+ if(user == NULL)
+ return KADM5_FAILURE;
+ ret = krb5_make_principal(context, &client,
+ NULL, user, "admin", NULL);
+ if(ret)
+ return ret;
+ }
+ if(client != default_client) {
+ krb5_free_principal(context, default_client);
+ default_client = NULL;
+ if (id != NULL) {
+ krb5_cc_close(context, id);
+ id = NULL;
+ }
+ }
+ } else if(ccache != NULL)
+ id = ccache;
+
+
+ if(id && (default_client == NULL ||
+ krb5_principal_compare(context, client, default_client))) {
+ ret = get_kadm_ticket(context, id, client, server_name);
+ if(ret == 0) {
+ *ret_cache = id;
+ krb5_free_principal(context, default_client);
+ if (default_client != client)
+ krb5_free_principal(context, client);
+ return 0;
+ }
+ if(ccache != NULL)
+ /* couldn't get ticket from cache */
+ return -1;
+ }
+ /* get creds via AS request */
+ if(id)
+ krb5_cc_close(context, id);
+ if (client != default_client)
+ krb5_free_principal(context, default_client);
+
+ ret = get_new_cache(context, client, password, prompter, keytab,
+ server_name, ret_cache);
+ krb5_free_principal(context, client);
+ return ret;
+}
+
+static kadm5_ret_t
+kadm5_c_init_with_context(krb5_context context,
+ const char *client_name,
+ const char *password,
+ krb5_prompter_fct prompter,
+ const char *keytab,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ kadm5_ret_t ret;
+ kadm5_client_context *ctx;
+ krb5_principal server;
+ krb5_ccache cc;
+ int s;
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char portstr[NI_MAXSERV];
+ char *hostname, *slash;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ ret = _kadm5_c_init_context(&ctx, realm_params, context);
+ if(ret)
+ return ret;
+
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(ctx->kadmind_port));
+
+ hostname = ctx->admin_server;
+ slash = strchr (hostname, '/');
+ if (slash != NULL)
+ hostname = slash + 1;
+
+ error = getaddrinfo (hostname, portstr, &hints, &ai);
+ if (error)
+ return KADM5_BAD_SERVER_NAME;
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0)
+ continue;
+ if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
+ krb5_warn (context, errno, "connect(%s)", hostname);
+ close (s);
+ continue;
+ }
+ break;
+ }
+ if (a == NULL) {
+ freeaddrinfo (ai);
+ krb5_warnx (context, "failed to contact %s", hostname);
+ return KADM5_FAILURE;
+ }
+ ret = get_cred_cache(context, client_name, service_name,
+ password, prompter, keytab, ccache, &cc);
+
+ if(ret) {
+ freeaddrinfo (ai);
+ close(s);
+ return ret;
+ }
+ ret = krb5_parse_name(context, KADM5_ADMIN_SERVICE, &server);
+ if(ret) {
+ freeaddrinfo (ai);
+ if(ccache == NULL)
+ krb5_cc_close(context, cc);
+ close(s);
+ return ret;
+ }
+ ctx->ac = NULL;
+
+ ret = krb5_sendauth(context, &ctx->ac, &s,
+ KADMIN_APPL_VERSION, NULL,
+ server, AP_OPTS_MUTUAL_REQUIRED,
+ NULL, NULL, cc, NULL, NULL, NULL);
+ if(ret == 0) {
+ krb5_data params, enc_data;
+ ret = _kadm5_marshal_params(context, realm_params, &params);
+
+ ret = krb5_mk_priv(context,
+ ctx->ac,
+ &params,
+ &enc_data,
+ NULL);
+
+ ret = krb5_write_message(context, &s, &enc_data);
+
+ krb5_data_free(&params);
+ krb5_data_free(&enc_data);
+ } else if(ret == KRB5_SENDAUTH_BADAPPLVERS) {
+ close(s);
+
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0) {
+ freeaddrinfo (ai);
+ return errno;
+ }
+ if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
+ close (s);
+ freeaddrinfo (ai);
+ return errno;
+ }
+ freeaddrinfo (ai);
+
+ ret = krb5_sendauth(context, &ctx->ac, &s,
+ KADMIN_OLD_APPL_VERSION, NULL,
+ server, AP_OPTS_MUTUAL_REQUIRED,
+ NULL, NULL, cc, NULL, NULL, NULL);
+ }
+ freeaddrinfo (ai);
+ if(ret) {
+ close(s);
+ return ret;
+ }
+
+ krb5_free_principal(context, server);
+ if(ccache == NULL)
+ krb5_cc_close(context, cc);
+ if(ret) {
+ close(s);
+ return ret;
+ }
+ ctx->sock = s;
+ *server_handle = ctx;
+ return 0;
+}
+
+static kadm5_ret_t
+init_context(const char *client_name,
+ const char *password,
+ krb5_prompter_fct prompter,
+ const char *keytab,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ krb5_context context;
+ kadm5_ret_t ret;
+ kadm5_server_context *ctx;
+
+ krb5_init_context(&context);
+ ret = kadm5_c_init_with_context(context,
+ client_name,
+ password,
+ prompter,
+ keytab,
+ ccache,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+ if(ret){
+ krb5_free_context(context);
+ return ret;
+ }
+ ctx = *server_handle;
+ ctx->my_context = 1;
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_c_init_with_password_ctx(krb5_context context,
+ const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_c_init_with_context(context,
+ client_name,
+ password,
+ krb5_prompter_posix,
+ NULL,
+ NULL,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_c_init_with_password(const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return init_context(client_name,
+ password,
+ krb5_prompter_posix,
+ NULL,
+ NULL,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_c_init_with_skey_ctx(krb5_context context,
+ const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_c_init_with_context(context,
+ client_name,
+ NULL,
+ NULL,
+ keytab,
+ NULL,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+
+kadm5_ret_t
+kadm5_c_init_with_skey(const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return init_context(client_name,
+ NULL,
+ NULL,
+ keytab,
+ NULL,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_c_init_with_creds_ctx(krb5_context context,
+ const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_c_init_with_context(context,
+ client_name,
+ NULL,
+ NULL,
+ NULL,
+ ccache,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_c_init_with_creds(const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return init_context(client_name,
+ NULL,
+ NULL,
+ NULL,
+ ccache,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+#if 0
+kadm5_ret_t
+kadm5_init(char *client_name, char *pass,
+ char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+}
+#endif
+
diff --git a/crypto/heimdal/lib/kadm5/init_s.c b/crypto/heimdal/lib/kadm5/init_s.c
new file mode 100644
index 000000000000..6c1f3d144d15
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/init_s.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: init_s.c,v 1.9 1999/12/02 17:05:06 joda Exp $");
+
+
+static kadm5_ret_t
+kadm5_s_init_with_context(krb5_context context,
+ const char *client_name,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ kadm5_ret_t ret;
+ kadm5_server_context *ctx;
+ ret = _kadm5_s_init_context(&ctx, realm_params, context);
+ if(ret)
+ return ret;
+
+ assert(ctx->config.dbname != NULL);
+ assert(ctx->config.stash_file != NULL);
+ assert(ctx->config.acl_file != NULL);
+ assert(ctx->log_context.log_file != NULL);
+ assert(ctx->log_context.socket_name.sun_path[0] != '\0');
+
+ ret = hdb_create(ctx->context, &ctx->db, ctx->config.dbname);
+ if(ret)
+ return ret;
+ ret = hdb_set_master_keyfile (ctx->context,
+ ctx->db, ctx->config.stash_file);
+ if(ret)
+ return ret;
+
+ ctx->log_context.log_fd = -1;
+
+ ctx->log_context.socket_fd = socket (AF_UNIX, SOCK_DGRAM, 0);
+
+ ret = krb5_parse_name(ctx->context, client_name, &ctx->caller);
+ if(ret)
+ return ret;
+
+ ret = _kadm5_acl_init(ctx);
+ if(ret)
+ return ret;
+
+ *server_handle = ctx;
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_s_init_with_password_ctx(krb5_context context,
+ const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_s_init_with_context(context,
+ client_name,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_s_init_with_password(const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ krb5_context context;
+ kadm5_ret_t ret;
+ kadm5_server_context *ctx;
+
+ krb5_init_context(&context);
+ ret = kadm5_s_init_with_password_ctx(context,
+ client_name,
+ password,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+ if(ret){
+ krb5_free_context(context);
+ return ret;
+ }
+ ctx = *server_handle;
+ ctx->my_context = 1;
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_s_init_with_skey_ctx(krb5_context context,
+ const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_s_init_with_context(context,
+ client_name,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_s_init_with_skey(const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ krb5_context context;
+ kadm5_ret_t ret;
+ kadm5_server_context *ctx;
+
+ krb5_init_context(&context);
+ ret = kadm5_s_init_with_skey_ctx(context,
+ client_name,
+ keytab,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+ if(ret){
+ krb5_free_context(context);
+ return ret;
+ }
+ ctx = *server_handle;
+ ctx->my_context = 1;
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_s_init_with_creds_ctx(krb5_context context,
+ const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_s_init_with_context(context,
+ client_name,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_s_init_with_creds(const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ krb5_context context;
+ kadm5_ret_t ret;
+ kadm5_server_context *ctx;
+
+ krb5_init_context(&context);
+ ret = kadm5_s_init_with_creds_ctx(context,
+ client_name,
+ ccache,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+ if(ret){
+ krb5_free_context(context);
+ return ret;
+ }
+ ctx = *server_handle;
+ ctx->my_context = 1;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/iprop.h b/crypto/heimdal/lib/kadm5/iprop.h
new file mode 100644
index 000000000000..499f51544e20
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/iprop.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1998-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: iprop.h,v 1.4 1999/12/02 17:05:06 joda Exp $ */
+
+#ifndef __IPROP_H__
+#define __IPROP_H__
+
+#include "kadm5_locl.h"
+#include <getarg.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#define IPROP_VERSION "iprop-0.0"
+
+#define KADM5_SLAVE_ACL HDB_DB_DIR "/slaves"
+
+#define IPROP_NAME "iprop"
+
+enum iprop_cmd { I_HAVE = 1, FOR_YOU = 2 };
+
+#endif /* __IPROP_H__ */
diff --git a/crypto/heimdal/lib/kadm5/ipropd_master.c b/crypto/heimdal/lib/kadm5/ipropd_master.c
new file mode 100644
index 000000000000..b2e71a736dd2
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/ipropd_master.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "iprop.h"
+
+RCSID("$Id: ipropd_master.c,v 1.12 1999/12/02 17:05:06 joda Exp $");
+
+static int
+make_signal_socket (krb5_context context)
+{
+ struct sockaddr_un addr;
+ int fd;
+
+ fd = socket (AF_UNIX, SOCK_DGRAM, 0);
+ if (fd < 0)
+ krb5_err (context, 1, errno, "socket AF_UNIX");
+ memset (&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, KADM5_LOG_SIGNAL, sizeof(addr.sun_path));
+ addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
+ unlink (addr.sun_path);
+ if (bind (fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+ krb5_err (context, 1, errno, "bind %s", addr.sun_path);
+ return fd;
+}
+
+static int
+make_listen_socket (krb5_context context)
+{
+ int fd;
+ int one = 1;
+ struct sockaddr_in addr;
+
+ fd = socket (AF_INET, SOCK_STREAM, 0);
+ if (fd < 0)
+ krb5_err (context, 1, errno, "socket AF_INET");
+ setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ memset (&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(4711);
+ if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+ krb5_err (context, 1, errno, "bind");
+ if (listen(fd, SOMAXCONN) < 0)
+ krb5_err (context, 1, errno, "listen");
+ return fd;
+}
+
+struct slave {
+ int fd;
+ struct sockaddr_in addr;
+ char *name;
+ krb5_auth_context ac;
+ u_int32_t version;
+ struct slave *next;
+};
+
+typedef struct slave slave;
+
+static int
+check_acl (krb5_context context, const char *name)
+{
+ FILE *fp;
+ char buf[256];
+ int ret = 1;
+
+ fp = fopen (KADM5_SLAVE_ACL, "r");
+ if (fp == NULL)
+ return 1;
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ if (buf[strlen(buf) - 1 ] == '\n')
+ buf[strlen(buf) - 1 ] = '\0';
+ if (strcmp (buf, name) == 0) {
+ ret = 0;
+ break;
+ }
+ }
+ fclose (fp);
+ return ret;
+}
+
+static void
+add_slave (krb5_context context, slave **root, int fd)
+{
+ krb5_principal server;
+ krb5_error_code ret;
+ slave *s;
+ int addr_len;
+ krb5_ticket *ticket = NULL;
+ char hostname[128];
+
+ s = malloc(sizeof(*s));
+ if (s == NULL) {
+ krb5_warnx (context, "add_slave: no memory");
+ return;
+ }
+ s->name = NULL;
+ s->ac = NULL;
+
+ addr_len = sizeof(s->addr);
+ s->fd = accept (fd, (struct sockaddr *)&s->addr, &addr_len);
+ if (s->fd < 0) {
+ krb5_warn (context, errno, "accept");
+ goto error;
+ }
+ gethostname(hostname, sizeof(hostname));
+ ret = krb5_sname_to_principal (context, hostname, IPROP_NAME,
+ KRB5_NT_SRV_HST, &server);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_sname_to_principal");
+ goto error;
+ }
+
+ ret = krb5_recvauth (context, &s->ac, &s->fd,
+ IPROP_VERSION, server, 0, NULL, &ticket);
+ krb5_free_principal (context, server);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_recvauth");
+ goto error;
+ }
+ ret = krb5_unparse_name (context, ticket->client, &s->name);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_unparse_name");
+ goto error;
+ }
+ if (check_acl (context, s->name)) {
+ krb5_warnx (context, "%s not in acl", s->name);
+ goto error;
+ }
+ krb5_free_ticket (context, ticket);
+ printf ("connection from %s\n", s->name);
+
+ s->version = 0;
+ s->next = *root;
+ *root = s;
+ return;
+error:
+ if (s->name)
+ free (s->name);
+ if (s->ac)
+ krb5_auth_con_free(context, s->ac);
+ if (ticket)
+ krb5_free_ticket (context, ticket);
+ close (s->fd);
+ free(s);
+}
+
+static void
+remove_slave (krb5_context context, slave *s, slave **root)
+{
+ slave **p;
+
+ close (s->fd);
+ free (s->name);
+ krb5_auth_con_free (context, s->ac);
+
+ for (p = root; *p; p = &(*p)->next)
+ if (*p == s) {
+ *p = s->next;
+ break;
+ }
+ free (s);
+}
+
+static int
+send_complete (krb5_context context, slave *s)
+{
+ abort ();
+}
+
+static int
+send_diffs (krb5_context context, slave *s, int log_fd,
+ u_int32_t current_version)
+{
+ krb5_storage *sp, *data_sp;
+ u_int32_t ver;
+ time_t timestamp;
+ enum kadm_ops op;
+ u_int32_t len;
+ off_t right, left;
+ krb5_data data;
+ krb5_data priv_data;
+ int ret = 0;
+
+ if (s->version == current_version)
+ return 0;
+
+ sp = kadm5_log_goto_end (log_fd);
+ right = sp->seek(sp, 0, SEEK_CUR);
+ printf ("%ld, looking for %d\n", (long)right, s->version);
+ for (;;) {
+ if (kadm5_log_previous (sp, &ver, &timestamp, &op, &len))
+ abort ();
+ printf ("version = %d\n", ver);
+ left = sp->seek(sp, -16, SEEK_CUR);
+ if (ver == s->version)
+ return 0;
+ if (ver == s->version + 1)
+ break;
+ if (left == 0)
+ return send_complete (context, s);
+ }
+ krb5_data_alloc (&data, right - left + 4);
+ sp->fetch (sp, (char *)data.data + 4, data.length - 4);
+ krb5_storage_free(sp);
+
+ _krb5_put_int(data.data, FOR_YOU, 4);
+
+ ret = krb5_mk_priv (context, s->ac, &data, &priv_data, NULL);
+ krb5_data_free(&data);
+ if (ret) {
+ krb5_warn (context, ret, "krb_mk_priv");
+ return 0;
+ }
+
+ ret = krb5_write_message (context, &s->fd, &priv_data);
+ krb5_data_free (&priv_data);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_write_message");
+ return 1;
+ }
+ return 0;
+}
+
+static int
+process_msg (krb5_context context, slave *s, int log_fd,
+ u_int32_t current_version)
+{
+ int ret = 0;
+ krb5_data in, out;
+ krb5_storage *sp;
+ int32_t tmp;
+
+ ret = krb5_read_message (context, &s->fd, &in);
+ if (ret)
+ return 1;
+
+ if(in.length == 0) {
+ krb5_warnx(context, "process_msg: short message");
+ return 1;
+ }
+
+ ret = krb5_rd_priv (context, s->ac, &in, &out, NULL);
+ krb5_data_free (&in);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_rd_priv");
+ return 1;
+ }
+
+ sp = krb5_storage_from_mem (out.data, out.length);
+ krb5_ret_int32 (sp, &tmp);
+ switch (tmp) {
+ case I_HAVE :
+ krb5_ret_int32 (sp, &tmp);
+ s->version = tmp;
+ ret = send_diffs (context, s, log_fd, current_version);
+ break;
+ case FOR_YOU :
+ default :
+ krb5_warnx (context, "Ignoring command %d", tmp);
+ break;
+ }
+
+ krb5_data_free (&out);
+ return ret;
+}
+
+char *realm;
+int version_flag;
+int help_flag;
+struct getargs args[] = {
+ { "realm", 'r', arg_string, &realm },
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+int num_args = sizeof(args) / sizeof(args[0]);
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ void *kadm_handle;
+ kadm5_server_context *server_context;
+ kadm5_config_params conf;
+ int signal_fd, listen_fd;
+ int log_fd;
+ slave *slaves = NULL;
+ u_int32_t current_version, old_version = 0;
+
+ int optind;
+
+ optind = krb5_program_setup(&context, argc, argv, args, num_args, NULL);
+
+ if(help_flag)
+ krb5_std_usage(0, args, num_args);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ memset(&conf, 0, sizeof(conf));
+ if(realm) {
+ conf.mask |= KADM5_CONFIG_REALM;
+ conf.realm = realm;
+ }
+ ret = kadm5_init_with_password_ctx (context,
+ KADM5_ADMIN_SERVICE,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm_handle);
+ if (ret)
+ krb5_err (context, 1, ret, "kadm5_init_with_password_ctx");
+
+ server_context = (kadm5_server_context *)kadm_handle;
+
+ log_fd = open (server_context->log_context.log_file, O_RDONLY, 0);
+ if (log_fd < 0)
+ krb5_err (context, 1, errno, "open %s",
+ server_context->log_context.log_file);
+
+ signal_fd = make_signal_socket (context);
+ listen_fd = make_listen_socket (context);
+
+ for (;;) {
+ slave *p;
+ fd_set readset;
+ int max_fd = 0;
+ struct timeval to = {30, 0};
+ u_int32_t vers;
+
+ FD_ZERO(&readset);
+ FD_SET(signal_fd, &readset);
+ max_fd = max(max_fd, signal_fd);
+ FD_SET(listen_fd, &readset);
+ max_fd = max(max_fd, listen_fd);
+
+ for (p = slaves; p != NULL; p = p->next) {
+ FD_SET(p->fd, &readset);
+ max_fd = max(max_fd, p->fd);
+ }
+
+ ret = select (max_fd + 1,
+ &readset, NULL, NULL, &to);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ krb5_err (context, 1, errno, "select");
+ }
+
+ if (ret == 0) {
+ old_version = current_version;
+ kadm5_log_get_version (log_fd, &current_version);
+
+ if (current_version > old_version)
+ for (p = slaves; p != NULL; p = p->next)
+ send_diffs (context, p, log_fd, current_version);
+ }
+
+ if (ret && FD_ISSET(signal_fd, &readset)) {
+ struct sockaddr_un peer_addr;
+ int peer_len = sizeof(peer_addr);
+
+ if(recvfrom(signal_fd, &vers, sizeof(vers), 0,
+ (struct sockaddr *)&peer_addr, &peer_len) < 0) {
+ krb5_warn (context, errno, "recvfrom");
+ continue;
+ }
+ printf ("signal: %u\n", vers);
+ --ret;
+ old_version = current_version;
+ kadm5_log_get_version (log_fd, &current_version);
+ for (p = slaves; p != NULL; p = p->next)
+ send_diffs (context, p, log_fd, current_version);
+ }
+
+ for(p = slaves; p != NULL && ret--; p = p->next)
+ if (FD_ISSET(p->fd, &readset)) {
+ if(process_msg (context, p, log_fd, current_version))
+ remove_slave (context, p, &slaves);
+ }
+
+ if (ret && FD_ISSET(listen_fd, &readset)) {
+ add_slave (context, &slaves, listen_fd);
+ --ret;
+ }
+
+ }
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/ipropd_slave.c b/crypto/heimdal/lib/kadm5/ipropd_slave.c
new file mode 100644
index 000000000000..76884eb00c89
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/ipropd_slave.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "iprop.h"
+
+RCSID("$Id: ipropd_slave.c,v 1.10 1999/12/02 17:05:06 joda Exp $");
+
+static int
+connect_to_master (krb5_context context, const char *master)
+{
+ int fd;
+ struct sockaddr_in addr;
+ struct hostent *he;
+
+ fd = socket (AF_INET, SOCK_STREAM, 0);
+ if (fd < 0)
+ krb5_err (context, 1, errno, "socket AF_INET");
+ memset (&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(4711);
+ he = roken_gethostbyname (master);
+ if (he == NULL)
+ krb5_errx (context, 1, "gethostbyname: %s", hstrerror(h_errno));
+ memcpy (&addr.sin_addr, he->h_addr, sizeof(addr.sin_addr));
+ if(connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+ krb5_err (context, 1, errno, "connect");
+ return fd;
+}
+
+static void
+get_creds(krb5_context context, krb5_ccache *cache, const char *host)
+{
+ krb5_keytab keytab;
+ krb5_principal client;
+ krb5_error_code ret;
+ krb5_get_init_creds_opt init_opts;
+#if 0
+ krb5_preauthtype preauth = KRB5_PADATA_ENC_TIMESTAMP;
+#endif
+ krb5_creds creds;
+ char my_hostname[128];
+ char *server;
+
+ ret = krb5_kt_default(context, &keytab);
+ if(ret) krb5_err(context, 1, ret, "krb5_kt_default");
+
+ gethostname (my_hostname, sizeof(my_hostname));
+ ret = krb5_sname_to_principal (context, my_hostname, IPROP_NAME,
+ KRB5_NT_SRV_HST, &client);
+ if (ret) krb5_err(context, 1, ret, "krb5_sname_to_principal");
+
+ krb5_get_init_creds_opt_init(&init_opts);
+#if 0
+ krb5_get_init_creds_opt_set_preauth_list(&init_opts, &preauth, 1);
+#endif
+
+ asprintf (&server, "%s/%s", IPROP_NAME, host);
+ if (server == NULL)
+ krb5_errx (context, 1, "malloc: no memory");
+
+ ret = krb5_get_init_creds_keytab(context, &creds, client, keytab,
+ 0, server, &init_opts);
+ free (server);
+ if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");
+
+ ret = krb5_kt_close(context, keytab);
+ if(ret) krb5_err(context, 1, ret, "krb5_kt_close");
+
+ ret = krb5_cc_gen_new(context, &krb5_mcc_ops, cache);
+ if(ret) krb5_err(context, 1, ret, "krb5_cc_gen_new");
+
+ ret = krb5_cc_initialize(context, *cache, client);
+ if(ret) krb5_err(context, 1, ret, "krb5_cc_initialize");
+
+ ret = krb5_cc_store_cred(context, *cache, &creds);
+ if(ret) krb5_err(context, 1, ret, "krb5_cc_store_cred");
+}
+
+static void
+ihave (krb5_context context, krb5_auth_context auth_context,
+ int fd, u_int32_t version)
+{
+ int ret;
+ u_char buf[8];
+ krb5_storage *sp;
+ krb5_data data, priv_data;
+
+ sp = krb5_storage_from_mem (buf, 8);
+ krb5_store_int32 (sp, I_HAVE);
+ krb5_store_int32 (sp, version);
+ krb5_storage_free (sp);
+ data.length = 8;
+ data.data = buf;
+
+ ret = krb5_mk_priv (context, auth_context, &data, &priv_data, NULL);
+ if (ret)
+ krb5_err (context, 1, ret, "krb_mk_priv");
+
+ ret = krb5_write_message (context, &fd, &priv_data);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_write_message");
+
+ krb5_data_free (&priv_data);
+}
+
+static void
+receive (krb5_context context,
+ krb5_storage *sp,
+ kadm5_server_context *server_context)
+{
+ int ret;
+ off_t left, right;
+ void *buf;
+ int32_t vers;
+
+ ret = server_context->db->open(context,
+ server_context->db,
+ O_RDWR | O_CREAT, 0);
+ if (ret)
+ krb5_err (context, 1, ret, "db->open");
+
+ do {
+ int32_t len, timestamp, tmp;
+ enum kadm_ops op;
+
+ if(krb5_ret_int32 (sp, &vers) != 0)
+ return;
+ krb5_ret_int32 (sp, &timestamp);
+ krb5_ret_int32 (sp, &tmp);
+ op = tmp;
+ krb5_ret_int32 (sp, &len);
+ if (vers <= server_context->log_context.version)
+ sp->seek(sp, len, SEEK_CUR);
+ } while(vers <= server_context->log_context.version);
+
+ left = sp->seek (sp, -16, SEEK_CUR);
+ right = sp->seek (sp, 0, SEEK_END);
+ buf = malloc (right - left);
+ if (buf == NULL) {
+ krb5_warnx (context, "malloc: no memory");
+ return;
+ }
+ sp->seek (sp, left, SEEK_SET);
+ sp->fetch (sp, buf, right - left);
+ write (server_context->log_context.log_fd, buf, right-left);
+ fsync (server_context->log_context.log_fd);
+ free (buf);
+
+ sp->seek (sp, left, SEEK_SET);
+
+ for(;;) {
+ int32_t len, timestamp, tmp;
+ enum kadm_ops op;
+
+ if(krb5_ret_int32 (sp, &vers) != 0)
+ break;
+ krb5_ret_int32 (sp, &timestamp);
+ krb5_ret_int32 (sp, &tmp);
+ op = tmp;
+ krb5_ret_int32 (sp, &len);
+
+ ret = kadm5_log_replay (server_context,
+ op, vers, len, sp);
+ if (ret)
+ krb5_warn (context, ret, "kadm5_log_replay");
+ else
+ server_context->log_context.version = vers;
+ sp->seek (sp, 8, SEEK_CUR);
+ }
+
+ ret = server_context->db->close (context, server_context->db);
+ if (ret)
+ krb5_err (context, 1, ret, "db->close");
+}
+
+char *realm;
+int version_flag;
+int help_flag;
+struct getargs args[] = {
+ { "realm", 'r', arg_string, &realm },
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+int num_args = sizeof(args) / sizeof(args[0]);
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_auth_context auth_context;
+ void *kadm_handle;
+ kadm5_server_context *server_context;
+ kadm5_config_params conf;
+ int master_fd;
+ krb5_ccache ccache;
+ krb5_principal server;
+
+ int optind;
+
+ optind = krb5_program_setup(&context, argc, argv, args, num_args, NULL);
+
+ if(help_flag)
+ krb5_std_usage(0, args, num_args);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ memset(&conf, 0, sizeof(conf));
+ if(realm) {
+ conf.mask |= KADM5_CONFIG_REALM;
+ conf.realm = realm;
+ }
+ ret = kadm5_init_with_password_ctx (context,
+ KADM5_ADMIN_SERVICE,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm_handle);
+ if (ret)
+ krb5_err (context, 1, ret, "kadm5_init_with_password_ctx");
+
+ server_context = (kadm5_server_context *)kadm_handle;
+
+ ret = kadm5_log_init (server_context);
+ if (ret)
+ krb5_err (context, 1, ret, "kadm5_log_init");
+
+ get_creds(context, &ccache, argv[1]);
+
+ master_fd = connect_to_master (context, argv[1]);
+
+ ret = krb5_sname_to_principal (context, argv[1], IPROP_NAME,
+ KRB5_NT_SRV_HST, &server);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_sname_to_principal");
+
+ auth_context = NULL;
+ ret = krb5_sendauth (context, &auth_context, &master_fd,
+ IPROP_VERSION, NULL, server,
+ AP_OPTS_MUTUAL_REQUIRED, NULL, NULL,
+ ccache, NULL, NULL, NULL);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_sendauth");
+
+ ihave (context, auth_context, master_fd,
+ server_context->log_context.version);
+
+ for (;;) {
+ int ret;
+ krb5_data data, out;
+ krb5_storage *sp;
+ int32_t tmp;
+
+ ret = krb5_read_message (context, &master_fd, &data);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_read_message");
+
+ ret = krb5_rd_priv (context, auth_context, &data, &out, NULL);
+ krb5_data_free (&data);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_rd_priv");
+
+ sp = krb5_storage_from_mem (out.data, out.length);
+ krb5_ret_int32 (sp, &tmp);
+ switch (tmp) {
+ case FOR_YOU :
+ receive (context, sp, server_context);
+ ihave (context, auth_context, master_fd,
+ server_context->log_context.version);
+ break;
+ case I_HAVE :
+ default :
+ krb5_warnx (context, "Ignoring command %d", tmp);
+ break;
+ }
+ krb5_storage_free (sp);
+ krb5_data_free (&out);
+ }
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/kadm5_err.et b/crypto/heimdal/lib/kadm5/kadm5_err.et
new file mode 100644
index 000000000000..506a554ac149
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/kadm5_err.et
@@ -0,0 +1,59 @@
+#
+# Error messages for the kadm5 library
+#
+# This might look like a com_err file, but is not
+#
+id "$Id: kadm5_err.et,v 1.4 1998/02/16 16:37:17 joda Exp $"
+
+error_table ovk kadm5
+
+prefix KADM5
+error_code FAILURE, "Operation failed for unspecified reason"
+error_code AUTH_GET, "Operation requires `get' privilege"
+error_code AUTH_ADD, "Operation requires `add' privilege"
+error_code AUTH_MODIFY, "Operation requires `modify' privilege"
+error_code AUTH_DELETE, "Operation requires `delete' privilege"
+error_code AUTH_INSUFFICIENT, "Insufficient authorization for operation"
+error_code BAD_DB, "Database inconsistency detected"
+error_code DUP, "Principal or policy already exists"
+error_code RPC_ERROR, "Communication failure with server"
+error_code NO_SRV, "No administration server found for realm"
+error_code BAD_HIST_KEY, "Password history principal key version mismatch"
+error_code NOT_INIT, "Connection to server not initialized"
+error_code UNK_PRINC, "Principal does not exist"
+error_code UNK_POLICY, "Policy does not exist"
+error_code BAD_MASK, "Invalid field mask for operation"
+error_code BAD_CLASS, "Invalid number of character classes"
+error_code BAD_LENGTH, "Invalid password length"
+error_code BAD_POLICY, "Invalid policy name"
+error_code BAD_PRINCIPAL, "Invalid principal name."
+error_code BAD_AUX_ATTR, "Invalid auxillary attributes"
+error_code BAD_HISTORY, "Invalid password history count"
+error_code BAD_MIN_PASS_LIFE, "Password minimum life is greater then password maximum life"
+error_code PASS_Q_TOOSHORT, "Password is too short"
+error_code PASS_Q_CLASS, "Password does not contain enough character classes"
+error_code PASS_Q_DICT, "Password is in the password dictionary"
+error_code PASS_REUSE, "Can't resuse password"
+error_code PASS_TOOSOON, "Current password's minimum life has not expired"
+error_code POLICY_REF, "Policy is in use"
+error_code INIT, "Connection to server already initialized"
+error_code BAD_PASSWORD, "Incorrect password"
+error_code PROTECT_PRINCIPAL, "Can't change protected principal"
+error_code BAD_SERVER_HANDLE, "Programmer error! Bad Admin server handle"
+error_code BAD_STRUCT_VERSION, "Programmer error! Bad API structure version"
+error_code OLD_STRUCT_VERSION, "API structure version specified by application is no longer supported"
+error_code NEW_STRUCT_VERSION, "API structure version specified by application is unknown to libraries"
+error_code BAD_API_VERSION, "Programmer error! Bad API version"
+error_code OLD_LIB_API_VERSION, "API version specified by application is no longer supported by libraries"
+error_code OLD_SERVER_API_VERSION,"API version specified by application is no longer supported by server"
+error_code NEW_LIB_API_VERSION, "API version specified by application is unknown to libraries"
+error_code NEW_SERVER_API_VERSION,"API version specified by application is unknown to server"
+error_code SECURE_PRINC_MISSING,"Database error! Required principal missing"
+error_code NO_RENAME_SALT, "The salt type of the specified principal does not support renaming"
+error_code BAD_CLIENT_PARAMS, "Invalid configuration parameter for remote KADM5 client"
+error_code BAD_SERVER_PARAMS, "Invalid configuration parameter for local KADM5 client."
+error_code AUTH_LIST, "Operation requires `list' privilege"
+error_code AUTH_CHANGEPW, "Operation requires `change-password' privilege"
+error_code BAD_TL_TYPE, "Programmer error! Invalid tagged data list element type"
+error_code MISSING_CONF_PARAMS, "Required parameters in kdc.conf missing"
+error_code BAD_SERVER_NAME, "Bad krb5 admin server hostname"
diff --git a/crypto/heimdal/lib/kadm5/kadm5_locl.h b/crypto/heimdal/lib/kadm5/kadm5_locl.h
new file mode 100644
index 000000000000..9344a2c13bad
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/kadm5_locl.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: kadm5_locl.h,v 1.21 1999/12/02 17:05:06 joda Exp $ */
+
+#ifndef __KADM5_LOCL_H__
+#define __KADM5_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#include <fnmatch.h>
+#include "admin.h"
+#include "kadm5_err.h"
+#include <hdb.h>
+#include <roken.h>
+#include <parse_units.h>
+#include "private.h"
+
+#endif /* __KADM5_LOCL_H__ */
diff --git a/crypto/heimdal/lib/kadm5/log.c b/crypto/heimdal/lib/kadm5/log.c
new file mode 100644
index 000000000000..e9dc38ce3934
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/log.c
@@ -0,0 +1,666 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: log.c,v 1.13 1999/12/04 19:50:35 assar Exp $");
+
+/*
+ * A log record consists of:
+ *
+ * version number 4 bytes
+ * time in seconds 4 bytes
+ * operation (enum kadm_ops) 4 bytes
+ * length of record 4 bytes
+ * data... n bytes
+ * length of record 4 bytes
+ * version number 4 bytes
+ *
+ */
+
+kadm5_ret_t
+kadm5_log_get_version (int fd,
+ u_int32_t *ver)
+{
+ int ret;
+ krb5_storage *sp;
+ int32_t old_version;
+
+ ret = lseek (fd, 0, SEEK_END);
+ if(ret < 0)
+ return errno;
+ if(ret == 0) {
+ *ver = 0;
+ return 0;
+ }
+ sp = krb5_storage_from_fd (fd);
+ sp->seek(sp, -4, SEEK_CUR);
+ krb5_ret_int32 (sp, &old_version);
+ *ver = old_version;
+ krb5_storage_free(sp);
+ lseek (fd, 0, SEEK_END);
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_log_init (kadm5_server_context *context)
+{
+ int fd;
+ kadm5_ret_t ret;
+ kadm5_log_context *log_context = &context->log_context;
+
+ if (log_context->log_fd != -1)
+ return 0;
+ fd = open (log_context->log_file, O_RDWR | O_CREAT, 0600);
+ if (fd < 0)
+ return errno;
+ if (flock (fd, LOCK_EX) < 0) {
+ close (fd);
+ return errno;
+ }
+
+ ret = kadm5_log_get_version (fd, &log_context->version);
+ if (ret)
+ return ret;
+
+ log_context->log_fd = fd;
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_log_end (kadm5_server_context *context)
+{
+ kadm5_log_context *log_context = &context->log_context;
+ int fd = log_context->log_fd;
+
+ flock (fd, LOCK_UN);
+ close(fd);
+ log_context->log_fd = -1;
+ return 0;
+}
+
+static kadm5_ret_t
+kadm5_log_preamble (kadm5_server_context *context,
+ krb5_storage *sp,
+ enum kadm_ops op)
+{
+ kadm5_log_context *log_context = &context->log_context;
+ kadm5_ret_t kadm_ret;
+
+ kadm_ret = kadm5_log_init (context);
+ if (kadm_ret)
+ return kadm_ret;
+
+ krb5_store_int32 (sp, ++log_context->version);
+ krb5_store_int32 (sp, time(NULL));
+ krb5_store_int32 (sp, op);
+ return 0;
+}
+
+static kadm5_ret_t
+kadm5_log_postamble (kadm5_log_context *context,
+ krb5_storage *sp)
+{
+ krb5_store_int32 (sp, context->version);
+ return 0;
+}
+
+/*
+ * flush the log record in `sp'.
+ */
+
+static kadm5_ret_t
+kadm5_log_flush (kadm5_log_context *log_context,
+ krb5_storage *sp)
+{
+ krb5_data data;
+ size_t len;
+ int ret;
+
+ krb5_storage_to_data(sp, &data);
+ len = data.length;
+ ret = write (log_context->log_fd, data.data, len);
+ if (ret != len) {
+ krb5_data_free(&data);
+ return errno;
+ }
+ if (fsync (log_context->log_fd) < 0) {
+ krb5_data_free(&data);
+ return errno;
+ }
+ /*
+ * Try to send a signal to any running `ipropd-master'
+ */
+ sendto (log_context->socket_fd,
+ (void *)&log_context->version,
+ sizeof(log_context->version),
+ 0,
+ (struct sockaddr *)&log_context->socket_name,
+ sizeof(log_context->socket_name));
+
+ krb5_data_free(&data);
+ return 0;
+}
+
+/*
+ * Add a `create' operation to the log.
+ */
+
+kadm5_ret_t
+kadm5_log_create (kadm5_server_context *context,
+ hdb_entry *ent)
+{
+ krb5_storage *sp;
+ kadm5_ret_t ret;
+ krb5_data value;
+ kadm5_log_context *log_context = &context->log_context;
+
+ sp = krb5_storage_emem();
+ ret = hdb_entry2value (context->context, ent, &value);
+ if (ret) {
+ krb5_storage_free(sp);
+ return ret;
+ }
+ ret = kadm5_log_preamble (context, sp, kadm_create);
+ if (ret) {
+ krb5_data_free (&value);
+ krb5_storage_free(sp);
+ return ret;
+ }
+ krb5_store_int32 (sp, value.length);
+ sp->store(sp, value.data, value.length);
+ krb5_store_int32 (sp, value.length);
+ krb5_data_free (&value);
+ ret = kadm5_log_postamble (log_context, sp);
+ if (ret) {
+ krb5_storage_free (sp);
+ return ret;
+ }
+ ret = kadm5_log_flush (log_context, sp);
+ krb5_storage_free (sp);
+ if (ret)
+ return ret;
+ ret = kadm5_log_end (context);
+ return ret;
+}
+
+/*
+ * Read the data of a create log record from `sp' and change the
+ * database.
+ */
+
+kadm5_ret_t
+kadm5_log_replay_create (kadm5_server_context *context,
+ u_int32_t ver,
+ u_int32_t len,
+ krb5_storage *sp)
+{
+ krb5_error_code ret;
+ krb5_data data;
+ hdb_entry ent;
+
+ krb5_data_alloc (&data, len);
+ sp->fetch (sp, data.data, len);
+ ret = hdb_value2entry (context->context, &data, &ent);
+ krb5_data_free(&data);
+ if (ret)
+ return ret;
+ ret = context->db->store(context->context, context->db, 0, &ent);
+ hdb_free_entry (context->context, &ent);
+ return ret;
+}
+
+/*
+ * Add a `delete' operation to the log.
+ */
+
+kadm5_ret_t
+kadm5_log_delete (kadm5_server_context *context,
+ krb5_principal princ)
+{
+ krb5_storage *sp;
+ kadm5_ret_t ret;
+ off_t off;
+ off_t len;
+ kadm5_log_context *log_context = &context->log_context;
+
+ sp = krb5_storage_emem();
+ ret = kadm5_log_preamble (context, sp, kadm_delete);
+ if (ret) {
+ krb5_storage_free(sp);
+ return ret;
+ }
+ krb5_store_int32 (sp, 0);
+ off = sp->seek (sp, 0, SEEK_CUR);
+ krb5_store_principal (sp, princ);
+ len = sp->seek (sp, 0, SEEK_CUR) - off;
+ sp->seek(sp, -(len + 4), SEEK_CUR);
+ krb5_store_int32 (sp, len);
+ sp->seek(sp, len, SEEK_CUR);
+ krb5_store_int32 (sp, len);
+ if (ret) {
+ krb5_storage_free (sp);
+ return ret;
+ }
+ ret = kadm5_log_postamble (log_context, sp);
+ if (ret) {
+ krb5_storage_free (sp);
+ return ret;
+ }
+ ret = kadm5_log_flush (log_context, sp);
+ krb5_storage_free (sp);
+ if (ret)
+ return ret;
+ ret = kadm5_log_end (context);
+ return ret;
+}
+
+/*
+ * Read a `delete' log operation from `sp' and apply it.
+ */
+
+kadm5_ret_t
+kadm5_log_replay_delete (kadm5_server_context *context,
+ u_int32_t ver,
+ u_int32_t len,
+ krb5_storage *sp)
+{
+ krb5_error_code ret;
+ hdb_entry ent;
+
+ krb5_ret_principal (sp, &ent.principal);
+
+ ret = context->db->remove(context->context, context->db, &ent);
+ krb5_free_principal (context->context, ent.principal);
+ return ret;
+}
+
+/*
+ * Add a `rename' operation to the log.
+ */
+
+kadm5_ret_t
+kadm5_log_rename (kadm5_server_context *context,
+ krb5_principal source,
+ hdb_entry *ent)
+{
+ krb5_storage *sp;
+ kadm5_ret_t ret;
+ off_t off;
+ off_t len;
+ krb5_data value;
+ kadm5_log_context *log_context = &context->log_context;
+
+ sp = krb5_storage_emem();
+ ret = hdb_entry2value (context->context, ent, &value);
+ if (ret) {
+ krb5_storage_free(sp);
+ return ret;
+ }
+ ret = kadm5_log_preamble (context, sp, kadm_rename);
+ if (ret) {
+ krb5_storage_free(sp);
+ krb5_data_free (&value);
+ return ret;
+ }
+ krb5_store_int32 (sp, 0);
+ off = sp->seek (sp, 0, SEEK_CUR);
+ krb5_store_principal (sp, source);
+ sp->store(sp, value.data, value.length);
+ krb5_data_free (&value);
+ len = sp->seek (sp, 0, SEEK_CUR) - off;
+
+ sp->seek(sp, -(len + 4), SEEK_CUR);
+ krb5_store_int32 (sp, len);
+ sp->seek(sp, len, SEEK_CUR);
+ krb5_store_int32 (sp, len);
+ if (ret) {
+ krb5_storage_free (sp);
+ return ret;
+ }
+ ret = kadm5_log_postamble (log_context, sp);
+ if (ret) {
+ krb5_storage_free (sp);
+ return ret;
+ }
+ ret = kadm5_log_flush (log_context, sp);
+ krb5_storage_free (sp);
+ if (ret)
+ return ret;
+ ret = kadm5_log_end (context);
+ return ret;
+}
+
+/*
+ * Read a `rename' log operation from `sp' and apply it.
+ */
+
+kadm5_ret_t
+kadm5_log_replay_rename (kadm5_server_context *context,
+ u_int32_t ver,
+ u_int32_t len,
+ krb5_storage *sp)
+{
+ krb5_error_code ret;
+ krb5_principal source;
+ hdb_entry source_ent, target_ent;
+ krb5_data value;
+ off_t off;
+ size_t princ_len, data_len;
+
+ off = sp->seek(sp, 0, SEEK_CUR);
+ krb5_ret_principal (sp, &source);
+ princ_len = sp->seek(sp, 0, SEEK_CUR) - off;
+ data_len = len - princ_len;
+ krb5_data_alloc (&value, data_len);
+ sp->fetch (sp, value.data, data_len);
+ ret = hdb_value2entry (context->context, &value, &target_ent);
+ krb5_data_free(&value);
+ if (ret) {
+ krb5_free_principal (context->context, source);
+ return ret;
+ }
+ ret = context->db->store (context->context, context->db, 0, &target_ent);
+ hdb_free_entry (context->context, &target_ent);
+ if (ret) {
+ krb5_free_principal (context->context, source);
+ return ret;
+ }
+ source_ent.principal = source;
+ ret = context->db->remove (context->context, context->db, &source_ent);
+ krb5_free_principal (context->context, source);
+ return ret;
+}
+
+
+/*
+ * Add a `modify' operation to the log.
+ */
+
+kadm5_ret_t
+kadm5_log_modify (kadm5_server_context *context,
+ hdb_entry *ent,
+ u_int32_t mask)
+{
+ krb5_storage *sp;
+ kadm5_ret_t ret;
+ krb5_data value;
+ u_int32_t len;
+ kadm5_log_context *log_context = &context->log_context;
+
+ sp = krb5_storage_emem();
+ ret = hdb_entry2value (context->context, ent, &value);
+ if (ret) {
+ krb5_storage_free(sp);
+ return ret;
+ }
+ ret = kadm5_log_preamble (context, sp, kadm_modify);
+ if (ret) {
+ krb5_data_free (&value);
+ krb5_storage_free(sp);
+ return ret;
+ }
+ len = value.length + 4;
+ krb5_store_int32 (sp, len);
+ krb5_store_int32 (sp, mask);
+ sp->store(sp, value.data, value.length);
+ krb5_data_free (&value);
+ krb5_store_int32 (sp, len);
+ if (ret) {
+ krb5_storage_free (sp);
+ return ret;
+ }
+ ret = kadm5_log_postamble (log_context, sp);
+ if (ret) {
+ krb5_storage_free (sp);
+ return ret;
+ }
+ ret = kadm5_log_flush (log_context, sp);
+ krb5_storage_free (sp);
+ if (ret)
+ return ret;
+ ret = kadm5_log_end (context);
+ return ret;
+}
+
+/*
+ * Read a `modify' log operation from `sp' and apply it.
+ */
+
+kadm5_ret_t
+kadm5_log_replay_modify (kadm5_server_context *context,
+ u_int32_t ver,
+ u_int32_t len,
+ krb5_storage *sp)
+{
+ krb5_error_code ret;
+ int32_t mask;
+ krb5_data value;
+ hdb_entry ent, log_ent;
+
+ krb5_ret_int32 (sp, &mask);
+ len -= 4;
+ krb5_data_alloc (&value, len);
+ sp->fetch (sp, value.data, len);
+ ret = hdb_value2entry (context->context, &value, &log_ent);
+ krb5_data_free(&value);
+ if (ret)
+ return ret;
+ ent.principal = log_ent.principal;
+ log_ent.principal = NULL;
+ ret = context->db->fetch(context->context, context->db,
+ HDB_F_DECRYPT, &ent);
+ if (ret)
+ return ret;
+ if (mask & KADM5_PRINC_EXPIRE_TIME) {
+ if (ent.valid_end == NULL)
+ ent.valid_end = malloc(sizeof(*ent.valid_end));
+ *ent.valid_end = *log_ent.valid_end;
+ }
+ if (mask & KADM5_PW_EXPIRATION) {
+ if (ent.pw_end == NULL)
+ ent.pw_end = malloc(sizeof(*ent.pw_end));
+ *ent.pw_end = *log_ent.pw_end;
+ }
+ if (mask & KADM5_LAST_PWD_CHANGE) {
+ abort (); /* XXX */
+ }
+ if (mask & KADM5_ATTRIBUTES) {
+ ent.flags = log_ent.flags;
+ }
+ if (mask & KADM5_MAX_LIFE) {
+ if (ent.max_life == NULL)
+ ent.max_life = malloc (sizeof(*ent.max_life));
+ *ent.max_life = *log_ent.max_life;
+ }
+ if ((mask & KADM5_MOD_TIME) && (mask & KADM5_MOD_NAME)) {
+ if (ent.modified_by == NULL) {
+ ent.modified_by = malloc(sizeof(*ent.modified_by));
+ } else
+ free_Event(ent.modified_by);
+ copy_Event(log_ent.modified_by, ent.modified_by);
+ }
+ if (mask & KADM5_KVNO) {
+ ent.kvno = log_ent.kvno;
+ }
+ if (mask & KADM5_MKVNO) {
+ abort (); /* XXX */
+ }
+ if (mask & KADM5_AUX_ATTRIBUTES) {
+ abort (); /* XXX */
+ }
+ if (mask & KADM5_POLICY) {
+ abort (); /* XXX */
+ }
+ if (mask & KADM5_POLICY_CLR) {
+ abort (); /* XXX */
+ }
+ if (mask & KADM5_MAX_RLIFE) {
+ if (ent.max_renew == NULL)
+ ent.max_renew = malloc (sizeof(*ent.max_renew));
+ *ent.max_renew = *log_ent.max_renew;
+ }
+ if (mask & KADM5_LAST_SUCCESS) {
+ abort (); /* XXX */
+ }
+ if (mask & KADM5_LAST_FAILED) {
+ abort (); /* XXX */
+ }
+ if (mask & KADM5_FAIL_AUTH_COUNT) {
+ abort (); /* XXX */
+ }
+ if (mask & KADM5_KEY_DATA) {
+ size_t len;
+ int i;
+
+ for (i = 0; i < ent.keys.len; ++i)
+ free_Key(&ent.keys.val[i]);
+ free (ent.keys.val);
+
+ len = log_ent.keys.len;
+
+ ent.keys.len = len;
+ ent.keys.val = malloc(len * sizeof(*ent.keys.val));
+ for (i = 0; i < ent.keys.len; ++i)
+ copy_Key(&log_ent.keys.val[i],
+ &ent.keys.val[i]);
+ }
+ ret = context->db->store(context->context, context->db,
+ HDB_F_REPLACE, &ent);
+ hdb_free_entry (context->context, &ent);
+ hdb_free_entry (context->context, &log_ent);
+ return ret;
+}
+
+/*
+ * Call `func' for each log record in the log in `context'
+ */
+
+kadm5_ret_t
+kadm5_log_foreach (kadm5_server_context *context,
+ void (*func)(kadm5_server_context *server_context,
+ u_int32_t ver,
+ time_t timestamp,
+ enum kadm_ops op,
+ u_int32_t len,
+ krb5_storage *sp))
+{
+ int fd = context->log_context.log_fd;
+ krb5_storage *sp;
+
+ lseek (fd, 0, SEEK_SET);
+ sp = krb5_storage_from_fd (fd);
+ for (;;) {
+ int32_t ver, timestamp, op, len;
+
+ if(krb5_ret_int32 (sp, &ver) != 0)
+ break;
+ krb5_ret_int32 (sp, &timestamp);
+ krb5_ret_int32 (sp, &op);
+ krb5_ret_int32 (sp, &len);
+ (*func)(context, ver, timestamp, op, len, sp);
+ sp->seek(sp, 8, SEEK_CUR);
+ }
+ return 0;
+}
+
+/*
+ * Go to end of log.
+ */
+
+krb5_storage *
+kadm5_log_goto_end (int fd)
+{
+ krb5_storage *sp;
+
+ sp = krb5_storage_from_fd (fd);
+ sp->seek(sp, 0, SEEK_END);
+ return sp;
+}
+
+/*
+ * Return previous log entry.
+ */
+
+kadm5_ret_t
+kadm5_log_previous (krb5_storage *sp,
+ u_int32_t *ver,
+ time_t *timestamp,
+ enum kadm_ops *op,
+ u_int32_t *len)
+{
+ off_t off;
+ int32_t tmp;
+
+ sp->seek(sp, -8, SEEK_CUR);
+ krb5_ret_int32 (sp, &tmp);
+ *len = tmp;
+ krb5_ret_int32 (sp, &tmp);
+ *ver = tmp;
+ off = 24 + *len;
+ sp->seek(sp, -off, SEEK_CUR);
+ krb5_ret_int32 (sp, &tmp);
+ assert(tmp == *ver);
+ krb5_ret_int32 (sp, &tmp);
+ *timestamp = tmp;
+ krb5_ret_int32 (sp, &tmp);
+ *op = tmp;
+ krb5_ret_int32 (sp, &tmp);
+ assert(tmp == *len);
+ return 0;
+}
+
+/*
+ * Replay a record from the log
+ */
+
+kadm5_ret_t
+kadm5_log_replay (kadm5_server_context *context,
+ enum kadm_ops op,
+ u_int32_t ver,
+ u_int32_t len,
+ krb5_storage *sp)
+{
+ switch (op) {
+ case kadm_create :
+ return kadm5_log_replay_create (context, ver, len, sp);
+ case kadm_delete :
+ return kadm5_log_replay_delete (context, ver, len, sp);
+ case kadm_rename :
+ return kadm5_log_replay_rename (context, ver, len, sp);
+ case kadm_modify :
+ return kadm5_log_replay_modify (context, ver, len, sp);
+ default :
+ return KADM5_FAILURE;
+ }
+}
diff --git a/crypto/heimdal/lib/kadm5/marshall.c b/crypto/heimdal/lib/kadm5/marshall.c
new file mode 100644
index 000000000000..98288376c4f4
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/marshall.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: marshall.c,v 1.6 1999/12/02 17:05:06 joda Exp $");
+
+kadm5_ret_t
+kadm5_store_key_data(krb5_storage *sp,
+ krb5_key_data *key)
+{
+ krb5_data c;
+ krb5_store_int32(sp, key->key_data_ver);
+ krb5_store_int32(sp, key->key_data_kvno);
+ krb5_store_int32(sp, key->key_data_type[0]);
+ c.length = key->key_data_length[0];
+ c.data = key->key_data_contents[0];
+ krb5_store_data(sp, c);
+ krb5_store_int32(sp, key->key_data_type[1]);
+ c.length = key->key_data_length[1];
+ c.data = key->key_data_contents[1];
+ krb5_store_data(sp, c);
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_ret_key_data(krb5_storage *sp,
+ krb5_key_data *key)
+{
+ krb5_data c;
+ int32_t tmp;
+ krb5_ret_int32(sp, &tmp);
+ key->key_data_ver = tmp;
+ krb5_ret_int32(sp, &tmp);
+ key->key_data_kvno = tmp;
+ krb5_ret_int32(sp, &tmp);
+ key->key_data_type[0] = tmp;
+ krb5_ret_data(sp, &c);
+ key->key_data_length[0] = c.length;
+ key->key_data_contents[0] = c.data;
+ krb5_ret_int32(sp, &tmp);
+ key->key_data_type[1] = tmp;
+ krb5_ret_data(sp, &c);
+ key->key_data_length[1] = c.length;
+ key->key_data_contents[1] = c.data;
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_store_tl_data(krb5_storage *sp,
+ krb5_tl_data *tl)
+{
+ krb5_data c;
+ krb5_store_int32(sp, tl->tl_data_type);
+ c.length = tl->tl_data_length;
+ c.data = tl->tl_data_contents;
+ krb5_store_data(sp, c);
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_ret_tl_data(krb5_storage *sp,
+ krb5_tl_data *tl)
+{
+ krb5_data c;
+ int32_t tmp;
+ krb5_ret_int32(sp, &tmp);
+ tl->tl_data_type = tmp;
+ krb5_ret_data(sp, &c);
+ tl->tl_data_length = c.length;
+ tl->tl_data_contents = c.data;
+ return 0;
+}
+
+static kadm5_ret_t
+store_principal_ent(krb5_storage *sp,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask)
+{
+ int i;
+
+ if (mask & KADM5_PRINCIPAL)
+ krb5_store_principal(sp, princ->principal);
+ if (mask & KADM5_PRINC_EXPIRE_TIME)
+ krb5_store_int32(sp, princ->princ_expire_time);
+ if (mask & KADM5_PW_EXPIRATION)
+ krb5_store_int32(sp, princ->pw_expiration);
+ if (mask & KADM5_LAST_PWD_CHANGE)
+ krb5_store_int32(sp, princ->last_pwd_change);
+ if (mask & KADM5_MAX_LIFE)
+ krb5_store_int32(sp, princ->max_life);
+ if (mask & KADM5_MOD_NAME) {
+ krb5_store_int32(sp, princ->mod_name != NULL);
+ if(princ->mod_name)
+ krb5_store_principal(sp, princ->mod_name);
+ }
+ if (mask & KADM5_MOD_TIME)
+ krb5_store_int32(sp, princ->mod_date);
+ if (mask & KADM5_ATTRIBUTES)
+ krb5_store_int32(sp, princ->attributes);
+ if (mask & KADM5_KVNO)
+ krb5_store_int32(sp, princ->kvno);
+ if (mask & KADM5_MKVNO)
+ krb5_store_int32(sp, princ->mkvno);
+ if (mask & KADM5_POLICY) {
+ krb5_store_int32(sp, princ->policy != NULL);
+ if(princ->policy)
+ krb5_store_string(sp, princ->policy);
+ }
+ if (mask & KADM5_AUX_ATTRIBUTES)
+ krb5_store_int32(sp, princ->aux_attributes);
+ if (mask & KADM5_MAX_RLIFE)
+ krb5_store_int32(sp, princ->max_renewable_life);
+ if (mask & KADM5_LAST_SUCCESS)
+ krb5_store_int32(sp, princ->last_success);
+ if (mask & KADM5_LAST_FAILED)
+ krb5_store_int32(sp, princ->last_failed);
+ if (mask & KADM5_FAIL_AUTH_COUNT)
+ krb5_store_int32(sp, princ->fail_auth_count);
+ if (mask & KADM5_KEY_DATA) {
+ krb5_store_int32(sp, princ->n_key_data);
+ for(i = 0; i < princ->n_key_data; i++)
+ kadm5_store_key_data(sp, &princ->key_data[i]);
+ }
+ if (mask & KADM5_TL_DATA) {
+ krb5_tl_data *tp;
+
+ krb5_store_int32(sp, princ->n_tl_data);
+ for(tp = princ->tl_data; tp; tp = tp->tl_data_next)
+ kadm5_store_tl_data(sp, tp);
+ }
+ return 0;
+}
+
+
+kadm5_ret_t
+kadm5_store_principal_ent(krb5_storage *sp,
+ kadm5_principal_ent_t princ)
+{
+ return store_principal_ent (sp, princ, ~0);
+}
+
+kadm5_ret_t
+kadm5_store_principal_ent_mask(krb5_storage *sp,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask)
+{
+ krb5_store_int32(sp, mask);
+ return store_principal_ent (sp, princ, mask);
+}
+
+static kadm5_ret_t
+ret_principal_ent(krb5_storage *sp,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask)
+{
+ int i;
+ int32_t tmp;
+
+ if (mask & KADM5_PRINCIPAL)
+ krb5_ret_principal(sp, &princ->principal);
+
+ if (mask & KADM5_PRINC_EXPIRE_TIME) {
+ krb5_ret_int32(sp, &tmp);
+ princ->princ_expire_time = tmp;
+ }
+ if (mask & KADM5_PW_EXPIRATION) {
+ krb5_ret_int32(sp, &tmp);
+ princ->pw_expiration = tmp;
+ }
+ if (mask & KADM5_LAST_PWD_CHANGE) {
+ krb5_ret_int32(sp, &tmp);
+ princ->last_pwd_change = tmp;
+ }
+ if (mask & KADM5_MAX_LIFE) {
+ krb5_ret_int32(sp, &tmp);
+ princ->max_life = tmp;
+ }
+ if (mask & KADM5_MOD_NAME) {
+ krb5_ret_int32(sp, &tmp);
+ if(tmp)
+ krb5_ret_principal(sp, &princ->mod_name);
+ else
+ princ->mod_name = NULL;
+ }
+ if (mask & KADM5_MOD_TIME) {
+ krb5_ret_int32(sp, &tmp);
+ princ->mod_date = tmp;
+ }
+ if (mask & KADM5_ATTRIBUTES) {
+ krb5_ret_int32(sp, &tmp);
+ princ->attributes = tmp;
+ }
+ if (mask & KADM5_KVNO) {
+ krb5_ret_int32(sp, &tmp);
+ princ->kvno = tmp;
+ }
+ if (mask & KADM5_MKVNO) {
+ krb5_ret_int32(sp, &tmp);
+ princ->mkvno = tmp;
+ }
+ if (mask & KADM5_POLICY) {
+ krb5_ret_int32(sp, &tmp);
+ if(tmp)
+ krb5_ret_string(sp, &princ->policy);
+ else
+ princ->policy = NULL;
+ }
+ if (mask & KADM5_AUX_ATTRIBUTES) {
+ krb5_ret_int32(sp, &tmp);
+ princ->aux_attributes = tmp;
+ }
+ if (mask & KADM5_MAX_RLIFE) {
+ krb5_ret_int32(sp, &tmp);
+ princ->max_renewable_life = tmp;
+ }
+ if (mask & KADM5_LAST_SUCCESS) {
+ krb5_ret_int32(sp, &tmp);
+ princ->last_success = tmp;
+ }
+ if (mask & KADM5_LAST_FAILED) {
+ krb5_ret_int32(sp, &tmp);
+ princ->last_failed = tmp;
+ }
+ if (mask & KADM5_FAIL_AUTH_COUNT) {
+ krb5_ret_int32(sp, &tmp);
+ princ->fail_auth_count = tmp;
+ }
+ if (mask & KADM5_KEY_DATA) {
+ krb5_ret_int32(sp, &tmp);
+ princ->n_key_data = tmp;
+ princ->key_data = malloc(princ->n_key_data * sizeof(*princ->key_data));
+ for(i = 0; i < princ->n_key_data; i++)
+ kadm5_ret_key_data(sp, &princ->key_data[i]);
+ }
+ if (mask & KADM5_TL_DATA) {
+ krb5_ret_int32(sp, &tmp);
+ princ->n_tl_data = tmp;
+ princ->tl_data = NULL;
+ for(i = 0; i < princ->n_tl_data; i++){
+ krb5_tl_data *tp = malloc(sizeof(*tp));
+ kadm5_ret_tl_data(sp, tp);
+ tp->tl_data_next = princ->tl_data;
+ princ->tl_data = tp;
+ }
+ }
+ return 0;
+}
+
+kadm5_ret_t
+kadm5_ret_principal_ent(krb5_storage *sp,
+ kadm5_principal_ent_t princ)
+{
+ return ret_principal_ent (sp, princ, ~0);
+}
+
+kadm5_ret_t
+kadm5_ret_principal_ent_mask(krb5_storage *sp,
+ kadm5_principal_ent_t princ,
+ u_int32_t *mask)
+{
+ int32_t tmp;
+
+ krb5_ret_int32 (sp, &tmp);
+ *mask = tmp;
+ return ret_principal_ent (sp, princ, *mask);
+}
+
+kadm5_ret_t
+_kadm5_marshal_params(krb5_context context,
+ kadm5_config_params *params,
+ krb5_data *out)
+{
+ krb5_storage *sp = krb5_storage_emem();
+
+ krb5_store_int32(sp, params->mask & (KADM5_CONFIG_REALM));
+
+ if(params->mask & KADM5_CONFIG_REALM)
+ krb5_store_string(sp, params->realm);
+ krb5_storage_to_data(sp, out);
+ krb5_storage_free(sp);
+
+ return 0;
+}
+
+kadm5_ret_t
+_kadm5_unmarshal_params(krb5_context context,
+ krb5_data *in,
+ kadm5_config_params *params)
+{
+ krb5_storage *sp = krb5_storage_from_data(in);
+
+ krb5_ret_int32(sp, &params->mask);
+
+ if(params->mask & KADM5_CONFIG_REALM)
+ krb5_ret_string(sp, &params->realm);
+ krb5_storage_free(sp);
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/modify_c.c b/crypto/heimdal/lib/kadm5/modify_c.c
new file mode 100644
index 000000000000..2a64ccc98484
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/modify_c.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: modify_c.c,v 1.3 1999/12/02 17:05:06 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_modify_principal(void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask)
+{
+ kadm5_client_context *context = server_handle;
+ kadm5_ret_t ret;
+ krb5_storage *sp;
+ unsigned char buf[1024];
+ int32_t tmp;
+ krb5_data reply;
+
+ sp = krb5_storage_from_mem(buf, sizeof(buf));
+ if (sp == NULL)
+ return ENOMEM;
+ krb5_store_int32(sp, kadm_modify);
+ kadm5_store_principal_ent(sp, princ);
+ krb5_store_int32(sp, mask);
+ ret = _kadm5_client_send(context, sp);
+ krb5_storage_free(sp);
+ if(ret)
+ return ret;
+ ret = _kadm5_client_recv(context, &reply);
+ if(ret)
+ return ret;
+ sp = krb5_storage_from_data (&reply);
+ if (sp == NULL) {
+ krb5_data_free (&reply);
+ return ENOMEM;
+ }
+ krb5_ret_int32(sp, &tmp);
+ krb5_storage_free(sp);
+ krb5_data_free (&reply);
+ return tmp;
+}
+
diff --git a/crypto/heimdal/lib/kadm5/modify_s.c b/crypto/heimdal/lib/kadm5/modify_s.c
new file mode 100644
index 000000000000..4157202fcd12
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/modify_s.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: modify_s.c,v 1.9 1999/12/02 17:05:06 joda Exp $");
+
+static kadm5_ret_t
+modify_principal(void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask,
+ u_int32_t forbidden_mask)
+{
+ kadm5_server_context *context = server_handle;
+ hdb_entry ent;
+ kadm5_ret_t ret;
+ if((mask & forbidden_mask))
+ return KADM5_BAD_MASK;
+ if((mask & KADM5_POLICY) && strcmp(princ->policy, "default"))
+ return KADM5_UNK_POLICY;
+
+ ent.principal = princ->principal;
+ ret = context->db->open(context->context, context->db, O_RDWR, 0);
+ if(ret)
+ return ret;
+ ret = context->db->fetch(context->context, context->db, 0, &ent);
+ if(ret)
+ goto out;
+ ret = _kadm5_setup_entry(&ent, mask, princ, mask, NULL, 0);
+ if(ret)
+ goto out2;
+ ret = _kadm5_set_modifier(context, &ent);
+ if(ret)
+ goto out2;
+
+ hdb_seal_keys(context->db, &ent);
+
+ kadm5_log_modify (context,
+ &ent,
+ mask | KADM5_MOD_NAME | KADM5_MOD_TIME);
+
+ ret = context->db->store(context->context, context->db,
+ HDB_F_REPLACE, &ent);
+out2:
+ hdb_free_entry(context->context, &ent);
+out:
+ context->db->close(context->context, context->db);
+ return _kadm5_error_code(ret);
+}
+
+
+kadm5_ret_t
+kadm5_s_modify_principal(void *server_handle,
+ kadm5_principal_ent_t princ,
+ u_int32_t mask)
+{
+ return modify_principal(server_handle, princ, mask,
+ KADM5_LAST_PWD_CHANGE | KADM5_MOD_TIME
+ | KADM5_MOD_NAME | KADM5_MKVNO
+ | KADM5_AUX_ATTRIBUTES | KADM5_LAST_SUCCESS
+ | KADM5_LAST_FAILED);
+}
diff --git a/crypto/heimdal/lib/kadm5/password_quality.c b/crypto/heimdal/lib/kadm5/password_quality.c
new file mode 100644
index 000000000000..86d35f36628b
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/password_quality.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: password_quality.c,v 1.3 1999/12/02 17:05:06 joda Exp $");
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+static const char *
+simple_passwd_quality (krb5_context context,
+ krb5_principal principal,
+ krb5_data *pwd)
+{
+ if (pwd->length < 6)
+ return "Password too short";
+ else
+ return NULL;
+}
+
+typedef const char* (*passwd_quality_check_func)(krb5_context,
+ krb5_principal,
+ krb5_data*);
+
+static passwd_quality_check_func passwd_quality_check = simple_passwd_quality;
+
+#ifdef HAVE_DLOPEN
+extern const char *check_library;
+extern const char *check_function;
+
+#define PASSWD_VERSION 0
+
+#endif
+
+/*
+ * setup the password quality hook
+ */
+
+void
+kadm5_setup_passwd_quality_check(krb5_context context,
+ const char *check_library,
+ const char *check_function)
+{
+#ifdef HAVE_DLOPEN
+ void *handle;
+ void *sym;
+ int *version;
+ int flags;
+ const char *tmp;
+
+#ifdef RTLD_NOW
+ flags = RTLD_NOW;
+#else
+ flags = 0;
+#endif
+
+ if(check_library == NULL) {
+ tmp = krb5_config_get_string(context, NULL,
+ "password_quality",
+ "check_library",
+ NULL);
+ if(tmp != NULL)
+ check_library = tmp;
+ }
+ if(check_function == NULL) {
+ tmp = krb5_config_get_string(context, NULL,
+ "password_quality",
+ "check_function",
+ NULL);
+ if(tmp != NULL)
+ check_function = tmp;
+ }
+ if(check_library != NULL && check_function == NULL)
+ check_function = "passwd_check";
+
+ if(check_library == NULL)
+ return;
+ handle = dlopen(check_library, flags);
+ if(handle == NULL) {
+ krb5_warnx(context, "failed to open `%s'", check_library);
+ return;
+ }
+ version = dlsym(handle, "version");
+ if(version == NULL) {
+ krb5_warnx(context,
+ "didn't find `version' symbol in `%s'", check_library);
+ dlclose(handle);
+ return;
+ }
+ if(*version != PASSWD_VERSION) {
+ krb5_warnx(context,
+ "version of loaded library is %d (expected %d)",
+ *version, PASSWD_VERSION);
+ dlclose(handle);
+ return;
+ }
+ sym = dlsym(handle, check_function);
+ if(sym == NULL) {
+ krb5_warnx(context,
+ "didn't find `%s' symbol in `%s'",
+ check_function, check_library);
+ dlclose(handle);
+ return;
+ }
+ passwd_quality_check = (passwd_quality_check_func) sym;
+#endif /* HAVE_DLOPEN */
+}
+
+const char *
+kadm5_check_password_quality (krb5_context context,
+ krb5_principal principal,
+ krb5_data *pwd_data)
+{
+ return (*passwd_quality_check) (context, principal, pwd_data);
+}
diff --git a/crypto/heimdal/lib/kadm5/private.h b/crypto/heimdal/lib/kadm5/private.h
new file mode 100644
index 000000000000..e56a0f5cb1f0
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/private.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: private.h,v 1.10 1999/12/04 23:09:34 assar Exp $ */
+
+#ifndef __kadm5_private_h__
+#define __kadm5_private_h__
+
+struct kadm_func {
+ kadm5_ret_t (*chpass_principal) (void *, krb5_principal, char*);
+ kadm5_ret_t (*create_principal) (void*, kadm5_principal_ent_t,
+ u_int32_t, char*);
+ kadm5_ret_t (*delete_principal) (void*, krb5_principal);
+ kadm5_ret_t (*destroy) (void*);
+ kadm5_ret_t (*flush) (void*);
+ kadm5_ret_t (*get_principal) (void*, krb5_principal,
+ kadm5_principal_ent_t, u_int32_t);
+ kadm5_ret_t (*get_principals) (void*, const char*, char***, int*);
+ kadm5_ret_t (*get_privs) (void*, u_int32_t*);
+ kadm5_ret_t (*modify_principal) (void*, kadm5_principal_ent_t, u_int32_t);
+ kadm5_ret_t (*randkey_principal) (void*, krb5_principal,
+ krb5_keyblock**, int*);
+ kadm5_ret_t (*rename_principal) (void*, krb5_principal, krb5_principal);
+};
+
+/* XXX should be integrated */
+typedef struct kadm5_common_context {
+ krb5_context context;
+ krb5_boolean my_context;
+ struct kadm_func funcs;
+ void *data;
+}kadm5_common_context;
+
+typedef struct kadm5_log_peer {
+ int fd;
+ char *name;
+ krb5_auth_context ac;
+ struct kadm5_log_peer *next;
+} kadm5_log_peer;
+
+typedef struct kadm5_log_context {
+ char *log_file;
+ int log_fd;
+ u_int32_t version;
+ struct sockaddr_un socket_name;
+ int socket_fd;
+} kadm5_log_context;
+
+typedef struct kadm5_server_context {
+ krb5_context context;
+ krb5_boolean my_context;
+ struct kadm_func funcs;
+ /* */
+ kadm5_config_params config;
+ HDB *db;
+ krb5_principal caller;
+ unsigned acl_flags;
+ kadm5_log_context log_context;
+}kadm5_server_context;
+
+typedef struct kadm5_client_context {
+ krb5_context context;
+ krb5_boolean my_context;
+ struct kadm_func funcs;
+ /* */
+ krb5_auth_context ac;
+ char *realm;
+ char *admin_server;
+ int kadmind_port;
+ int sock;
+}kadm5_client_context;
+
+enum kadm_ops {
+ kadm_get,
+ kadm_delete,
+ kadm_create,
+ kadm_rename,
+ kadm_chpass,
+ kadm_modify,
+ kadm_randkey,
+ kadm_get_privs,
+ kadm_get_princs
+};
+
+#define KADMIN_APPL_VERSION "KADM0.1"
+#define KADMIN_OLD_APPL_VERSION "KADM0.0"
+
+#define KADM5_LOG_SIGNAL HDB_DB_DIR "/signal"
+
+kadm5_ret_t _kadm5_privs_to_string (u_int32_t, char*, size_t);
+
+kadm5_ret_t _kadm5_string_to_privs (const char*, u_int32_t*);
+
+HDB *_kadm5_s_get_db (void *);
+
+kadm5_ret_t
+_kadm5_acl_check_permission __P((
+ kadm5_server_context *context,
+ unsigned op));
+
+kadm5_ret_t
+_kadm5_acl_init __P((kadm5_server_context *context));
+
+kadm5_ret_t
+_kadm5_c_init_context __P((
+ kadm5_client_context **ctx,
+ kadm5_config_params *params,
+ krb5_context context));
+
+kadm5_ret_t
+_kadm5_client_recv __P((
+ kadm5_client_context *context,
+ krb5_data *reply));
+
+kadm5_ret_t
+_kadm5_client_send __P((
+ kadm5_client_context *context,
+ krb5_storage *sp));
+
+kadm5_ret_t
+_kadm5_error_code __P((kadm5_ret_t code));
+
+kadm5_ret_t
+_kadm5_s_init_context __P((
+ kadm5_server_context **ctx,
+ kadm5_config_params *params,
+ krb5_context context));
+
+kadm5_ret_t
+_kadm5_set_keys __P((
+ kadm5_server_context *context,
+ hdb_entry *ent,
+ const char *password));
+
+kadm5_ret_t
+_kadm5_set_keys2 __P((
+ hdb_entry *ent,
+ int16_t n_key_data,
+ krb5_key_data *key_data));
+
+kadm5_ret_t
+_kadm5_set_keys_randomly __P((kadm5_server_context *context,
+ hdb_entry *ent,
+ krb5_keyblock **new_keys,
+ int *n_keys));
+
+kadm5_ret_t
+_kadm5_set_modifier __P((
+ kadm5_server_context *context,
+ hdb_entry *ent));
+
+kadm5_ret_t
+_kadm5_setup_entry __P((
+ hdb_entry *ent,
+ u_int32_t mask,
+ kadm5_principal_ent_t princ,
+ u_int32_t princ_mask,
+ kadm5_principal_ent_t def,
+ u_int32_t def_mask));
+
+kadm5_ret_t
+kadm5_log_get_version (int fd,
+ u_int32_t *ver);
+
+kadm5_ret_t
+kadm5_log_init (kadm5_server_context *context);
+
+kadm5_ret_t
+kadm5_log_create (kadm5_server_context *context,
+ hdb_entry *ent);
+
+kadm5_ret_t
+kadm5_log_delete (kadm5_server_context *context,
+ krb5_principal princ);
+
+kadm5_ret_t
+kadm5_log_rename (kadm5_server_context *context,
+ krb5_principal source,
+ hdb_entry *ent);
+
+kadm5_ret_t
+kadm5_log_modify (kadm5_server_context *context,
+ hdb_entry *ent,
+ u_int32_t mask);
+
+kadm5_ret_t
+kadm5_log_end (kadm5_server_context *context);
+
+kadm5_ret_t
+kadm5_log_foreach (kadm5_server_context *context,
+ void (*func)(kadm5_server_context *server_context,
+ u_int32_t ver,
+ time_t timestamp,
+ enum kadm_ops op,
+ u_int32_t len,
+ krb5_storage *sp));
+
+kadm5_ret_t
+kadm5_log_replay_create (kadm5_server_context *context,
+ u_int32_t ver,
+ u_int32_t len,
+ krb5_storage *sp);
+
+kadm5_ret_t
+kadm5_log_replay_delete (kadm5_server_context *context,
+ u_int32_t ver,
+ u_int32_t len,
+ krb5_storage *sp);
+
+kadm5_ret_t
+kadm5_log_replay_rename (kadm5_server_context *context,
+ u_int32_t ver,
+ u_int32_t len,
+ krb5_storage *sp);
+
+kadm5_ret_t
+kadm5_log_replay_modify (kadm5_server_context *context,
+ u_int32_t ver,
+ u_int32_t len,
+ krb5_storage *sp);
+
+kadm5_ret_t
+kadm5_log_replay (kadm5_server_context *context,
+ enum kadm_ops op,
+ u_int32_t ver,
+ u_int32_t len,
+ krb5_storage *sp);
+
+krb5_storage *
+kadm5_log_goto_end (int fd);
+
+kadm5_ret_t
+kadm5_log_previous (krb5_storage *sp,
+ u_int32_t *ver,
+ time_t *timestamp,
+ enum kadm_ops *op,
+ u_int32_t *len);
+
+kadm5_ret_t
+_kadm5_marshal_params __P((krb5_context context,
+ kadm5_config_params *params,
+ krb5_data *out));
+
+kadm5_ret_t
+_kadm5_unmarshal_params __P((krb5_context context,
+ krb5_data *in,
+ kadm5_config_params *params));
+
+
+
+#endif /* __kadm5_private_h__ */
diff --git a/crypto/heimdal/lib/kadm5/privs_c.c b/crypto/heimdal/lib/kadm5/privs_c.c
new file mode 100644
index 000000000000..25d49761cdd0
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/privs_c.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: privs_c.c,v 1.3 1999/12/02 17:05:07 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_get_privs(void *server_handle, u_int32_t *privs)
+{
+ kadm5_client_context *context = server_handle;
+ kadm5_ret_t ret;
+ krb5_storage *sp;
+ unsigned char buf[1024];
+ int32_t tmp;
+ krb5_data reply;
+
+ sp = krb5_storage_from_mem(buf, sizeof(buf));
+ if (sp == NULL)
+ return ENOMEM;
+ krb5_store_int32(sp, kadm_get_privs);
+ ret = _kadm5_client_send(context, sp);
+ krb5_storage_free(sp);
+ if(ret)
+ return ret;
+ ret = _kadm5_client_recv(context, &reply);
+ if (ret)
+ return ret;
+ sp = krb5_storage_from_data(&reply);
+ if (sp == NULL) {
+ krb5_data_free (&reply);
+ return ENOMEM;
+ }
+ krb5_ret_int32(sp, &tmp);
+ ret = tmp;
+ if(ret == 0){
+ krb5_ret_int32(sp, &tmp);
+ *privs = tmp;
+ }
+ krb5_storage_free(sp);
+ krb5_data_free (&reply);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/kadm5/privs_s.c b/crypto/heimdal/lib/kadm5/privs_s.c
new file mode 100644
index 000000000000..85cd5d597d00
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/privs_s.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: privs_s.c,v 1.2 1999/12/02 17:05:07 joda Exp $");
+
+kadm5_ret_t
+kadm5_s_get_privs(void *server_handle, u_int32_t *privs)
+{
+ kadm5_server_context *context = server_handle;
+ *privs = context->acl_flags;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/randkey_c.c b/crypto/heimdal/lib/kadm5/randkey_c.c
new file mode 100644
index 000000000000..7531b6e9f096
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/randkey_c.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: randkey_c.c,v 1.3 1999/12/02 17:05:07 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_randkey_principal(void *server_handle,
+ krb5_principal princ,
+ krb5_keyblock **new_keys,
+ int *n_keys)
+{
+ kadm5_client_context *context = server_handle;
+ kadm5_ret_t ret;
+ krb5_storage *sp;
+ unsigned char buf[1024];
+ int32_t tmp;
+ krb5_data reply;
+
+ sp = krb5_storage_from_mem(buf, sizeof(buf));
+ if (sp == NULL)
+ return ENOMEM;
+ krb5_store_int32(sp, kadm_randkey);
+ krb5_store_principal(sp, princ);
+ ret = _kadm5_client_send(context, sp);
+ krb5_storage_free(sp);
+ if (ret)
+ return ret;
+ ret = _kadm5_client_recv(context, &reply);
+ if(ret)
+ return ret;
+ sp = krb5_storage_from_data(&reply);
+ if (sp == NULL) {
+ krb5_data_free (&reply);
+ return ENOMEM;
+ }
+ krb5_ret_int32(sp, &tmp);
+ ret = tmp;
+ if(ret == 0){
+ krb5_keyblock *k;
+ int i;
+
+ krb5_ret_int32(sp, &tmp);
+ k = malloc(tmp * sizeof(*k));
+ if (k == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ for(i = 0; i < tmp; i++)
+ krb5_ret_keyblock(sp, &k[i]);
+ *n_keys = tmp;
+ *new_keys = k;
+ }
+out:
+ krb5_storage_free(sp);
+ krb5_data_free (&reply);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/kadm5/randkey_s.c b/crypto/heimdal/lib/kadm5/randkey_s.c
new file mode 100644
index 000000000000..25c857174501
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/randkey_s.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: randkey_s.c,v 1.10 1999/12/02 17:05:07 joda Exp $");
+
+/*
+ * Set the keys of `princ' to random values, returning the random keys
+ * in `new_keys', `n_keys'.
+ */
+
+kadm5_ret_t
+kadm5_s_randkey_principal(void *server_handle,
+ krb5_principal princ,
+ krb5_keyblock **new_keys,
+ int *n_keys)
+{
+ kadm5_server_context *context = server_handle;
+ hdb_entry ent;
+ kadm5_ret_t ret;
+
+ ent.principal = princ;
+ ret = context->db->open(context->context, context->db, O_RDWR, 0);
+ if(ret)
+ return ret;
+ ret = context->db->fetch(context->context, context->db, 0, &ent);
+ if(ret)
+ goto out;
+
+ ret = _kadm5_set_keys_randomly (context,
+ &ent,
+ new_keys,
+ n_keys);
+ if (ret)
+ goto out2;
+
+ ret = _kadm5_set_modifier(context, &ent);
+ if(ret)
+ goto out3;
+
+ hdb_seal_keys(context->db, &ent);
+
+ kadm5_log_modify (context,
+ &ent,
+ KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME |
+ KADM5_KEY_DATA | KADM5_KVNO);
+
+ ret = context->db->store(context->context, context->db,
+ HDB_F_REPLACE, &ent);
+out3:
+ if (ret) {
+ int i;
+
+ for (i = 0; i < *n_keys; ++i)
+ krb5_free_keyblock_contents (context->context, &(*new_keys)[i]);
+ free (*new_keys);
+ *new_keys = NULL;
+ *n_keys = 0;
+ }
+out2:
+ hdb_free_entry(context->context, &ent);
+out:
+ context->db->close(context->context, context->db);
+ return _kadm5_error_code(ret);
+}
diff --git a/crypto/heimdal/lib/kadm5/rename_c.c b/crypto/heimdal/lib/kadm5/rename_c.c
new file mode 100644
index 000000000000..d33e611dedd3
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/rename_c.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: rename_c.c,v 1.3 1999/12/02 17:05:07 joda Exp $");
+
+kadm5_ret_t
+kadm5_c_rename_principal(void *server_handle,
+ krb5_principal source,
+ krb5_principal target)
+{
+ kadm5_client_context *context = server_handle;
+ kadm5_ret_t ret;
+ krb5_storage *sp;
+ unsigned char buf[1024];
+ int32_t tmp;
+ krb5_data reply;
+
+ sp = krb5_storage_from_mem(buf, sizeof(buf));
+ if (sp == NULL)
+ return ENOMEM;
+ krb5_store_int32(sp, kadm_rename);
+ krb5_store_principal(sp, source);
+ krb5_store_principal(sp, target);
+ ret = _kadm5_client_send(context, sp);
+ krb5_storage_free(sp);
+ if (ret)
+ return ret;
+ ret = _kadm5_client_recv(context, &reply);
+ if(ret)
+ return ret;
+ sp = krb5_storage_from_data (&reply);
+ if (sp == NULL) {
+ krb5_data_free (&reply);
+ return ENOMEM;
+ }
+ krb5_ret_int32(sp, &tmp);
+ ret = tmp;
+ krb5_storage_free(sp);
+ krb5_data_free (&reply);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/kadm5/rename_s.c b/crypto/heimdal/lib/kadm5/rename_s.c
new file mode 100644
index 000000000000..e7f9038baba0
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/rename_s.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: rename_s.c,v 1.9 1999/12/02 17:05:07 joda Exp $");
+
+kadm5_ret_t
+kadm5_s_rename_principal(void *server_handle,
+ krb5_principal source,
+ krb5_principal target)
+{
+ kadm5_server_context *context = server_handle;
+ kadm5_ret_t ret;
+ hdb_entry ent, ent2;
+ ent.principal = source;
+ if(krb5_principal_compare(context->context, source, target))
+ return KADM5_DUP; /* XXX is this right? */
+ if(!krb5_realm_compare(context->context, source, target))
+ return KADM5_FAILURE; /* XXX better code */
+ ret = context->db->open(context->context, context->db, O_RDWR, 0);
+ if(ret)
+ return ret;
+ ret = context->db->fetch(context->context, context->db, 0, &ent);
+ if(ret){
+ context->db->close(context->context, context->db);
+ goto out;
+ }
+ ret = _kadm5_set_modifier(context, &ent);
+ if(ret)
+ goto out2;
+ {
+ /* fix salt */
+ int i;
+ Salt salt;
+ krb5_salt salt2;
+ krb5_get_pw_salt(context->context, source, &salt2);
+ salt.type = hdb_pw_salt;
+ salt.salt = salt2.saltvalue;
+ for(i = 0; i < ent.keys.len; i++){
+ if(ent.keys.val[i].salt == NULL){
+ ent.keys.val[i].salt = malloc(sizeof(*ent.keys.val[i].salt));
+ ret = copy_Salt(&salt, ent.keys.val[i].salt);
+ if(ret)
+ break;
+ }
+ }
+ krb5_free_salt(context->context, salt2);
+ }
+ if(ret)
+ goto out2;
+ ent2.principal = ent.principal;
+ ent.principal = target;
+
+ hdb_seal_keys(context->db, &ent);
+
+ kadm5_log_rename (context,
+ source,
+ &ent);
+
+ ret = context->db->store(context->context, context->db, 0, &ent);
+ if(ret){
+ ent.principal = ent2.principal;
+ goto out2;
+ }
+ ret = context->db->remove(context->context, context->db, &ent2);
+ ent.principal = ent2.principal;
+out2:
+ context->db->close(context->context, context->db);
+ hdb_free_entry(context->context, &ent);
+out:
+ return _kadm5_error_code(ret);
+}
+
diff --git a/crypto/heimdal/lib/kadm5/replay_log.c b/crypto/heimdal/lib/kadm5/replay_log.c
new file mode 100644
index 000000000000..c0e05eee6af0
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/replay_log.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "iprop.h"
+
+RCSID("$Id: replay_log.c,v 1.7 1999/12/04 19:51:11 assar Exp $");
+
+static void
+apply_entry(kadm5_server_context *server_context,
+ u_int32_t ver,
+ time_t timestamp,
+ enum kadm_ops op,
+ u_int32_t len,
+ krb5_storage *sp)
+{
+ krb5_error_code ret;
+
+ printf ("ver %u... ", ver);
+ fflush (stdout);
+
+ ret = kadm5_log_replay (server_context,
+ op, ver, len, sp);
+ if (ret)
+ krb5_warn (server_context->context, ret, "kadm5_log_replay");
+
+
+ printf ("done\n");
+}
+
+int version_flag;
+int help_flag;
+struct getargs args[] = {
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+int num_args = sizeof(args) / sizeof(args[0]);
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ void *kadm_handle;
+ kadm5_config_params conf;
+ kadm5_server_context *server_context;
+
+ krb5_program_setup(&context, argc, argv, args, num_args, NULL);
+
+ if(help_flag)
+ krb5_std_usage(0, args, num_args);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ memset(&conf, 0, sizeof(conf));
+ ret = kadm5_init_with_password_ctx (context,
+ KADM5_ADMIN_SERVICE,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm_handle);
+ if (ret)
+ krb5_err (context, 1, ret, "kadm5_init_with_password_ctx");
+
+ server_context = (kadm5_server_context *)kadm_handle;
+
+ ret = server_context->db->open(context,
+ server_context->db,
+ O_RDWR | O_CREAT, 0);
+ if (ret)
+ krb5_err (context, 1, ret, "db->open");
+
+ ret = kadm5_log_init (server_context);
+ if (ret)
+ krb5_err (context, 1, ret, "kadm5_log_init");
+
+ ret = kadm5_log_foreach (server_context, apply_entry);
+ if(ret)
+ krb5_warn(context, ret, "kadm5_log_foreach");
+ ret = kadm5_log_end (server_context);
+ if (ret)
+ krb5_warn(context, ret, "kadm5_log_end");
+ ret = server_context->db->close (context, server_context->db);
+ if (ret)
+ krb5_err (context, 1, ret, "db->close");
+ return 0;
+}
diff --git a/crypto/heimdal/lib/kadm5/sample_passwd_check.c b/crypto/heimdal/lib/kadm5/sample_passwd_check.c
new file mode 100644
index 000000000000..4ff5122c164b
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/sample_passwd_check.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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. */
+
+/* $Id: sample_passwd_check.c,v 1.1 1999/09/10 10:11:03 assar Exp $ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <krb5.h>
+
+/* specify the api-version this library conforms to */
+
+int version = 0;
+
+/* just check the length of the password, this is what the default
+ check does, but this lets you specify the minimum length in
+ krb5.conf */
+const char*
+check_length(krb5_context context,
+ krb5_principal prinipal,
+ krb5_data *password)
+{
+ int min_length = krb5_config_get_int_default(context, NULL, 6,
+ "password_quality",
+ "min_length",
+ NULL);
+ if(password->length < min_length)
+ return "Password too short";
+ return NULL;
+}
+
+#ifdef DICTPATH
+
+/* use cracklib to check password quality; this requires a patch for
+ cracklib that can be found at
+ ftp://ftp.pdc.kth.se/pub/krb/src/cracklib.patch */
+
+const char*
+check_cracklib(krb5_context context,
+ krb5_principal principal,
+ krb5_data *password)
+{
+ char *s = malloc(password->length + 1);
+ char *msg;
+ char *strings[2];
+ if(s == NULL)
+ return NULL; /* XXX */
+ strings[0] = principal->name.name_string.val[0]; /* XXX */
+ strings[1] = NULL;
+ memcpy(s, password->data, password->length);
+ s[password->length] = '\0';
+ msg = FascistCheck(s, DICTPATH, strings);
+ memset(s, 0, password->length);
+ free(s);
+ return msg;
+}
+#endif
diff --git a/crypto/heimdal/lib/kadm5/send_recv.c b/crypto/heimdal/lib/kadm5/send_recv.c
new file mode 100644
index 000000000000..51f6972c12f3
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/send_recv.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: send_recv.c,v 1.7 1999/12/02 17:05:07 joda Exp $");
+
+kadm5_ret_t
+_kadm5_client_send(kadm5_client_context *context, krb5_storage *sp)
+{
+ krb5_data msg, out;
+ krb5_error_code ret;
+ size_t len;
+ krb5_storage *sock;
+
+ len = sp->seek(sp, 0, SEEK_CUR);
+ ret = krb5_data_alloc(&msg, len);
+ sp->seek(sp, 0, SEEK_SET);
+ sp->fetch(sp, msg.data, msg.length);
+
+ ret = krb5_mk_priv(context->context, context->ac, &msg, &out, NULL);
+ krb5_data_free(&msg);
+ if(ret)
+ return ret;
+
+ sock = krb5_storage_from_fd(context->sock);
+ if(sock == NULL) {
+ krb5_data_free(&out);
+ return ENOMEM;
+ }
+
+ ret = krb5_store_data(sock, out);
+ krb5_storage_free(sock);
+ krb5_data_free(&out);
+ return ret;
+}
+
+kadm5_ret_t
+_kadm5_client_recv(kadm5_client_context *context, krb5_data *reply)
+{
+ krb5_error_code ret;
+ krb5_data data;
+ krb5_storage *sock;
+
+ sock = krb5_storage_from_fd(context->sock);
+ if(sock == NULL)
+ return ENOMEM;
+ ret = krb5_ret_data(sock, &data);
+ krb5_storage_free(sock);
+ if(ret == KRB5_CC_END)
+ return KADM5_RPC_ERROR;
+ else if(ret)
+ return ret;
+
+ ret = krb5_rd_priv(context->context, context->ac, &data, reply, NULL);
+ krb5_data_free(&data);
+ return ret;
+}
+
diff --git a/crypto/heimdal/lib/kadm5/server_glue.c b/crypto/heimdal/lib/kadm5/server_glue.c
new file mode 100644
index 000000000000..21b60776add0
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/server_glue.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: server_glue.c,v 1.6 1999/12/02 17:05:07 joda Exp $");
+
+kadm5_ret_t
+kadm5_init_with_password(const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_s_init_with_password(client_name,
+ password,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_init_with_password_ctx(krb5_context context,
+ const char *client_name,
+ const char *password,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_s_init_with_password_ctx(context,
+ client_name,
+ password,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_init_with_skey(const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_s_init_with_skey(client_name,
+ keytab,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_init_with_skey_ctx(krb5_context context,
+ const char *client_name,
+ const char *keytab,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_s_init_with_skey_ctx(context,
+ client_name,
+ keytab,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_init_with_creds(const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_s_init_with_creds(client_name,
+ ccache,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
+
+kadm5_ret_t
+kadm5_init_with_creds_ctx(krb5_context context,
+ const char *client_name,
+ krb5_ccache ccache,
+ const char *service_name,
+ kadm5_config_params *realm_params,
+ unsigned long struct_version,
+ unsigned long api_version,
+ void **server_handle)
+{
+ return kadm5_s_init_with_creds_ctx(context,
+ client_name,
+ ccache,
+ service_name,
+ realm_params,
+ struct_version,
+ api_version,
+ server_handle);
+}
diff --git a/crypto/heimdal/lib/kadm5/set_keys.c b/crypto/heimdal/lib/kadm5/set_keys.c
new file mode 100644
index 000000000000..e4d5d1a64878
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/set_keys.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: set_keys.c,v 1.18 1999/12/04 23:11:01 assar Exp $");
+
+/*
+ * free all the memory used by (len, keys)
+ */
+
+static void
+free_keys (kadm5_server_context *context,
+ int len, Key *keys)
+{
+ int i;
+
+ for (i = 0; i < len; ++i) {
+ free (keys[i].mkvno);
+ keys[i].mkvno = NULL;
+ if (keys[i].salt != NULL) {
+ free_Salt(keys[i].salt);
+ free(keys[i].salt);
+ keys[i].salt = NULL;
+ }
+ krb5_free_keyblock_contents(context->context, &keys[i].key);
+ }
+ free (keys);
+}
+
+/*
+ * null-ify `len', `keys'
+ */
+
+static void
+init_keys (Key *keys, int len)
+{
+ int i;
+
+ for (i = 0; i < len; ++i) {
+ keys[i].mkvno = NULL;
+ keys[i].salt = NULL;
+ keys[i].key.keyvalue.length = 0;
+ keys[i].key.keyvalue.data = NULL;
+ }
+}
+
+/*
+ * the known and used DES enctypes
+ */
+
+static krb5_enctype des_types[] = { ETYPE_DES_CBC_CRC,
+ ETYPE_DES_CBC_MD4,
+ ETYPE_DES_CBC_MD5 };
+
+static unsigned n_des_types = 3;
+
+/*
+ * Set the keys of `ent' to the string-to-key of `password'
+ */
+
+kadm5_ret_t
+_kadm5_set_keys(kadm5_server_context *context,
+ hdb_entry *ent,
+ const char *password)
+{
+ kadm5_ret_t ret = 0;
+ int i;
+ unsigned len;
+ Key *keys;
+ krb5_salt salt;
+ krb5_boolean v4_salt = FALSE;
+
+ len = n_des_types + 1;
+ keys = malloc (len * sizeof(*keys));
+ if (keys == NULL)
+ return ENOMEM;
+
+ init_keys (keys, len);
+
+ salt.salttype = KRB5_PW_SALT;
+ salt.saltvalue.length = 0;
+ salt.saltvalue.data = NULL;
+
+ if (krb5_config_get_bool (context->context,
+ NULL, "kadmin", "use_v4_salt", NULL)) {
+ v4_salt = TRUE;
+ } else {
+ ret = krb5_get_pw_salt (context->context, ent->principal, &salt);
+ if (ret)
+ goto out;
+ }
+
+ for (i = 0; i < n_des_types; ++i) {
+ ret = krb5_string_to_key_salt (context->context,
+ des_types[i],
+ password,
+ salt,
+ &keys[i].key);
+ if (ret)
+ goto out;
+ if (v4_salt) {
+ keys[i].salt = malloc (sizeof(*keys[i].salt));
+ if (keys[i].salt == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ keys[i].salt->type = salt.salttype;
+ ret = copy_octet_string (&salt.saltvalue, &keys[i].salt->salt);
+ if (ret)
+ goto out;
+ }
+ }
+
+ ret = krb5_string_to_key (context->context,
+ ETYPE_DES3_CBC_SHA1,
+ password,
+ ent->principal,
+ &keys[n_des_types].key);
+ if (ret)
+ goto out;
+
+ free_keys (context, ent->keys.len, ent->keys.val);
+ ent->keys.len = len;
+ ent->keys.val = keys;
+ ent->kvno++;
+ return ret;
+out:
+ krb5_data_free (&salt.saltvalue);
+ free_keys (context, len, keys);
+ return ret;
+}
+
+/*
+ * Set the keys of `ent' to (`n_key_data', `key_data')
+ */
+
+kadm5_ret_t
+_kadm5_set_keys2(hdb_entry *ent,
+ int16_t n_key_data,
+ krb5_key_data *key_data)
+{
+ krb5_error_code ret;
+ int i;
+
+ ent->keys.len = n_key_data;
+ ent->keys.val = malloc(ent->keys.len * sizeof(*ent->keys.val));
+ if(ent->keys.val == NULL)
+ return ENOMEM;
+ for(i = 0; i < n_key_data; i++) {
+ ent->keys.val[i].mkvno = NULL;
+ ent->keys.val[i].key.keytype = key_data[i].key_data_type[0];
+ ret = krb5_data_copy(&ent->keys.val[i].key.keyvalue,
+ key_data[i].key_data_contents[0],
+ key_data[i].key_data_length[0]);
+ if(ret)
+ return ret;
+ if(key_data[i].key_data_ver == 2) {
+ Salt *salt;
+ salt = malloc(sizeof(*salt));
+ if(salt == NULL)
+ return ENOMEM;
+ ent->keys.val[i].salt = salt;
+ salt->type = key_data[i].key_data_type[1];
+ krb5_data_copy(&salt->salt,
+ key_data[i].key_data_contents[1],
+ key_data[i].key_data_length[1]);
+ } else
+ ent->keys.val[i].salt = NULL;
+ }
+ ent->kvno++;
+ return 0;
+}
+
+/*
+ * Set the keys of `ent' to random keys and return them in `n_keys'
+ * and `new_keys'.
+ */
+
+kadm5_ret_t
+_kadm5_set_keys_randomly (kadm5_server_context *context,
+ hdb_entry *ent,
+ krb5_keyblock **new_keys,
+ int *n_keys)
+{
+ kadm5_ret_t ret = 0;
+ int i;
+ unsigned len;
+ krb5_keyblock *keys;
+ Key *hkeys;
+
+ len = n_des_types + 1;
+ keys = malloc (len * sizeof(*keys));
+ if (keys == NULL)
+ return ENOMEM;
+
+ for (i = 0; i < len; ++i) {
+ keys[i].keyvalue.length = 0;
+ keys[i].keyvalue.data = NULL;
+ }
+
+ hkeys = malloc (len * sizeof(*hkeys));
+ if (hkeys == NULL) {
+ free (keys);
+ return ENOMEM;
+ }
+
+ init_keys (hkeys, len);
+
+ ret = krb5_generate_random_keyblock (context->context,
+ des_types[0],
+ &keys[0]);
+ if (ret)
+ goto out;
+
+ ret = krb5_copy_keyblock_contents (context->context,
+ &keys[0],
+ &hkeys[0].key);
+ if (ret)
+ goto out;
+
+ for (i = 1; i < n_des_types; ++i) {
+ ret = krb5_copy_keyblock_contents (context->context,
+ &keys[0],
+ &keys[i]);
+ if (ret)
+ goto out;
+ keys[i].keytype = des_types[i];
+ ret = krb5_copy_keyblock_contents (context->context,
+ &keys[0],
+ &hkeys[i].key);
+ if (ret)
+ goto out;
+ hkeys[i].key.keytype = des_types[i];
+ }
+
+ ret = krb5_generate_random_keyblock (context->context,
+ ETYPE_DES3_CBC_SHA1,
+ &keys[n_des_types]);
+ if (ret)
+ goto out;
+
+ ret = krb5_copy_keyblock_contents (context->context,
+ &keys[n_des_types],
+ &hkeys[n_des_types].key);
+ if (ret)
+ goto out;
+
+ free_keys (context, ent->keys.len, ent->keys.val);
+ ent->keys.len = len;
+ ent->keys.val = hkeys;
+ ent->kvno++;
+ *new_keys = keys;
+ *n_keys = len;
+ return ret;
+out:
+ for (i = 0; i < len; ++i)
+ krb5_free_keyblock_contents (context->context, &keys[i]);
+ free (keys);
+ free_keys (context, len, hkeys);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/kadm5/set_modifier.c b/crypto/heimdal/lib/kadm5/set_modifier.c
new file mode 100644
index 000000000000..2b097459b5d2
--- /dev/null
+++ b/crypto/heimdal/lib/kadm5/set_modifier.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kadm5_locl.h"
+
+RCSID("$Id: set_modifier.c,v 1.2 1999/12/02 17:05:07 joda Exp $");
+
+kadm5_ret_t
+_kadm5_set_modifier(kadm5_server_context *context,
+ hdb_entry *ent)
+{
+ kadm5_ret_t ret;
+ if(ent->modified_by == NULL){
+ ent->modified_by = malloc(sizeof(*ent->modified_by));
+ if(ent->modified_by == NULL)
+ return ENOMEM;
+ } else
+ free_Event(ent->modified_by);
+ ent->modified_by->time = time(NULL);
+ ret = krb5_copy_principal(context->context, context->caller,
+ &ent->modified_by->principal);
+ return ret;
+}
+
diff --git a/crypto/heimdal/lib/kafs/ChangeLog b/crypto/heimdal/lib/kafs/ChangeLog
new file mode 100644
index 000000000000..09ea01ed95e5
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/ChangeLog
@@ -0,0 +1,169 @@
+1999-12-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 1:2:1
+
+1999-11-22 Assar Westerlund <assar@sics.se>
+
+ * afskrb5.c (afslog_uid_int): handle d->realm == NULL
+
+1999-11-17 Assar Westerlund <assar@sics.se>
+
+ * afskrb5.c (afslog_uid_int): don't look at the local realm at
+ all. just use the realm from the ticket file.
+
+1999-10-20 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 1:1:1
+
+ * afskrb5.c (get_cred): always request a DES key
+
+Mon Oct 18 17:40:21 1999 Bjoern Groenvall <bg@mummel.sics.se>
+
+ * common.c (find_cells): Trim trailing whitespace from
+ cellname. Lines starting with # are regarded as comments.
+
+Fri Oct 8 18:17:22 1999 Bjoern Groenvall <bg@mummel.sics.se>
+
+ * afskrb.c, common.c : Change code to make a clear distinction
+ between hinted realm and ticket realm.
+
+ * kafs_locl.h: Added argument realm_hint.
+
+ * common.c (_kafs_get_cred): Change code to acquire the ``best''
+ possible ticket. Use cross-cell authentication only as method of
+ last resort.
+
+ * afskrb.c (afslog_uid_int): Add realm_hint argument and extract
+ realm from ticket file.
+
+ * afskrb5.c (afslog_uid_int): Added argument realm_hint.
+
+1999-10-03 Assar Westerlund <assar@sics.se>
+
+ * afskrb5.c (get_cred): update to new krb524_convert_creds_kdc
+
+1999-08-12 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: ignore the comlicated aix construct if !krb4
+
+1999-07-26 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 1:0:1
+
+1999-07-22 Assar Westerlund <assar@sics.se>
+
+ * afssysdefs.h: define AFS_SYSCALL to 73 for Solaris 2.7
+
+1999-07-07 Assar Westerlund <assar@sics.se>
+
+ * afskrb5.c (krb5_realm_of_cell): new function
+
+ * afskrb.c (krb_realm_of_cell): new function
+ (afslog_uid_int): call krb_get_lrealm correctly
+
+1999-06-15 Assar Westerlund <assar@sics.se>
+
+ * common.c (realm_of_cell): rename to _kafs_realm_of_cell and
+ un-staticize
+
+Fri Mar 19 14:52:29 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: add version-info
+
+Thu Mar 18 11:24:02 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: include Makefile.am.common
+
+Sat Feb 27 19:46:21 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: remove EXTRA_DATA (as of autoconf 2.13/automake
+ 1.4)
+
+Thu Feb 11 22:57:37 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: set AIX_SRC also if !AIX
+
+Tue Dec 1 14:45:15 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: fix AIX linkage
+
+Sun Nov 22 10:40:44 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (WFLAGS): set
+
+Sat Nov 21 16:55:19 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * afskrb5.c: add homedir support
+
+Sun Sep 6 20:16:27 1998 Assar Westerlund <assar@sics.se>
+
+ * add new functionality for specifying the homedir to krb_afslog
+ et al
+
+Thu Jul 16 01:27:19 1998 Assar Westerlund <assar@sics.se>
+
+ * afssys.c: reorganize order of definitions.
+ (try_one, try_two): conditionalize
+
+Thu Jul 9 18:31:52 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * common.c (realm_of_cell): make the dns fallback work
+
+Wed Jul 8 01:39:44 1998 Assar Westerlund <assar@sics.se>
+
+ * afssys.c (map_syscall_name_to_number): new function for finding
+ the number of a syscall given the name on solaris
+ (k_hasafs): try using map_syscall_name_to_number
+
+Tue Jun 30 17:19:00 1998 Assar Westerlund <assar@sics.se>
+
+ * afssys.c: rewrite and add support for environment variable
+ AFS_SYSCALL
+
+ * Makefile.in (distclean): don't remove roken_rename.h
+
+Fri May 29 19:03:20 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (roken_rename.h): remove dependency
+
+Mon May 25 05:25:54 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (clean): try to remove shared library debris
+
+Sun Apr 19 09:58:40 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: add symlink magic for linux
+
+Sat Apr 4 15:08:48 1998 Assar Westerlund <assar@sics.se>
+
+ * kafs.h: add arla paths
+
+ * common.c (_kafs_afslog_all_local_cells): Try _PATH_ARLA_*
+ (_realm_of_cell): Try _PATH_ARLA_CELLSERVDB
+
+Thu Feb 19 14:50:22 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * common.c: Don't store expired tokens (this broke when using
+ pag-less rsh-sessions, and `non-standard' ticket files).
+
+Thu Feb 12 11:20:15 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Makefile.in: Install/uninstall one library at a time.
+
+Thu Feb 12 05:38:58 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (install): one library at a time.
+
+Mon Feb 9 23:40:32 1998 Assar Westerlund <assar@sics.se>
+
+ * common.c (find_cells): ignore empty lines
+
+Tue Jan 6 04:25:58 1998 Assar Westerlund <assar@sics.se>
+
+ * afssysdefs.h (AFS_SYSCALL): add FreeBSD
+
+Fri Jan 2 17:08:24 1998 Assar Westerlund <assar@sics.se>
+
+ * kafs.h: new VICEIOCTL's. From <rb@stacken.kth.se>
+
+ * afssysdefs.h: Add OpenBSD
diff --git a/crypto/heimdal/lib/kafs/Makefile.am b/crypto/heimdal/lib/kafs/Makefile.am
new file mode 100644
index 000000000000..2460e555e266
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/Makefile.am
@@ -0,0 +1,71 @@
+# $Id: Makefile.am,v 1.19 2000/01/06 15:14:27 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4) $(AFS_EXTRA_DEFS)
+
+if KRB4
+AFSLIBS = libkafs.la
+
+if AIX
+AFSL_EXP = $(srcdir)/afsl.exp
+
+if AIX4
+AFS_EXTRA_LD = -bnoentry
+else
+AFS_EXTRA_LD = -e _nostart
+endif
+
+if AIX_DYNAMIC_AFS
+if HAVE_DLOPEN
+AIX_SRC =
+else
+AIX_SRC = dlfcn.c
+endif
+AFS_EXTRA_LIBS = afslib.so
+AFS_EXTRA_DEFS =
+else
+AIX_SRC = afslib.c
+AFS_EXTRA_LIBS =
+AFS_EXTRA_DEFS = -DSTATIC_AFS
+endif
+
+else
+AFSL_EXP =
+AIX_SRC =
+endif # AIX
+
+else
+AFSLIBS =
+endif # KRB4
+
+
+lib_LTLIBRARIES = $(AFSLIBS)
+libkafs_la_LDFLAGS = -version-info 1:2:1
+foodir = $(libdir)
+foo_DATA = $(AFS_EXTRA_LIBS)
+# EXTRA_DATA = afslib.so
+
+CLEANFILES= $(AFS_EXTRA_LIBS)
+
+include_HEADERS = kafs.h
+
+if KRB5
+afskrb5_c = afskrb5.c
+endif
+
+libkafs_la_SOURCES = afssys.c afskrb.c $(afskrb5_c) common.c $(AIX_SRC) kafs_locl.h afssysdefs.h
+#afslib_so_SOURCES = afslib.c
+
+EXTRA_libkafs_la_SOURCES = afskrb5.c dlfcn.c afslib.c dlfcn.h
+
+EXTRA_DIST = README.dlfcn afsl.exp afslib.exp
+
+man_MANS = kafs.3
+
+# AIX: this almost works with gcc, but somehow it fails to use the
+# correct ld, use ld instead
+afslib.so: afslib.o
+ ld -o $@ -bM:SRE -bI:$(srcdir)/afsl.exp -bE:$(srcdir)/afslib.exp $(AFS_EXTRA_LD) afslib.o -lc
+
+$(OBJECTS): ../../include/config.h
diff --git a/crypto/heimdal/lib/kafs/Makefile.in b/crypto/heimdal/lib/kafs/Makefile.in
new file mode 100644
index 000000000000..32b69cb76a83
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/Makefile.in
@@ -0,0 +1,898 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.19 2000/01/06 15:14:27 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4) $(AFS_EXTRA_DEFS)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+@KRB4_TRUE@AFSLIBS = libkafs.la
+@KRB4_FALSE@AFSLIBS =
+
+@KRB4_TRUE@@AIX_TRUE@AFSL_EXP = $(srcdir)/afsl.exp
+@KRB4_TRUE@@AIX_FALSE@AFSL_EXP =
+@KRB4_TRUE@@AIX_TRUE@@AIX4_TRUE@AFS_EXTRA_LD = -bnoentry
+@KRB4_TRUE@@AIX_TRUE@@AIX4_FALSE@AFS_EXTRA_LD = -e _nostart
+@KRB4_TRUE@@AIX_TRUE@@AIX_DYNAMIC_AFS_TRUE@@HAVE_DLOPEN_TRUE@AIX_SRC =
+@KRB4_TRUE@@AIX_TRUE@@AIX_DYNAMIC_AFS_TRUE@@HAVE_DLOPEN_FALSE@AIX_SRC = dlfcn.c
+@KRB4_TRUE@@AIX_TRUE@@AIX_DYNAMIC_AFS_FALSE@AIX_SRC = afslib.c
+@KRB4_TRUE@@AIX_FALSE@AIX_SRC =
+@KRB4_TRUE@@AIX_TRUE@@AIX_DYNAMIC_AFS_TRUE@AFS_EXTRA_LIBS = afslib.so
+@KRB4_TRUE@@AIX_TRUE@@AIX_DYNAMIC_AFS_FALSE@AFS_EXTRA_LIBS =
+@KRB4_TRUE@@AIX_TRUE@@AIX_DYNAMIC_AFS_TRUE@AFS_EXTRA_DEFS =
+@KRB4_TRUE@@AIX_TRUE@@AIX_DYNAMIC_AFS_FALSE@AFS_EXTRA_DEFS = -DSTATIC_AFS
+
+lib_LTLIBRARIES = $(AFSLIBS)
+libkafs_la_LDFLAGS = -version-info 1:2:1
+foodir = $(libdir)
+foo_DATA = $(AFS_EXTRA_LIBS)
+# EXTRA_DATA = afslib.so
+
+CLEANFILES = $(AFS_EXTRA_LIBS)
+
+include_HEADERS = kafs.h
+
+@KRB5_TRUE@afskrb5_c = afskrb5.c
+
+libkafs_la_SOURCES = afssys.c afskrb.c $(afskrb5_c) common.c $(AIX_SRC) kafs_locl.h afssysdefs.h
+#afslib_so_SOURCES = afslib.c
+
+EXTRA_libkafs_la_SOURCES = afskrb5.c dlfcn.c afslib.c dlfcn.h
+
+EXTRA_DIST = README.dlfcn afsl.exp afslib.exp
+
+man_MANS = kafs.3
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libkafs_la_LIBADD =
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb5.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb5.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb5.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb5.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb5.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb5.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb5.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb5.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb5.lo \
+@AIX_FALSE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb5.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@common.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afslib.lo
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb5.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@common.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@dlfcn.lo
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb5.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb5.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@common.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afslib.lo
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@common.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@dlfcn.lo
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@afskrb5.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afssys.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@afskrb.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_TRUE@common.lo
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb5.lo \
+@AIX_TRUE@@KRB4_FALSE@@KRB5_TRUE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@common.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_FALSE@@HAVE_DLOPEN_TRUE@@AIX_DYNAMIC_AFS_FALSE@afslib.lo
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb5.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@common.lo \
+@AIX_TRUE@@KRB4_TRUE@@KRB5_TRUE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afslib.lo
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@libkafs_la_OBJECTS = \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afssys.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@afskrb.lo \
+@AIX_FALSE@@KRB4_FALSE@@KRB5_FALSE@@HAVE_DLOPEN_FALSE@@AIX_DYNAMIC_AFS_FALSE@common.lo
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man3dir = $(mandir)/man3
+MANS = $(man_MANS)
+DATA = $(foo_DATA)
+
+HEADERS = $(include_HEADERS)
+
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libkafs_la_SOURCES) $(EXTRA_libkafs_la_SOURCES)
+OBJECTS = $(libkafs_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/kafs/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libkafs.la: $(libkafs_la_OBJECTS) $(libkafs_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libkafs_la_LDFLAGS) $(libkafs_la_OBJECTS) $(libkafs_la_LIBADD) $(LIBS)
+
+install-man3:
+ $(mkinstalldirs) $(DESTDIR)$(man3dir)
+ @list='$(man3_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst; \
+ done
+
+uninstall-man3:
+ @list='$(man3_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man3dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man3dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man3
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man3
+
+install-fooDATA: $(foo_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(foodir)
+ @list='$(foo_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(foodir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(foodir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(foodir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(foodir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-fooDATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(foo_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(foodir)/$$p; \
+ done
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/kafs
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-man install-fooDATA install-includeHEADERS \
+ install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-man uninstall-fooDATA \
+ uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(mandir)/man3 \
+ $(DESTDIR)$(foodir) $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool install-man3 uninstall-man3 install-man \
+uninstall-man uninstall-fooDATA install-fooDATA \
+uninstall-includeHEADERS install-includeHEADERS tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check-local check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-local \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# AIX: this almost works with gcc, but somehow it fails to use the
+# correct ld, use ld instead
+afslib.so: afslib.o
+ ld -o $@ -bM:SRE -bI:$(srcdir)/afsl.exp -bE:$(srcdir)/afslib.exp $(AFS_EXTRA_LD) afslib.o -lc
+
+$(OBJECTS): ../../include/config.h
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/kafs/README.dlfcn b/crypto/heimdal/lib/kafs/README.dlfcn
new file mode 100644
index 000000000000..cee1b751939e
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/README.dlfcn
@@ -0,0 +1,246 @@
+Copyright (c) 1992,1993,1995,1996, Jens-Uwe Mager, Helios Software GmbH
+Not derived from licensed software.
+
+Permission is granted to freely use, copy, modify, and redistribute
+this software, provided that the author is not construed to be liable
+for any results of using the software, alterations are clearly marked
+as such, and this notice is not modified.
+
+libdl.a
+-------
+
+This is an emulation library to emulate the SunOS/System V.4 functions
+to access the runtime linker. The functions are emulated by using the
+AIX load() function and by reading the .loader section of the loaded
+module to find the exports. The to be loaded module should be linked as
+follows (if using AIX 3):
+
+ cc -o module.so -bM:SRE -bE:module.exp -e _nostart $(OBJS)
+
+For AIX 4:
+
+ cc -o module.so -bM:SRE -bE:module.exp -bnoentry $(OBJS)
+
+If you want to reference symbols from the main part of the program in a
+loaded module, you will have to link against the export file of the
+main part:
+
+ cc -o main -bE:main.exp $(MAIN_OBJS)
+ cc -o module.so -bM:SRE -bI:main.exp -bE:module.exp -bnoentry $(OBJS)
+
+Note that you explicitely have to specify what functions are supposed
+to be accessible from your loaded modules, this is different from
+SunOS/System V.4 where any global is automatically exported. If you
+want to export all globals, the following script might be of help:
+
+#!/bin/sh
+/usr/ucb/nm -g $* | awk '$2 == "B" || $2 == "D" { print $3 }'
+
+The module export file contains the symbols to be exported. Because
+this library uses the loader section, the final module.so file can be
+stripped. C++ users should build their shared objects using the script
+makeC++SharedLib (part of the IBM C++ compiler), this will make sure
+that constructors and destructors for static and global objects will be
+called upon loading and unloading the module. GNU C++ users should use
+the -shared option to g++ to link the shared object:
+
+ g++ -o module.so -shared $(OBJS)
+
+If the shared object does have permissions for anybody, the shared
+object will be loaded into the shared library segment and it will stay
+there even if the main application terminates. If you rebuild your
+shared object after a bugfix and you want to make sure that you really
+get the newest version you will have to use the "slibclean" command
+before starting the application again to garbage collect the shared
+library segment. If the performance utilities (bosperf) are installed
+you can use the following command to see what shared objects are
+loaded:
+
+/usr/lpp/bosperf/genkld | sort | uniq
+
+For easier debugging you can avoid loading the shared object into the
+shared library segment alltogether by removing permissions for others
+from the module.so file:
+
+chmod o-rwx module.so
+
+This will ensure you get a fresh copy of the shared object for every
+dlopen() call which is loaded into the application's data segment.
+
+Usage
+-----
+
+void *dlopen(const char *path, int mode);
+
+This routine loads the module pointed to by path and reads its export
+table. If the path does not contain a '/' character, dlopen will search
+for the module using the LIBPATH environment variable. It returns an
+opaque handle to the module or NULL on error. The mode parameter can be
+either RTLD_LAZY (for lazy function binding) or RTLD_NOW for immediate
+function binding. The AIX implementation currently does treat RTLD_NOW
+the same as RTLD_LAZY. The flag RTLD_GLOBAL might be or'ed into the
+mode parameter to allow loaded modules to bind to global variables or
+functions in other loaded modules loaded by dlopen(). If RTLD_GLOBAL is
+not specified, only globals from the main part of the executable or
+shared libraries are used to look for undefined symbols in loaded
+modules.
+
+
+void *dlsym(void *handle, const char *symbol);
+
+This routine searches for the symbol in the module referred to by
+handle and returns its address. If the symbol could not be found, the
+function returns NULL. The return value must be casted to a proper
+function pointer before it can be used. SunOS/System V.4 allows handle
+to be a NULL pointer to refer to the module the call is made from, this
+is not implemented.
+
+int dlclose(void *handle);
+
+This routine unloads the module referred to by the handle and disposes
+of any local storage. this function returns -1 on failure. Any function
+pointers obtained through dlsym() should be considered invalid after
+closing a module.
+
+As AIX caches shared objects in the shared library segment, function
+pointers obtained through dlsym() might still work even though the
+module has been unloaded. This can introduce subtle bugs that will
+segment fault later if AIX garbage collects or immediatly on
+SunOS/System V.4 as the text segment is unmapped.
+
+char *dlerror(void);
+
+This routine can be used to retrieve a text message describing the most
+recent error that occured on on of the above routines. This function
+returns NULL if there is no error information.
+
+Initialization and termination handlers
+---------------------------------------
+
+The emulation provides for an initialization and a termination
+handler. The dlfcn.h file contains a structure declaration named
+dl_info with following members:
+
+ void (*init)(void);
+ void (*fini)(void);
+
+The init function is called upon first referencing the library. The
+fini function is called at dlclose() time or when the process exits.
+The module should declare a variable named dl_info that contains this
+structure which must be exported. These functions correspond to the
+documented _init() and _fini() functions of SunOS 4.x, but these are
+appearently not implemented in SunOS. When using SunOS 5.0, these
+correspond to #pragma init and #pragma fini respectively. At the same
+time any static or global C++ object's constructors or destructors will
+be called.
+
+BUGS
+----
+
+Please note that there is currently a problem with implicitely loaded
+shared C++ libaries: if you refer to a shared C++ library from a loaded
+module that is not yet used by the main program, the dlopen() emulator
+does not notice this and does not call the static constructors for the
+implicitely loaded library. This can be easily demonstrated by
+referencing the C++ standard streams from a loaded module if the main
+program is a plain C program.
+
+Jens-Uwe Mager
+
+HELIOS Software GmbH
+Lavesstr. 80
+30159 Hannover
+Germany
+
+Phone: +49 511 36482-0
+FAX: +49 511 36482-69
+AppleLink: helios.de/jum
+Internet: jum@helios.de
+
+Revison History
+---------------
+
+SCCS/s.dlfcn.h:
+
+D 1.4 95/04/25 09:36:52 jum 4 3 00018/00004/00028
+MRs:
+COMMENTS:
+added RTLD_GLOBAL, include and C++ guards
+
+D 1.3 92/12/27 20:58:32 jum 3 2 00001/00001/00031
+MRs:
+COMMENTS:
+we always have prototypes on RS/6000
+
+D 1.2 92/08/16 17:45:11 jum 2 1 00009/00000/00023
+MRs:
+COMMENTS:
+added dl_info structure to implement initialize and terminate functions
+
+D 1.1 92/08/02 18:08:45 jum 1 0 00023/00000/00000
+MRs:
+COMMENTS:
+Erstellungsdatum und -uhrzeit 92/08/02 18:08:45 von jum
+
+SCCS/s.dlfcn.c:
+
+D 1.11 96/04/10 20:12:51 jum 13 12 00037/00000/00533
+MRs:
+COMMENTS:
+Integrated the changes from John W. Eaton <jwe@bevo.che.wisc.edu> to initialize
+g++ generated shared objects.
+
+D 1.10 96/02/15 17:42:44 jum 12 10 00012/00007/00521
+MRs:
+COMMENTS:
+the C++ constructor and destructor chains are now called properly for either
+xlC 2 or xlC 3 (CSet++).
+
+D 1.9 95/09/22 11:09:38 markus 10 9 00001/00008/00527
+MRs:
+COMMENTS:
+Fix version number
+
+D 1.8 95/09/22 10:14:34 markus 9 8 00008/00001/00527
+MRs:
+COMMENTS:
+Added version number for dl lib
+
+D 1.7 95/08/14 19:08:38 jum 8 6 00026/00004/00502
+MRs:
+COMMENTS:
+Integrated the fixes from Kirk Benell (kirk@rsinc.com) to allow loading of
+shared objects generated under AIX 4. Fixed bug that symbols with exactly
+8 characters would use garbage characters from the following symbol value.
+
+D 1.6 95/04/25 09:38:03 jum 6 5 00046/00006/00460
+MRs:
+COMMENTS:
+added handling of C++ static constructors and destructors, added RTLD_GLOBAL to bind against other loaded modules
+
+D 1.5 93/02/14 20:14:17 jum 5 4 00002/00000/00464
+MRs:
+COMMENTS:
+added path to dlopen error message to make clear where there error occured.
+
+D 1.4 93/01/03 19:13:56 jum 4 3 00061/00005/00403
+MRs:
+COMMENTS:
+to allow calling symbols in the main module call load with L_NOAUTODEFER and
+do a loadbind later with the main module.
+
+D 1.3 92/12/27 20:59:55 jum 3 2 00066/00008/00342
+MRs:
+COMMENTS:
+added search by L_GETINFO if module got loaded by LIBPATH
+
+D 1.2 92/08/16 17:45:43 jum 2 1 00074/00006/00276
+MRs:
+COMMENTS:
+implemented initialize and terminate functions, added reference counting to avoid multiple loads of the same library
+
+D 1.1 92/08/02 18:08:45 jum 1 0 00282/00000/00000
+MRs:
+COMMENTS:
+Erstellungsdatum und -uhrzeit 92/08/02 18:08:45 von jum
+
diff --git a/crypto/heimdal/lib/kafs/afskrb.c b/crypto/heimdal/lib/kafs/afskrb.c
new file mode 100644
index 000000000000..805750dad605
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/afskrb.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kafs_locl.h"
+
+RCSID("$Id: afskrb.c,v 1.13 1999/12/02 16:58:39 joda Exp $");
+
+struct krb_kafs_data {
+ const char *realm;
+};
+
+static int
+get_cred(kafs_data *data, const char *name, const char *inst,
+ const char *realm, CREDENTIALS *c)
+{
+ KTEXT_ST tkt;
+ int ret = krb_get_cred((char*)name, (char*)inst, (char*)realm, c);
+
+ if (ret) {
+ ret = krb_mk_req(&tkt, (char*)name, (char*)inst, (char*)realm, 0);
+ if (ret == KSUCCESS)
+ ret = krb_get_cred((char*)name, (char*)inst, (char*)realm, c);
+ }
+ return ret;
+}
+
+static int
+afslog_uid_int(kafs_data *data,
+ const char *cell,
+ const char *realm_hint,
+ uid_t uid,
+ const char *homedir)
+{
+ int ret;
+ CREDENTIALS c;
+ char realm[REALM_SZ];
+
+ if (cell == 0 || cell[0] == 0)
+ return _kafs_afslog_all_local_cells (data, uid, homedir);
+
+ /* Extract realm from ticket file. */
+ {
+ char name[ANAME_SZ], inst[INST_SZ];
+
+ ret = krb_get_default_principal(name, inst, realm);
+ if (ret != KSUCCESS)
+ return ret;
+ }
+
+ ret = _kafs_get_cred(data, cell, realm_hint, realm, &c);
+
+ if (ret == 0)
+ ret = kafs_settoken(cell, uid, &c);
+ return ret;
+}
+
+static char *
+get_realm(kafs_data *data, const char *host)
+{
+ char *r = krb_realmofhost(host);
+ if(r != NULL)
+ return strdup(r);
+ else
+ return NULL;
+}
+
+int
+krb_afslog_uid_home(const char *cell, const char *realm_hint, uid_t uid,
+ const char *homedir)
+{
+ kafs_data kd;
+
+ kd.afslog_uid = afslog_uid_int;
+ kd.get_cred = get_cred;
+ kd.get_realm = get_realm;
+ kd.data = 0;
+ return afslog_uid_int(&kd, cell, realm_hint, uid, homedir);
+}
+
+int
+krb_afslog_uid(const char *cell, const char *realm_hint, uid_t uid)
+{
+ return krb_afslog_uid_home(cell, realm_hint, uid, NULL);
+}
+
+int
+krb_afslog(const char *cell, const char *realm_hint)
+{
+ return krb_afslog_uid(cell, realm_hint, getuid());
+}
+
+int
+krb_afslog_home(const char *cell, const char *realm_hint, const char *homedir)
+{
+ return krb_afslog_uid_home(cell, realm_hint, getuid(), homedir);
+}
+
+/*
+ *
+ */
+
+int
+krb_realm_of_cell(const char *cell, char **realm)
+{
+ kafs_data kd;
+
+ kd.get_realm = get_realm;
+ return _kafs_realm_of_cell(&kd, cell, realm);
+}
diff --git a/crypto/heimdal/lib/kafs/afskrb5.c b/crypto/heimdal/lib/kafs/afskrb5.c
new file mode 100644
index 000000000000..4c35ea7382f2
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/afskrb5.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kafs_locl.h"
+
+RCSID("$Id: afskrb5.c,v 1.13 1999/12/02 16:58:39 joda Exp $");
+
+struct krb5_kafs_data {
+ krb5_context context;
+ krb5_ccache id;
+ krb5_const_realm realm;
+};
+
+static int
+get_cred(kafs_data *data, const char *name, const char *inst,
+ const char *realm, CREDENTIALS *c)
+{
+ krb5_error_code ret;
+ krb5_creds in_creds, *out_creds;
+ struct krb5_kafs_data *d = data->data;
+
+ memset(&in_creds, 0, sizeof(in_creds));
+ ret = krb5_425_conv_principal(d->context, name, inst, realm,
+ &in_creds.server);
+ if(ret)
+ return ret;
+ ret = krb5_cc_get_principal(d->context, d->id, &in_creds.client);
+ if(ret){
+ krb5_free_principal(d->context, in_creds.server);
+ return ret;
+ }
+ in_creds.session.keytype = KEYTYPE_DES;
+ ret = krb5_get_credentials(d->context, 0, d->id, &in_creds, &out_creds);
+ krb5_free_principal(d->context, in_creds.server);
+ krb5_free_principal(d->context, in_creds.client);
+ if(ret)
+ return ret;
+ ret = krb524_convert_creds_kdc(d->context, d->id, out_creds, c);
+ krb5_free_creds(d->context, out_creds);
+ return ret;
+}
+
+static krb5_error_code
+afslog_uid_int(kafs_data *data, const char *cell, const char *rh, uid_t uid,
+ const char *homedir)
+{
+ krb5_error_code ret;
+ CREDENTIALS c;
+ krb5_principal princ;
+ krb5_realm *trealm; /* ticket realm */
+ struct krb5_kafs_data *d = data->data;
+
+ if (cell == 0 || cell[0] == 0)
+ return _kafs_afslog_all_local_cells (data, uid, homedir);
+
+ ret = krb5_cc_get_principal (d->context, d->id, &princ);
+ if (ret)
+ return ret;
+
+ trealm = krb5_princ_realm (d->context, princ);
+
+ if (d->realm != NULL && strcmp (d->realm, *trealm) == 0) {
+ trealm = NULL;
+ krb5_free_principal (d->context, princ);
+ }
+
+ ret = _kafs_get_cred(data, cell, d->realm, *trealm, &c);
+ if(trealm)
+ krb5_free_principal (d->context, princ);
+
+ if(ret == 0)
+ ret = kafs_settoken(cell, uid, &c);
+ return ret;
+}
+
+static char *
+get_realm(kafs_data *data, const char *host)
+{
+ struct krb5_kafs_data *d = data->data;
+ krb5_realm *realms;
+ char *r;
+ if(krb5_get_host_realm(d->context, host, &realms))
+ return NULL;
+ r = strdup(realms[0]);
+ krb5_free_host_realm(d->context, realms);
+ return r;
+}
+
+krb5_error_code
+krb5_afslog_uid_home(krb5_context context,
+ krb5_ccache id,
+ const char *cell,
+ krb5_const_realm realm,
+ uid_t uid,
+ const char *homedir)
+{
+ kafs_data kd;
+ struct krb5_kafs_data d;
+ kd.afslog_uid = afslog_uid_int;
+ kd.get_cred = get_cred;
+ kd.get_realm = get_realm;
+ kd.data = &d;
+ d.context = context;
+ d.id = id;
+ d.realm = realm;
+ return afslog_uid_int(&kd, cell, 0, uid, homedir);
+}
+
+krb5_error_code
+krb5_afslog_uid(krb5_context context,
+ krb5_ccache id,
+ const char *cell,
+ krb5_const_realm realm,
+ uid_t uid)
+{
+ return krb5_afslog_uid_home (context, id, cell, realm, uid, NULL);
+}
+
+krb5_error_code
+krb5_afslog(krb5_context context,
+ krb5_ccache id,
+ const char *cell,
+ krb5_const_realm realm)
+{
+ return krb5_afslog_uid (context, id, cell, realm, getuid());
+}
+
+krb5_error_code
+krb5_afslog_home(krb5_context context,
+ krb5_ccache id,
+ const char *cell,
+ krb5_const_realm realm,
+ const char *homedir)
+{
+ return krb5_afslog_uid_home (context, id, cell, realm, getuid(), homedir);
+}
+
+/*
+ *
+ */
+
+krb5_error_code
+krb5_realm_of_cell(const char *cell, char **realm)
+{
+ kafs_data kd;
+
+ kd.get_realm = get_realm;
+ return _kafs_realm_of_cell(&kd, cell, realm);
+}
diff --git a/crypto/heimdal/lib/kafs/afsl.exp b/crypto/heimdal/lib/kafs/afsl.exp
new file mode 100644
index 000000000000..4d2b00e28337
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/afsl.exp
@@ -0,0 +1,6 @@
+#!/unix
+
+* This mumbo jumbo creates entry points to syscalls in _AIX
+
+lpioctl syscall
+lsetpag syscall
diff --git a/crypto/heimdal/lib/kafs/afslib.c b/crypto/heimdal/lib/kafs/afslib.c
new file mode 100644
index 000000000000..ae3b5a5692d7
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/afslib.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*
+ * This file is only used with AIX
+ */
+
+#include "kafs_locl.h"
+
+RCSID("$Id: afslib.c,v 1.6 1999/12/02 16:58:40 joda Exp $");
+
+int
+aix_pioctl(char *a_path,
+ int o_opcode,
+ struct ViceIoctl *a_paramsP,
+ int a_followSymlinks)
+{
+ return lpioctl(a_path, o_opcode, a_paramsP, a_followSymlinks);
+}
+
+int
+aix_setpag(void)
+{
+ return lsetpag();
+}
diff --git a/crypto/heimdal/lib/kafs/afslib.exp b/crypto/heimdal/lib/kafs/afslib.exp
new file mode 100644
index 000000000000..f288717706ea
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/afslib.exp
@@ -0,0 +1,3 @@
+#!
+aix_pioctl
+aix_setpag
diff --git a/crypto/heimdal/lib/kafs/afssys.c b/crypto/heimdal/lib/kafs/afssys.c
new file mode 100644
index 000000000000..d49a65ac6c84
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/afssys.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kafs_locl.h"
+
+RCSID("$Id: afssys.c,v 1.65 1999/12/02 16:58:40 joda Exp $");
+
+int _kafs_debug; /* this should be done in a better way */
+
+#define NO_ENTRY_POINT 0
+#define SINGLE_ENTRY_POINT 1
+#define MULTIPLE_ENTRY_POINT 2
+#define SINGLE_ENTRY_POINT2 3
+#define SINGLE_ENTRY_POINT3 4
+#define AIX_ENTRY_POINTS 5
+#define UNKNOWN_ENTRY_POINT 6
+static int afs_entry_point = UNKNOWN_ENTRY_POINT;
+static int afs_syscalls[2];
+
+/* Magic to get AIX syscalls to work */
+#ifdef _AIX
+
+static int (*Pioctl)(char*, int, struct ViceIoctl*, int);
+static int (*Setpag)(void);
+
+#include "dlfcn.h"
+
+/*
+ *
+ */
+
+static int
+try_aix(void)
+{
+#ifdef STATIC_AFS_SYSCALLS
+ Pioctl = aix_pioctl;
+ Setpag = aix_setpag;
+#else
+ void *ptr;
+ char path[MaxPathLen], *p;
+ /*
+ * If we are root or running setuid don't trust AFSLIBPATH!
+ */
+ if (getuid() != 0 && !issuid() && (p = getenv("AFSLIBPATH")) != NULL)
+ strlcpy(path, p, sizeof(path));
+ else
+ snprintf(path, sizeof(path), "%s/afslib.so", LIBDIR);
+
+ ptr = dlopen(path, RTLD_NOW);
+ if(ptr == NULL) {
+ if(_kafs_debug) {
+ if(errno == ENOEXEC && (p = dlerror()) != NULL)
+ fprintf(stderr, "dlopen(%s): %s\n", path, p);
+ else if (errno != ENOENT)
+ fprintf(stderr, "dlopen(%s): %s\n", path, strerror(errno));
+ }
+ return 1;
+ }
+ Setpag = (int (*)(void))dlsym(ptr, "aix_setpag");
+ Pioctl = (int (*)(char*, int,
+ struct ViceIoctl*, int))dlsym(ptr, "aix_pioctl");
+#endif
+ afs_entry_point = AIX_ENTRY_POINTS;
+ return 0;
+}
+#endif /* _AIX */
+
+/*
+ * This probably only works under Solaris and could get confused if
+ * there's a /etc/name_to_sysnum file.
+ */
+
+#define _PATH_ETC_NAME_TO_SYSNUM "/etc/name_to_sysnum"
+
+static int
+map_syscall_name_to_number (const char *str, int *res)
+{
+ FILE *f;
+ char buf[256];
+ size_t str_len = strlen (str);
+
+ f = fopen (_PATH_ETC_NAME_TO_SYSNUM, "r");
+ if (f == NULL)
+ return -1;
+ while (fgets (buf, sizeof(buf), f) != NULL) {
+ if (strncmp (str, buf, str_len) == 0) {
+ char *begptr = buf + str_len;
+ char *endptr;
+ long val = strtol (begptr, &endptr, 0);
+
+ if (val != 0 && endptr != begptr) {
+ fclose (f);
+ *res = val;
+ return 0;
+ }
+ }
+ }
+ fclose (f);
+ return -1;
+}
+
+int
+k_pioctl(char *a_path,
+ int o_opcode,
+ struct ViceIoctl *a_paramsP,
+ int a_followSymlinks)
+{
+#ifndef NO_AFS
+ switch(afs_entry_point){
+#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
+ case SINGLE_ENTRY_POINT:
+ case SINGLE_ENTRY_POINT2:
+ case SINGLE_ENTRY_POINT3:
+ return syscall(afs_syscalls[0], AFSCALL_PIOCTL,
+ a_path, o_opcode, a_paramsP, a_followSymlinks);
+#endif
+#if defined(AFS_PIOCTL)
+ case MULTIPLE_ENTRY_POINT:
+ return syscall(afs_syscalls[0],
+ a_path, o_opcode, a_paramsP, a_followSymlinks);
+#endif
+#ifdef _AIX
+ case AIX_ENTRY_POINTS:
+ return Pioctl(a_path, o_opcode, a_paramsP, a_followSymlinks);
+#endif
+ }
+
+ errno = ENOSYS;
+#ifdef SIGSYS
+ kill(getpid(), SIGSYS); /* You loose! */
+#endif
+#endif /* NO_AFS */
+ return -1;
+}
+
+int
+k_afs_cell_of_file(const char *path, char *cell, int len)
+{
+ struct ViceIoctl parms;
+ parms.in = NULL;
+ parms.in_size = 0;
+ parms.out = cell;
+ parms.out_size = len;
+ return k_pioctl((char*)path, VIOC_FILE_CELL_NAME, &parms, 1);
+}
+
+int
+k_unlog(void)
+{
+ struct ViceIoctl parms;
+ memset(&parms, 0, sizeof(parms));
+ return k_pioctl(0, VIOCUNLOG, &parms, 0);
+}
+
+int
+k_setpag(void)
+{
+#ifndef NO_AFS
+ switch(afs_entry_point){
+#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
+ case SINGLE_ENTRY_POINT:
+ case SINGLE_ENTRY_POINT2:
+ case SINGLE_ENTRY_POINT3:
+ return syscall(afs_syscalls[0], AFSCALL_SETPAG);
+#endif
+#if defined(AFS_PIOCTL)
+ case MULTIPLE_ENTRY_POINT:
+ return syscall(afs_syscalls[1]);
+#endif
+#ifdef _AIX
+ case AIX_ENTRY_POINTS:
+ return Setpag();
+#endif
+ }
+
+ errno = ENOSYS;
+#ifdef SIGSYS
+ kill(getpid(), SIGSYS); /* You loose! */
+#endif
+#endif /* NO_AFS */
+ return -1;
+}
+
+static jmp_buf catch_SIGSYS;
+
+#ifdef SIGSYS
+
+static RETSIGTYPE
+SIGSYS_handler(int sig)
+{
+ errno = 0;
+ signal(SIGSYS, SIGSYS_handler); /* Need to reinstall handler on SYSV */
+ longjmp(catch_SIGSYS, 1);
+}
+
+#endif
+
+/*
+ * Try to see if `syscall' is a pioctl. Return 0 iff succesful.
+ */
+
+#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
+static int
+try_one (int syscall_num)
+{
+ struct ViceIoctl parms;
+ memset(&parms, 0, sizeof(parms));
+
+ if (setjmp(catch_SIGSYS) == 0) {
+ syscall(syscall_num, AFSCALL_PIOCTL,
+ 0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ if (errno == EINVAL) {
+ afs_entry_point = SINGLE_ENTRY_POINT;
+ afs_syscalls[0] = syscall_num;
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif
+
+/*
+ * Try to see if `syscall_pioctl' is a pioctl syscall. Return 0 iff
+ * succesful.
+ *
+ */
+
+#ifdef AFS_PIOCTL
+static int
+try_two (int syscall_pioctl, int syscall_setpag)
+{
+ struct ViceIoctl parms;
+ memset(&parms, 0, sizeof(parms));
+
+ if (setjmp(catch_SIGSYS) == 0) {
+ syscall(syscall_pioctl,
+ 0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ if (errno == EINVAL) {
+ afs_entry_point = MULTIPLE_ENTRY_POINT;
+ afs_syscalls[0] = syscall_pioctl;
+ afs_syscalls[1] = syscall_setpag;
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif
+
+int
+k_hasafs(void)
+{
+#if !defined(NO_AFS) && defined(SIGSYS)
+ RETSIGTYPE (*saved_func)();
+#endif
+ int saved_errno;
+ char *env = getenv ("AFS_SYSCALL");
+
+ /*
+ * Already checked presence of AFS syscalls?
+ */
+ if (afs_entry_point != UNKNOWN_ENTRY_POINT)
+ return afs_entry_point != NO_ENTRY_POINT;
+
+ /*
+ * Probe kernel for AFS specific syscalls,
+ * they (currently) come in two flavors.
+ * If the syscall is absent we recive a SIGSYS.
+ */
+ afs_entry_point = NO_ENTRY_POINT;
+
+ saved_errno = errno;
+#ifndef NO_AFS
+#ifdef SIGSYS
+ saved_func = signal(SIGSYS, SIGSYS_handler);
+#endif
+
+#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
+ {
+ int tmp;
+
+ if (env != NULL) {
+ if (sscanf (env, "%d", &tmp) == 1) {
+ if (try_one (tmp) == 0)
+ goto done;
+ } else {
+ char *end = NULL;
+ char *p;
+ char *s = strdup (env);
+
+ if (s != NULL) {
+ for (p = strtok_r (s, ",", &end);
+ p != NULL;
+ p = strtok_r (NULL, ",", &end)) {
+ if (map_syscall_name_to_number (p, &tmp) == 0)
+ if (try_one (tmp) == 0) {
+ free (s);
+ goto done;
+ }
+ }
+ free (s);
+ }
+ }
+ }
+ }
+#endif /* AFS_SYSCALL || AFS_SYSCALL2 || AFS_SYSCALL3 */
+
+#ifdef AFS_SYSCALL
+ if (try_one (AFS_SYSCALL) == 0)
+ goto done;
+#endif /* AFS_SYSCALL */
+
+#ifdef AFS_PIOCTL
+ {
+ int tmp[2];
+
+ if (env != NULL && sscanf (env, "%d%d", &tmp[0], &tmp[1]) == 2)
+ if (try_two (tmp[0], tmp[1]) == 2)
+ goto done;
+ }
+#endif /* AFS_PIOCTL */
+
+#ifdef AFS_PIOCTL
+ if (try_two (AFS_PIOCTL, AFS_SETPAG) == 0)
+ goto done;
+#endif /* AFS_PIOCTL */
+
+#ifdef AFS_SYSCALL2
+ if (try_one (AFS_SYSCALL2) == 0)
+ goto done;
+#endif /* AFS_SYSCALL2 */
+
+#ifdef AFS_SYSCALL3
+ if (try_one (AFS_SYSCALL3) == 0)
+ goto done;
+#endif /* AFS_SYSCALL3 */
+
+#ifdef _AIX
+#if 0
+ if (env != NULL) {
+ char *pos = NULL;
+ char *pioctl_name;
+ char *setpag_name;
+
+ pioctl_name = strtok_r (env, ", \t", &pos);
+ if (pioctl_name != NULL) {
+ setpag_name = strtok_r (NULL, ", \t", &pos);
+ if (setpag_name != NULL)
+ if (try_aix (pioctl_name, setpag_name) == 0)
+ goto done;
+ }
+ }
+#endif
+
+ if(try_aix() == 0)
+ goto done;
+#endif
+
+done:
+#ifdef SIGSYS
+ signal(SIGSYS, saved_func);
+#endif
+#endif /* NO_AFS */
+ errno = saved_errno;
+ return afs_entry_point != NO_ENTRY_POINT;
+}
diff --git a/crypto/heimdal/lib/kafs/afssysdefs.h b/crypto/heimdal/lib/kafs/afssysdefs.h
new file mode 100644
index 000000000000..574b33f70af6
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/afssysdefs.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: afssysdefs.h,v 1.21 1999/12/02 16:58:40 joda Exp $ */
+
+/*
+ * This section is for machines using single entry point AFS syscalls!
+ * and/or
+ * This section is for machines using multiple entry point AFS syscalls!
+ *
+ * SunOS 4 is an example of single entry point and sgi of multiple
+ * entry point syscalls.
+ */
+
+#if SunOS == 40
+#define AFS_SYSCALL 31
+#endif
+
+#if SunOS >= 50 && SunOS < 57
+#define AFS_SYSCALL 105
+#endif
+
+#if SunOS == 57
+#define AFS_SYSCALL 73
+#endif
+
+#if defined(__hpux)
+#define AFS_SYSCALL 50
+#define AFS_SYSCALL2 49
+#define AFS_SYSCALL3 48
+#endif
+
+#if defined(_AIX)
+/* _AIX is too weird */
+#endif
+
+#if defined(__sgi)
+#define AFS_PIOCTL (64+1000)
+#define AFS_SETPAG (65+1000)
+#endif
+
+#if defined(__osf__)
+#define AFS_SYSCALL 232
+#define AFS_SYSCALL2 258
+#endif
+
+#if defined(__ultrix)
+#define AFS_SYSCALL 31
+#endif
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#define AFS_SYSCALL 210
+#endif
+
+#ifdef SYS_afs_syscall
+#define AFS_SYSCALL3 SYS_afs_syscall
+#endif
diff --git a/crypto/heimdal/lib/kafs/common.c b/crypto/heimdal/lib/kafs/common.c
new file mode 100644
index 000000000000..207b9b643de7
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/common.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "kafs_locl.h"
+
+RCSID("$Id: common.c,v 1.19 1999/12/02 16:58:40 joda Exp $");
+
+#define AUTH_SUPERUSER "afs"
+
+/*
+ * Here only ASCII characters are relevant.
+ */
+
+#define IsAsciiLower(c) ('a' <= (c) && (c) <= 'z')
+
+#define ToAsciiUpper(c) ((c) - 'a' + 'A')
+
+static void
+foldup(char *a, const char *b)
+{
+ for (; *b; a++, b++)
+ if (IsAsciiLower(*b))
+ *a = ToAsciiUpper(*b);
+ else
+ *a = *b;
+ *a = '\0';
+}
+
+int
+kafs_settoken(const char *cell, uid_t uid, CREDENTIALS *c)
+{
+ struct ViceIoctl parms;
+ struct ClearToken ct;
+ int32_t sizeof_x;
+ char buf[2048], *t;
+ int ret;
+
+ /*
+ * Build a struct ClearToken
+ */
+ ct.AuthHandle = c->kvno;
+ memcpy (ct.HandShakeKey, c->session, sizeof(c->session));
+ ct.ViceId = uid;
+ ct.BeginTimestamp = c->issue_date;
+ ct.EndTimestamp = krb_life_to_time(c->issue_date, c->lifetime);
+ if(ct.EndTimestamp < time(NULL))
+ return 0; /* don't store tokens that has expired (and possibly
+ overwriting valid tokens)*/
+
+#define ODD(x) ((x) & 1)
+ /* According to Transarc conventions ViceId is valid iff
+ * (EndTimestamp - BeginTimestamp) is odd. By decrementing EndTime
+ * the transformations:
+ *
+ * (issue_date, life) -> (StartTime, EndTime) -> (issue_date, life)
+ * preserves the original values.
+ */
+ if (uid != 0) /* valid ViceId */
+ {
+ if (!ODD(ct.EndTimestamp - ct.BeginTimestamp))
+ ct.EndTimestamp--;
+ }
+ else /* not valid ViceId */
+ {
+ if (ODD(ct.EndTimestamp - ct.BeginTimestamp))
+ ct.EndTimestamp--;
+ }
+
+ t = buf;
+ /*
+ * length of secret token followed by secret token
+ */
+ sizeof_x = c->ticket_st.length;
+ memcpy(t, &sizeof_x, sizeof(sizeof_x));
+ t += sizeof(sizeof_x);
+ memcpy(t, c->ticket_st.dat, sizeof_x);
+ t += sizeof_x;
+ /*
+ * length of clear token followed by clear token
+ */
+ sizeof_x = sizeof(ct);
+ memcpy(t, &sizeof_x, sizeof(sizeof_x));
+ t += sizeof(sizeof_x);
+ memcpy(t, &ct, sizeof_x);
+ t += sizeof_x;
+
+ /*
+ * do *not* mark as primary cell
+ */
+ sizeof_x = 0;
+ memcpy(t, &sizeof_x, sizeof(sizeof_x));
+ t += sizeof(sizeof_x);
+ /*
+ * follow with cell name
+ */
+ sizeof_x = strlen(cell) + 1;
+ memcpy(t, cell, sizeof_x);
+ t += sizeof_x;
+
+ /*
+ * Build argument block
+ */
+ parms.in = buf;
+ parms.in_size = t - buf;
+ parms.out = 0;
+ parms.out_size = 0;
+ ret = k_pioctl(0, VIOCSETTOK, &parms, 0);
+ return ret;
+}
+
+/* Try to get a db-server for an AFS cell from a AFSDB record */
+
+static int
+dns_find_cell(const char *cell, char *dbserver, size_t len)
+{
+ struct dns_reply *r;
+ int ok = -1;
+ r = dns_lookup(cell, "afsdb");
+ if(r){
+ struct resource_record *rr = r->head;
+ while(rr){
+ if(rr->type == T_AFSDB && rr->u.afsdb->preference == 1){
+ strlcpy(dbserver,
+ rr->u.afsdb->domain,
+ len);
+ ok = 0;
+ break;
+ }
+ rr = rr->next;
+ }
+ dns_free_data(r);
+ }
+ return ok;
+}
+
+
+/*
+ * Try to find the cells we should try to klog to in "file".
+ */
+static void
+find_cells(char *file, char ***cells, int *index)
+{
+ FILE *f;
+ char cell[64];
+ int i;
+ int ind = *index;
+
+ f = fopen(file, "r");
+ if (f == NULL)
+ return;
+ while (fgets(cell, sizeof(cell), f)) {
+ char *t;
+ t = cell + strlen(cell);
+ for (; t >= cell; t--)
+ if (*t == '\n' || *t == '\t' || *t == ' ')
+ *t = 0;
+ if (cell[0] == '\0' || cell[0] == '#')
+ continue;
+ for(i = 0; i < ind; i++)
+ if(strcmp((*cells)[i], cell) == 0)
+ break;
+ if(i == ind){
+ char **tmp;
+
+ tmp = realloc(*cells, (ind + 1) * sizeof(**cells));
+ if (tmp == NULL)
+ break;
+ *cells = tmp;
+ (*cells)[ind] = strdup(cell);
+ if ((*cells)[ind] == NULL)
+ break;
+ ++ind;
+ }
+ }
+ fclose(f);
+ *index = ind;
+}
+
+/*
+ * Get tokens for all cells[]
+ */
+static int
+afslog_cells(kafs_data *data, char **cells, int max, uid_t uid,
+ const char *homedir)
+{
+ int ret = 0;
+ int i;
+ for (i = 0; i < max; i++) {
+ int er = (*data->afslog_uid)(data, cells[i], 0, uid, homedir);
+ if (er)
+ ret = er;
+ }
+ return ret;
+}
+
+int
+_kafs_afslog_all_local_cells(kafs_data *data, uid_t uid, const char *homedir)
+{
+ int ret;
+ char **cells = NULL;
+ int index = 0;
+
+ if (homedir == NULL)
+ homedir = getenv("HOME");
+ if (homedir != NULL) {
+ char home[MaxPathLen];
+ snprintf(home, sizeof(home), "%s/.TheseCells", homedir);
+ find_cells(home, &cells, &index);
+ }
+ find_cells(_PATH_THESECELLS, &cells, &index);
+ find_cells(_PATH_THISCELL, &cells, &index);
+ find_cells(_PATH_ARLA_THESECELLS, &cells, &index);
+ find_cells(_PATH_ARLA_THISCELL, &cells, &index);
+
+ ret = afslog_cells(data, cells, index, uid, homedir);
+ while(index > 0)
+ free(cells[--index]);
+ free(cells);
+ return ret;
+}
+
+
+/* Find the realm associated with cell. Do this by opening
+ /usr/vice/etc/CellServDB and getting the realm-of-host for the
+ first VL-server for the cell.
+
+ This does not work when the VL-server is living in one realm, but
+ the cell it is serving is living in another realm.
+
+ Return 0 on success, -1 otherwise.
+ */
+
+int
+_kafs_realm_of_cell(kafs_data *data, const char *cell, char **realm)
+{
+ FILE *F;
+ char buf[1024];
+ char *p;
+ int ret = -1;
+
+ if ((F = fopen(_PATH_CELLSERVDB, "r"))
+ || (F = fopen(_PATH_ARLA_CELLSERVDB, "r"))) {
+ while (fgets(buf, sizeof(buf), F)) {
+ if (buf[0] != '>')
+ continue; /* Not a cell name line, try next line */
+ if (strncmp(buf + 1, cell, strlen(cell)) == 0) {
+ /*
+ * We found the cell name we're looking for.
+ * Read next line on the form ip-address '#' hostname
+ */
+ if (fgets(buf, sizeof(buf), F) == NULL)
+ break; /* Read failed, give up */
+ p = strchr(buf, '#');
+ if (p == NULL)
+ break; /* No '#', give up */
+ p++;
+ if (buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ *realm = (*data->get_realm)(data, p);
+ if (*realm && **realm != '\0')
+ ret = 0;
+ break; /* Won't try any more */
+ }
+ }
+ fclose(F);
+ }
+ if (*realm == NULL && dns_find_cell(cell, buf, sizeof(buf)) == 0) {
+ *realm = strdup(krb_realmofhost(buf));
+ if(*realm != NULL)
+ ret = 0;
+ }
+ return ret;
+}
+
+int
+_kafs_get_cred(kafs_data *data,
+ const char *cell,
+ const char *realm_hint,
+ const char *realm,
+ CREDENTIALS *c)
+{
+ int ret = -1;
+ char *vl_realm;
+ char CELL[64];
+
+ /* We're about to find the the realm that holds the key for afs in
+ * the specified cell. The problem is that null-instance
+ * afs-principals are common and that hitting the wrong realm might
+ * yield the wrong afs key. The following assumptions were made.
+ *
+ * Any realm passed to us is preferred.
+ *
+ * If there is a realm with the same name as the cell, it is most
+ * likely the correct realm to talk to.
+ *
+ * In most (maybe even all) cases the database servers of the cell
+ * will live in the realm we are looking for.
+ *
+ * Try the local realm, but if the previous cases fail, this is
+ * really a long shot.
+ *
+ */
+
+ /* comments on the ordering of these tests */
+
+ /* If the user passes a realm, she probably knows something we don't
+ * know and we should try afs@realm_hint (otherwise we're talking with a
+ * blondino and she might as well have it.)
+ */
+
+ if (realm_hint) {
+ ret = (*data->get_cred)(data, AUTH_SUPERUSER, cell, realm_hint, c);
+ if (ret == 0) return 0;
+ ret = (*data->get_cred)(data, AUTH_SUPERUSER, "", realm_hint, c);
+ if (ret == 0) return 0;
+ }
+
+ foldup(CELL, cell);
+
+ /*
+ * If cell == realm we don't need no cross-cell authentication.
+ * Try afs@REALM.
+ */
+ if (strcmp(CELL, realm) == 0) {
+ ret = (*data->get_cred)(data, AUTH_SUPERUSER, "", realm, c);
+ if (ret == 0) return 0;
+ /* Try afs.cell@REALM below. */
+ }
+
+ /*
+ * If the AFS servers have a file /usr/afs/etc/krb.conf containing
+ * REALM we still don't have to resort to cross-cell authentication.
+ * Try afs.cell@REALM.
+ */
+ ret = (*data->get_cred)(data, AUTH_SUPERUSER, cell, realm, c);
+ if (ret == 0) return 0;
+
+ /*
+ * We failed to get ``first class tickets'' for afs,
+ * fall back to cross-cell authentication.
+ * Try afs@CELL.
+ * Try afs.cell@CELL.
+ */
+ ret = (*data->get_cred)(data, AUTH_SUPERUSER, "", CELL, c);
+ if (ret == 0) return 0;
+ ret = (*data->get_cred)(data, AUTH_SUPERUSER, cell, CELL, c);
+ if (ret == 0) return 0;
+
+ /*
+ * Perhaps the cell doesn't correspond to any realm?
+ * Use realm of first volume location DB server.
+ * Try afs.cell@VL_REALM.
+ * Try afs@VL_REALM???
+ */
+ if (_kafs_realm_of_cell(data, cell, &vl_realm) == 0
+ && strcmp(vl_realm, realm) != 0
+ && strcmp(vl_realm, CELL) != 0) {
+ ret = (*data->get_cred)(data, AUTH_SUPERUSER, cell, vl_realm, c);
+ if (ret)
+ ret = (*data->get_cred)(data, AUTH_SUPERUSER, "", vl_realm, c);
+ free(vl_realm);
+ if (ret == 0) return 0;
+ }
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/kafs/dlfcn.c b/crypto/heimdal/lib/kafs/dlfcn.c
new file mode 100644
index 000000000000..e664fe3e5da6
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/dlfcn.c
@@ -0,0 +1,581 @@
+/*
+ * @(#)dlfcn.c 1.11 revision of 96/04/10 20:12:51
+ * This is an unpublished work copyright (c) 1992 HELIOS Software GmbH
+ * 30159 Hannover, Germany
+ */
+
+/*
+ * Changes marked with `--jwe' were made on April 7 1996 by John W. Eaton
+ * <jwe@bevo.che.wisc.edu> to support g++ and/or use with Octave.
+ */
+
+/*
+ * This makes my life easier with Octave. --jwe
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/ldr.h>
+#include <a.out.h>
+#include <ldfcn.h>
+#include "dlfcn.h"
+
+/*
+ * We simulate dlopen() et al. through a call to load. Because AIX has
+ * no call to find an exported symbol we read the loader section of the
+ * loaded module and build a list of exported symbols and their virtual
+ * address.
+ */
+
+typedef struct {
+ char *name; /* the symbols's name */
+ void *addr; /* its relocated virtual address */
+} Export, *ExportPtr;
+
+/*
+ * xlC uses the following structure to list its constructors and
+ * destructors. This is gleaned from the output of munch.
+ */
+typedef struct {
+ void (*init)(void); /* call static constructors */
+ void (*term)(void); /* call static destructors */
+} Cdtor, *CdtorPtr;
+
+typedef void (*GccCDtorPtr)(void);
+
+/*
+ * The void * handle returned from dlopen is actually a ModulePtr.
+ */
+typedef struct Module {
+ struct Module *next;
+ char *name; /* module name for refcounting */
+ int refCnt; /* the number of references */
+ void *entry; /* entry point from load */
+ struct dl_info *info; /* optional init/terminate functions */
+ CdtorPtr cdtors; /* optional C++ constructors */
+ GccCDtorPtr gcc_ctor; /* g++ constructors --jwe */
+ GccCDtorPtr gcc_dtor; /* g++ destructors --jwe */
+ int nExports; /* the number of exports found */
+ ExportPtr exports; /* the array of exports */
+} Module, *ModulePtr;
+
+/*
+ * We keep a list of all loaded modules to be able to call the fini
+ * handlers and destructors at atexit() time.
+ */
+static ModulePtr modList;
+
+/*
+ * The last error from one of the dl* routines is kept in static
+ * variables here. Each error is returned only once to the caller.
+ */
+static char errbuf[BUFSIZ];
+static int errvalid;
+
+/*
+ * The `fixed' gcc header files on AIX 3.2.5 provide a prototype for
+ * strdup(). --jwe
+ */
+#ifndef HAVE_STRDUP
+extern char *strdup(const char *);
+#endif
+static void caterr(char *);
+static int readExports(ModulePtr);
+static void terminate(void);
+static void *findMain(void);
+
+void *dlopen(const char *path, int mode)
+{
+ ModulePtr mp;
+ static void *mainModule;
+
+ /*
+ * Upon the first call register a terminate handler that will
+ * close all libraries. Also get a reference to the main module
+ * for use with loadbind.
+ */
+ if (!mainModule) {
+ if ((mainModule = findMain()) == NULL)
+ return NULL;
+ atexit(terminate);
+ }
+ /*
+ * Scan the list of modules if we have the module already loaded.
+ */
+ for (mp = modList; mp; mp = mp->next)
+ if (strcmp(mp->name, path) == 0) {
+ mp->refCnt++;
+ return mp;
+ }
+ if ((mp = (ModulePtr)calloc(1, sizeof(*mp))) == NULL) {
+ errvalid++;
+ snprintf (errbuf, "calloc: %s", strerror(errno));
+ return NULL;
+ }
+ if ((mp->name = strdup(path)) == NULL) {
+ errvalid++;
+ snprintf (errbuf, "strdup: %s", strerror(errno));
+ free(mp);
+ return NULL;
+ }
+ /*
+ * load should be declared load(const char *...). Thus we
+ * cast the path to a normal char *. Ugly.
+ */
+ if ((mp->entry = (void *)load((char *)path, L_NOAUTODEFER, NULL)) == NULL) {
+ free(mp->name);
+ free(mp);
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "dlopen: %s: ", path);
+ /*
+ * If AIX says the file is not executable, the error
+ * can be further described by querying the loader about
+ * the last error.
+ */
+ if (errno == ENOEXEC) {
+ char *tmp[BUFSIZ/sizeof(char *)];
+ if (loadquery(L_GETMESSAGES, tmp, sizeof(tmp)) == -1)
+ strlcpy(errbuf,
+ strerror(errno),
+ sizeof(errbuf));
+ else {
+ char **p;
+ for (p = tmp; *p; p++)
+ caterr(*p);
+ }
+ } else
+ strlcat(errbuf,
+ strerror(errno),
+ sizeof(errbuf));
+ return NULL;
+ }
+ mp->refCnt = 1;
+ mp->next = modList;
+ modList = mp;
+ if (loadbind(0, mainModule, mp->entry) == -1) {
+ dlclose(mp);
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "loadbind: %s", strerror(errno));
+ return NULL;
+ }
+ /*
+ * If the user wants global binding, loadbind against all other
+ * loaded modules.
+ */
+ if (mode & RTLD_GLOBAL) {
+ ModulePtr mp1;
+ for (mp1 = mp->next; mp1; mp1 = mp1->next)
+ if (loadbind(0, mp1->entry, mp->entry) == -1) {
+ dlclose(mp);
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "loadbind: %s",
+ strerror(errno));
+ return NULL;
+ }
+ }
+ if (readExports(mp) == -1) {
+ dlclose(mp);
+ return NULL;
+ }
+ /*
+ * If there is a dl_info structure, call the init function.
+ */
+ if (mp->info = (struct dl_info *)dlsym(mp, "dl_info")) {
+ if (mp->info->init)
+ (*mp->info->init)();
+ } else
+ errvalid = 0;
+ /*
+ * If the shared object was compiled using xlC we will need
+ * to call static constructors (and later on dlclose destructors).
+ */
+ if (mp->cdtors = (CdtorPtr)dlsym(mp, "__cdtors")) {
+ CdtorPtr cp = mp->cdtors;
+ while (cp->init || cp->term) {
+ if (cp->init && cp->init != (void (*)(void))0xffffffff)
+ (*cp->init)();
+ cp++;
+ }
+ /*
+ * If the shared object was compiled using g++, we will need
+ * to call global constructors using the _GLOBAL__DI function,
+ * and later, global destructors using the _GLOBAL_DD
+ * funciton. --jwe
+ */
+ } else if (mp->gcc_ctor = (GccCDtorPtr)dlsym(mp, "_GLOBAL__DI")) {
+ (*mp->gcc_ctor)();
+ mp->gcc_dtor = (GccCDtorPtr)dlsym(mp, "_GLOBAL__DD");
+ } else
+ errvalid = 0;
+ return mp;
+}
+
+/*
+ * Attempt to decipher an AIX loader error message and append it
+ * to our static error message buffer.
+ */
+static void caterr(char *s)
+{
+ char *p = s;
+
+ while (*p >= '0' && *p <= '9')
+ p++;
+ switch(atoi(s)) {
+ case L_ERROR_TOOMANY:
+ strlcat(errbuf, "to many errors", sizeof(errbuf));
+ break;
+ case L_ERROR_NOLIB:
+ strlcat(errbuf, "can't load library", sizeof(errbuf));
+ strlcat(errbuf, p, sizeof(errbuf));
+ break;
+ case L_ERROR_UNDEF:
+ strlcat(errbuf, "can't find symbol", sizeof(errbuf));
+ strlcat(errbuf, p, sizeof(errbuf));
+ break;
+ case L_ERROR_RLDBAD:
+ strlcat(errbuf, "bad RLD", sizeof(errbuf));
+ strlcat(errbuf, p, sizeof(errbuf));
+ break;
+ case L_ERROR_FORMAT:
+ strlcat(errbuf, "bad exec format in", sizeof(errbuf));
+ strlcat(errbuf, p, sizeof(errbuf));
+ break;
+ case L_ERROR_ERRNO:
+ strlcat(errbuf, strerror(atoi(++p)), sizeof(errbuf));
+ break;
+ default:
+ strlcat(errbuf, s, sizeof(errbuf));
+ break;
+ }
+}
+
+void *dlsym(void *handle, const char *symbol)
+{
+ ModulePtr mp = (ModulePtr)handle;
+ ExportPtr ep;
+ int i;
+
+ /*
+ * Could speed up the search, but I assume that one assigns
+ * the result to function pointers anyways.
+ */
+ for (ep = mp->exports, i = mp->nExports; i; i--, ep++)
+ if (strcmp(ep->name, symbol) == 0)
+ return ep->addr;
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "dlsym: undefined symbol %s", symbol);
+ return NULL;
+}
+
+char *dlerror(void)
+{
+ if (errvalid) {
+ errvalid = 0;
+ return errbuf;
+ }
+ return NULL;
+}
+
+int dlclose(void *handle)
+{
+ ModulePtr mp = (ModulePtr)handle;
+ int result;
+ ModulePtr mp1;
+
+ if (--mp->refCnt > 0)
+ return 0;
+ if (mp->info && mp->info->fini)
+ (*mp->info->fini)();
+ if (mp->cdtors) {
+ CdtorPtr cp = mp->cdtors;
+ while (cp->init || cp->term) {
+ if (cp->term && cp->init != (void (*)(void))0xffffffff)
+ (*cp->term)();
+ cp++;
+ }
+ /*
+ * If the function to handle global destructors for g++
+ * exists, call it. --jwe
+ */
+ } else if (mp->gcc_dtor) {
+ (*mp->gcc_dtor)();
+ }
+ result = unload(mp->entry);
+ if (result == -1) {
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "%s", strerror(errno));
+ }
+ if (mp->exports) {
+ ExportPtr ep;
+ int i;
+ for (ep = mp->exports, i = mp->nExports; i; i--, ep++)
+ if (ep->name)
+ free(ep->name);
+ free(mp->exports);
+ }
+ if (mp == modList)
+ modList = mp->next;
+ else {
+ for (mp1 = modList; mp1; mp1 = mp1->next)
+ if (mp1->next == mp) {
+ mp1->next = mp->next;
+ break;
+ }
+ }
+ free(mp->name);
+ free(mp);
+ return result;
+}
+
+static void terminate(void)
+{
+ while (modList)
+ dlclose(modList);
+}
+
+/*
+ * Build the export table from the XCOFF .loader section.
+ */
+static int readExports(ModulePtr mp)
+{
+ LDFILE *ldp = NULL;
+ SCNHDR sh, shdata;
+ LDHDR *lhp;
+ char *ldbuf;
+ LDSYM *ls;
+ int i;
+ ExportPtr ep;
+
+ if ((ldp = ldopen(mp->name, ldp)) == NULL) {
+ struct ld_info *lp;
+ char *buf;
+ int size = 4*1024;
+ if (errno != ENOENT) {
+ errvalid++;
+ snprintf(errbuf, sizeof(errbuf),
+ "readExports: %s",
+ strerror(errno));
+ return -1;
+ }
+ /*
+ * The module might be loaded due to the LIBPATH
+ * environment variable. Search for the loaded
+ * module using L_GETINFO.
+ */
+ if ((buf = malloc(size)) == NULL) {
+ errvalid++;
+ snprintf(errbuf, sizeof(errbuf),
+ "readExports: %s",
+ strerror(errno));
+ return -1;
+ }
+ while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
+ free(buf);
+ size += 4*1024;
+ if ((buf = malloc(size)) == NULL) {
+ errvalid++;
+ snprintf(errbuf, sizeof(errbuf),
+ "readExports: %s",
+ strerror(errno));
+ return -1;
+ }
+ }
+ if (i == -1) {
+ errvalid++;
+ snprintf(errbuf, sizeof(errbuf),
+ "readExports: %s",
+ strerror(errno));
+ free(buf);
+ return -1;
+ }
+ /*
+ * Traverse the list of loaded modules. The entry point
+ * returned by load() does actually point to the data
+ * segment origin.
+ */
+ lp = (struct ld_info *)buf;
+ while (lp) {
+ if (lp->ldinfo_dataorg == mp->entry) {
+ ldp = ldopen(lp->ldinfo_filename, ldp);
+ break;
+ }
+ if (lp->ldinfo_next == 0)
+ lp = NULL;
+ else
+ lp = (struct ld_info *)((char *)lp + lp->ldinfo_next);
+ }
+ free(buf);
+ if (!ldp) {
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "readExports: %s", strerror(errno));
+ return -1;
+ }
+ }
+ if (TYPE(ldp) != U802TOCMAGIC) {
+ errvalid++;
+ snprintf(errbuf, sizeof(errbuf), "readExports: bad magic");
+ while(ldclose(ldp) == FAILURE)
+ ;
+ return -1;
+ }
+ /*
+ * Get the padding for the data section. This is needed for
+ * AIX 4.1 compilers. This is used when building the final
+ * function pointer to the exported symbol.
+ */
+ if (ldnshread(ldp, _DATA, &shdata) != SUCCESS) {
+ errvalid++;
+ snprintf(errbuf, sizeof(errbuf),
+ "readExports: cannot read data section header");
+ while(ldclose(ldp) == FAILURE)
+ ;
+ return -1;
+ }
+ if (ldnshread(ldp, _LOADER, &sh) != SUCCESS) {
+ errvalid++;
+ snprintf(errbuf, sizeof(errbuf),
+ "readExports: cannot read loader section header");
+ while(ldclose(ldp) == FAILURE)
+ ;
+ return -1;
+ }
+ /*
+ * We read the complete loader section in one chunk, this makes
+ * finding long symbol names residing in the string table easier.
+ */
+ if ((ldbuf = (char *)malloc(sh.s_size)) == NULL) {
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "readExports: %s", strerror(errno));
+ while(ldclose(ldp) == FAILURE)
+ ;
+ return -1;
+ }
+ if (FSEEK(ldp, sh.s_scnptr, BEGINNING) != OKFSEEK) {
+ errvalid++;
+ snprintf(errbuf, sizeof(errbuf),
+ "readExports: cannot seek to loader section");
+ free(ldbuf);
+ while(ldclose(ldp) == FAILURE)
+ ;
+ return -1;
+ }
+ if (FREAD(ldbuf, sh.s_size, 1, ldp) != 1) {
+ errvalid++;
+ snprintf(errbuf, sizeof(errbuf),
+ "readExports: cannot read loader section");
+ free(ldbuf);
+ while(ldclose(ldp) == FAILURE)
+ ;
+ return -1;
+ }
+ lhp = (LDHDR *)ldbuf;
+ ls = (LDSYM *)(ldbuf+LDHDRSZ);
+ /*
+ * Count the number of exports to include in our export table.
+ */
+ for (i = lhp->l_nsyms; i; i--, ls++) {
+ if (!LDR_EXPORT(*ls))
+ continue;
+ mp->nExports++;
+ }
+ if ((mp->exports = (ExportPtr)calloc(mp->nExports, sizeof(*mp->exports))) == NULL) {
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "readExports: %s", strerror(errno));
+ free(ldbuf);
+ while(ldclose(ldp) == FAILURE)
+ ;
+ return -1;
+ }
+ /*
+ * Fill in the export table. All entries are relative to
+ * the entry point we got from load.
+ */
+ ep = mp->exports;
+ ls = (LDSYM *)(ldbuf+LDHDRSZ);
+ for (i = lhp->l_nsyms; i; i--, ls++) {
+ char *symname;
+ char tmpsym[SYMNMLEN+1];
+ if (!LDR_EXPORT(*ls))
+ continue;
+ if (ls->l_zeroes == 0)
+ symname = ls->l_offset+lhp->l_stoff+ldbuf;
+ else {
+ /*
+ * The l_name member is not zero terminated, we
+ * must copy the first SYMNMLEN chars and make
+ * sure we have a zero byte at the end.
+ */
+ strlcpy (tmpsym, ls->l_name,
+ SYMNMLEN + 1);
+ symname = tmpsym;
+ }
+ ep->name = strdup(symname);
+ ep->addr = (void *)((unsigned long)mp->entry +
+ ls->l_value - shdata.s_vaddr);
+ ep++;
+ }
+ free(ldbuf);
+ while(ldclose(ldp) == FAILURE)
+ ;
+ return 0;
+}
+
+/*
+ * Find the main modules entry point. This is used as export pointer
+ * for loadbind() to be able to resolve references to the main part.
+ */
+static void * findMain(void)
+{
+ struct ld_info *lp;
+ char *buf;
+ int size = 4*1024;
+ int i;
+ void *ret;
+
+ if ((buf = malloc(size)) == NULL) {
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "findMail: %s", strerror(errno));
+ return NULL;
+ }
+ while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
+ free(buf);
+ size += 4*1024;
+ if ((buf = malloc(size)) == NULL) {
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "findMail: %s", strerror(errno));
+ return NULL;
+ }
+ }
+ if (i == -1) {
+ errvalid++;
+ snprintf (errbuf, sizeof(errbuf),
+ "findMail: %s", strerror(errno));
+ free(buf);
+ return NULL;
+ }
+ /*
+ * The first entry is the main module. The entry point
+ * returned by load() does actually point to the data
+ * segment origin.
+ */
+ lp = (struct ld_info *)buf;
+ ret = lp->ldinfo_dataorg;
+ free(buf);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/kafs/dlfcn.h b/crypto/heimdal/lib/kafs/dlfcn.h
new file mode 100644
index 000000000000..5671e9caa3a7
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/dlfcn.h
@@ -0,0 +1,46 @@
+/*
+ * @(#)dlfcn.h 1.4 revision of 95/04/25 09:36:52
+ * This is an unpublished work copyright (c) 1992 HELIOS Software GmbH
+ * 30159 Hannover, Germany
+ */
+
+#ifndef __dlfcn_h__
+#define __dlfcn_h__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Mode flags for the dlopen routine.
+ */
+#define RTLD_LAZY 1 /* lazy function call binding */
+#define RTLD_NOW 2 /* immediate function call binding */
+#define RTLD_GLOBAL 0x100 /* allow symbols to be global */
+
+/*
+ * To be able to intialize, a library may provide a dl_info structure
+ * that contains functions to be called to initialize and terminate.
+ */
+struct dl_info {
+ void (*init)(void);
+ void (*fini)(void);
+};
+
+#if __STDC__ || defined(_IBMR2)
+void *dlopen(const char *path, int mode);
+void *dlsym(void *handle, const char *symbol);
+char *dlerror(void);
+int dlclose(void *handle);
+#else
+void *dlopen();
+void *dlsym();
+char *dlerror();
+int dlclose();
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __dlfcn_h__ */
diff --git a/crypto/heimdal/lib/kafs/kafs.3 b/crypto/heimdal/lib/kafs/kafs.3
new file mode 100644
index 000000000000..4a7b5efb8c4f
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/kafs.3
@@ -0,0 +1,158 @@
+.\" $Id: kafs.3,v 1.3 1998/06/30 15:41:52 assar Exp $
+.\"
+.Dd May 7, 1997
+.Os KTH-KRB
+.Dt KAFS 3
+.Sh NAME
+.Nm k_hasafs ,
+.Nm k_pioctl ,
+.Nm k_unlog ,
+.Nm k_setpag ,
+.Nm k_afs_cell_of_file ,
+.Nm krb_afslog ,
+.Nm krb_afslog_uid
+\" .Nm krb5_afslog ,
+\" .Nm krb5_afslog_uid
+.Nd AFS library
+.Sh SYNOPSIS
+.Fd #include <kafs.h>
+.Ft int
+.Fn k_afs_cell_of_file "const char *path" "char *cell" "int len"
+.Ft int
+.Fn k_hasafs
+.Ft int
+.Fn k_pioctl "char *a_path" "int o_opcode" "struct ViceIoctl *a_paramsP" "int a_followSymlinks"
+.Ft int
+.Fn k_setpag
+.Ft int
+.Fn k_unlog
+.Ft int
+.Fn krb_afslog "char *cell" "char *realm"
+.Ft int
+.Fn krb_afslog_uid "char *cell" "char *realm" "uid_t uid"
+\" .Ft krb5_error_code
+\" .Fn krb5_afslog_uid "krb5_context context" "krb5_ccache id" "const char *cell" "krb5_const_realm realm" "uid_t uid"
+\" .Ft krb5_error_code
+\" .Fn krb5_afslog "krb5_context context" "krb5_ccache id" "const char *cell" "krb5_const_realm realm"
+.Sh DESCRIPTION
+.Fn k_hasafs
+initializes some library internal structures, and tests for the
+presense of AFS in the kernel, none of the other functions should be
+called before
+.Fn k_hasafs
+is called, or if it fails.
+
+.Fn krb_afslog ,
+and
+.Fn krb_afslog_uid
+obtains new tokens (and possibly tickets) for the specified
+.Fa cell
+and
+.Fa realm .
+If
+.Fa cell
+is
+.Dv NULL ,
+the local cell is used. If
+.Fa realm
+is
+.Dv NULL ,
+the function tries to guess what realm to use. Unless you have some good knowledge of what cell or realm to use, you should pass
+.Dv NULL .
+.Fn krb_afslog
+will use the real user-id for the
+.Dv ViceId
+field in the token,
+.Fn krb_afslog_uid
+will use
+.Fa uid .
+
+\" .Fn krb5_afslog ,
+\" and
+\" .Fn krb5_afslog_uid
+\" are the Kerberos 5 equivalents of
+\" .Fn krb_afslog ,
+\" and
+\" .Fn krb_afslog_uid .
+\" The extra arguments are the ubiquitous context, and the cache id where
+\" to store any obtained tickets. Since AFS servers normally can't handle
+\" Kerberos 5 tickets directly, these functions will first obtain version
+\" 5 tickets for the requested cells, and then convert them to version 4
+\" tickets, that can be stashed in the kernel. To convert tickets the
+\" .Fn krb524_convert_creds_kdc
+\" function will be used.
+
+.Fn k_afs_cell_of_file
+will in
+.Fa cell
+return the cell of a specified file, no more than
+.Fa len
+characters is put in
+.Fa cell .
+
+.Fn k_pioctl
+does a
+.Fn pioctl
+syscall with the specified arguments. This function is equivalent to
+.Fn lpioctl .
+
+.Fn k_setpag
+initializes a new PAG.
+
+.Fn k_unlog
+removes destroys all tokens in the current PAG.
+
+.Sh ENVIRONMENT
+The following environment variable affect the mode of operation of
+.Nm kafs :
+.Bl -tag
+.It Ev AFS_SYSCALL
+Normally,
+.Nm kafs
+will try to figure out the correct system call(s) that are used by AFS
+by itself. If it does not manage to do that, or does it incorrectly,
+you can set this variable to the system call number or list of system
+call numbers that should be used.
+.El
+.Sh RETURN VALUES
+.Fn k_hasafs
+returns 1 if AFS is present in the kernel, 0 otherwise.
+.Fn krb_afslog
+and
+.Fn krb_afslog_uid
+returns 0 on success, or a kerberos error number on failure.
+.Fn k_afs_cell_of_file ,
+.Fn k_pioctl ,
+.Fn k_setpag ,
+and
+.Fn k_unlog
+all return the value of the underlaying system call, 0 on success.
+.Sh EXAMPLES
+The following code from
+.Nm login
+will obtain a new PAG and tokens for the local cell and the cell of
+the users home directory.
+.Bd -literal
+if (k_hasafs()) {
+ char cell[64];
+ k_setpag();
+ if(k_afs_cell_of_file(pwd->pw_dir, cell, sizeof(cell)) == 0)
+ krb_afslog(cell, NULL);
+ krb_afslog(NULL, NULL);
+}
+.Ed
+.Sh ERRORS
+If any of these functions (appart from
+.Fn k_hasafs )
+is called without AFS beeing present in the kernel, the process will
+usually (depending on the operating system) receive a SIGSYS signal.
+.Sh SEE ALSO
+.Rs
+.%A Transarc Corporation
+.%J AFS-3 Programmer's Reference
+.%T File Server/Cache Manager Interface
+.%D 1991
+.Re
+.Sh BUGS
+.Ev AFS_SYSCALL
+has no effect under AIX.
diff --git a/crypto/heimdal/lib/kafs/kafs.h b/crypto/heimdal/lib/kafs/kafs.h
new file mode 100644
index 000000000000..0fb969ea3300
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/kafs.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: kafs.h,v 1.32 1999/12/02 16:58:40 joda Exp $ */
+
+#ifndef __KAFS_H
+#define __KAFS_H
+
+/* XXX must include krb5.h or krb.h */
+
+/* sys/ioctl.h must be included manually before kafs.h */
+
+/*
+ */
+#define AFSCALL_PIOCTL 20
+#define AFSCALL_SETPAG 21
+
+#ifndef _VICEIOCTL
+#define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl))
+#endif /* _VICEIOCTL */
+
+#define VIOCSETAL _VICEIOCTL(1)
+#define VIOCGETAL _VICEIOCTL(2)
+#define VIOCSETTOK _VICEIOCTL(3)
+#define VIOCGETVOLSTAT _VICEIOCTL(4)
+#define VIOCSETVOLSTAT _VICEIOCTL(5)
+#define VIOCFLUSH _VICEIOCTL(6)
+#define VIOCGETTOK _VICEIOCTL(8)
+#define VIOCUNLOG _VICEIOCTL(9)
+#define VIOCCKSERV _VICEIOCTL(10)
+#define VIOCCKBACK _VICEIOCTL(11)
+#define VIOCCKCONN _VICEIOCTL(12)
+#define VIOCWHEREIS _VICEIOCTL(14)
+#define VIOCACCESS _VICEIOCTL(20)
+#define VIOCUNPAG _VICEIOCTL(21)
+#define VIOCGETFID _VICEIOCTL(22)
+#define VIOCSETCACHESIZE _VICEIOCTL(24)
+#define VIOCFLUSHCB _VICEIOCTL(25)
+#define VIOCNEWCELL _VICEIOCTL(26)
+#define VIOCGETCELL _VICEIOCTL(27)
+#define VIOC_AFS_DELETE_MT_PT _VICEIOCTL(28)
+#define VIOC_AFS_STAT_MT_PT _VICEIOCTL(29)
+#define VIOC_FILE_CELL_NAME _VICEIOCTL(30)
+#define VIOC_GET_WS_CELL _VICEIOCTL(31)
+#define VIOC_AFS_MARINER_HOST _VICEIOCTL(32)
+#define VIOC_GET_PRIMARY_CELL _VICEIOCTL(33)
+#define VIOC_VENUSLOG _VICEIOCTL(34)
+#define VIOC_GETCELLSTATUS _VICEIOCTL(35)
+#define VIOC_SETCELLSTATUS _VICEIOCTL(36)
+#define VIOC_FLUSHVOLUME _VICEIOCTL(37)
+#define VIOC_AFS_SYSNAME _VICEIOCTL(38)
+#define VIOC_EXPORTAFS _VICEIOCTL(39)
+#define VIOCGETCACHEPARAMS _VICEIOCTL(40)
+#define VIOC_GCPAGS _VICEIOCTL(48)
+
+struct ViceIoctl {
+ caddr_t in, out;
+ short in_size;
+ short out_size;
+};
+
+struct ClearToken {
+ int32_t AuthHandle;
+ char HandShakeKey[8];
+ int32_t ViceId;
+ int32_t BeginTimestamp;
+ int32_t EndTimestamp;
+};
+
+#ifdef __STDC__
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+/* Use k_hasafs() to probe if the machine supports AFS syscalls.
+ The other functions will generate a SIGSYS if AFS is not supported */
+
+int k_hasafs __P((void));
+
+int krb_afslog __P((const char *cell, const char *realm));
+int krb_afslog_uid __P((const char *cell, const char *realm, uid_t uid));
+int krb_afslog_home __P((const char *cell, const char *realm,
+ const char *homedir));
+int krb_afslog_uid_home __P((const char *cell, const char *realm, uid_t uid,
+ const char *homedir));
+
+int krb_realm_of_cell __P((const char *cell, char **realm));
+
+/* compat */
+#define k_afsklog krb_afslog
+#define k_afsklog_uid krb_afslog_uid
+
+int k_pioctl __P((char *a_path,
+ int o_opcode,
+ struct ViceIoctl *a_paramsP,
+ int a_followSymlinks));
+int k_unlog __P((void));
+int k_setpag __P((void));
+int k_afs_cell_of_file __P((const char *path, char *cell, int len));
+
+
+
+/* XXX */
+#ifdef KFAILURE
+#define KRB_H_INCLUDED
+#endif
+
+#ifdef KRB5_RECVAUTH_IGNORE_VERSION
+#define KRB5_H_INCLUDED
+#endif
+
+#ifdef KRB_H_INCLUDED
+int kafs_settoken __P((const char*, uid_t, CREDENTIALS*));
+#endif
+
+#ifdef KRB5_H_INCLUDED
+krb5_error_code krb5_afslog_uid __P((krb5_context context,
+ krb5_ccache id,
+ const char *cell,
+ krb5_const_realm realm,
+ uid_t uid));
+krb5_error_code krb5_afslog __P((krb5_context context,
+ krb5_ccache id,
+ const char *cell,
+ krb5_const_realm realm));
+krb5_error_code krb5_afslog_uid_home __P((krb5_context context,
+ krb5_ccache id,
+ const char *cell,
+ krb5_const_realm realm,
+ uid_t uid,
+ const char *homedir));
+
+krb5_error_code krb5_afslog_home __P((krb5_context context,
+ krb5_ccache id,
+ const char *cell,
+ krb5_const_realm realm,
+ const char *homedir));
+
+krb5_error_code krb5_realm_of_cell __P((const char *cell, char **realm));
+
+#endif
+
+
+#define _PATH_VICE "/usr/vice/etc/"
+#define _PATH_THISCELL _PATH_VICE "ThisCell"
+#define _PATH_CELLSERVDB _PATH_VICE "CellServDB"
+#define _PATH_THESECELLS _PATH_VICE "TheseCells"
+
+#define _PATH_ARLA_VICE "/usr/arla/etc/"
+#define _PATH_ARLA_THISCELL _PATH_ARLA_VICE "ThisCell"
+#define _PATH_ARLA_CELLSERVDB _PATH_ARLA_VICE "CellServDB"
+#define _PATH_ARLA_THESECELLS _PATH_ARLA_VICE "TheseCells"
+
+extern int _kafs_debug;
+
+#endif /* __KAFS_H */
diff --git a/crypto/heimdal/lib/kafs/kafs_locl.h b/crypto/heimdal/lib/kafs/kafs_locl.h
new file mode 100644
index 000000000000..ac1c2f6d9faa
--- /dev/null
+++ b/crypto/heimdal/lib/kafs/kafs_locl.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: kafs_locl.h,v 1.15 1999/12/02 16:58:40 joda Exp $ */
+
+#ifndef __KAFS_LOCL_H__
+#define __KAFS_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <errno.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+
+#ifdef HAVE_SYS_SYSCALL_H
+#include <sys/syscall.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+#include <roken.h>
+
+#ifdef KRB5
+#include <krb5.h>
+#endif
+#ifdef KRB4
+#include <krb.h>
+#endif
+#include <kafs.h>
+
+#include <resolve.h>
+
+#include "afssysdefs.h"
+
+struct kafs_data;
+typedef int (*afslog_uid_func_t)(struct kafs_data *,
+ const char *cell,
+ const char *realm_hint,
+ uid_t,
+ const char *homedir);
+
+typedef int (*get_cred_func_t)(struct kafs_data*, const char*, const char*,
+ const char*, CREDENTIALS*);
+
+typedef char* (*get_realm_func_t)(struct kafs_data*, const char*);
+
+typedef struct kafs_data {
+ afslog_uid_func_t afslog_uid;
+ get_cred_func_t get_cred;
+ get_realm_func_t get_realm;
+ void *data;
+} kafs_data;
+
+int _kafs_afslog_all_local_cells(kafs_data*, uid_t, const char*);
+
+int _kafs_get_cred(kafs_data*, const char*, const char*, const char *,
+ CREDENTIALS*);
+
+int
+_kafs_realm_of_cell(kafs_data *data, const char *cell, char **realm);
+
+#ifdef _AIX
+int aix_pioctl(char*, int, struct ViceIoctl*, int);
+int aix_setpag(void);
+#endif
+
+#endif /* __KAFS_LOCL_H__ */
diff --git a/crypto/heimdal/lib/krb5/Makefile.am b/crypto/heimdal/lib/krb5/Makefile.am
new file mode 100644
index 000000000000..17551cb59c2a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/Makefile.am
@@ -0,0 +1,148 @@
+# $Id: Makefile.am,v 1.95 2000/01/08 17:03:51 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+bin_PROGRAMS = verify_krb5_conf
+
+noinst_PROGRAMS = dump_config
+
+check_PROGRAMS = n-fold-test string-to-key-test
+TESTS = n-fold-test string-to-key-test
+
+if KRB4
+KRB4LIB = $(LIB_krb4)
+keytab_krb4_c = keytab_krb4.c
+endif
+
+LDADD = libkrb5.la \
+ $(KRB4LIB) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
+
+lib_LTLIBRARIES = libkrb5.la
+
+ERR_FILES = krb5_err.c heim_err.c
+
+libkrb5_la_SOURCES = \
+ add_et_list.c \
+ addr_families.c \
+ address.c \
+ aname_to_localname.c \
+ asn1_glue.c \
+ auth_context.c \
+ build_ap_req.c \
+ build_auth.c \
+ cache.c \
+ changepw.c \
+ codec.c \
+ config_file.c \
+ config_file_netinfo.c \
+ convert_creds.c \
+ constants.c \
+ context.c \
+ copy_host_realm.c \
+ crc.c \
+ creds.c \
+ crypto.c \
+ data.c \
+ expand_hostname.c \
+ fcache.c \
+ free.c \
+ free_host_realm.c \
+ generate_seq_number.c \
+ generate_subkey.c \
+ get_addrs.c \
+ get_cred.c \
+ get_default_principal.c \
+ get_default_realm.c \
+ get_for_creds.c \
+ get_host_realm.c \
+ get_in_tkt.c \
+ get_in_tkt_pw.c \
+ get_in_tkt_with_keytab.c \
+ get_in_tkt_with_skey.c \
+ get_port.c \
+ init_creds.c \
+ init_creds_pw.c \
+ keyblock.c \
+ keytab.c \
+ keytab_file.c \
+ keytab_memory.c \
+ $(keytab_krb4_c) \
+ keytab_keyfile.c \
+ krbhst.c \
+ kuserok.c \
+ log.c \
+ mcache.c \
+ misc.c \
+ mk_error.c \
+ mk_priv.c \
+ mk_rep.c \
+ mk_req.c \
+ mk_req_ext.c \
+ mk_safe.c \
+ net_read.c \
+ net_write.c \
+ n-fold.c \
+ padata.c \
+ principal.c \
+ prog_setup.c \
+ prompter_posix.c \
+ rd_cred.c \
+ rd_error.c \
+ rd_priv.c \
+ rd_rep.c \
+ rd_req.c \
+ rd_safe.c \
+ read_message.c \
+ recvauth.c \
+ send_to_kdc.c \
+ sendauth.c \
+ set_default_realm.c \
+ sock_principal.c \
+ store.c \
+ store_emem.c \
+ store_fd.c \
+ store_mem.c \
+ ticket.c \
+ time.c \
+ transited.c \
+ verify_init.c \
+ verify_user.c \
+ version.c \
+ warn.c \
+ write_message.c \
+ $(ERR_FILES)
+
+EXTRA_libkrb5_la_SOURCES = keytab_krb4.c
+
+libkrb5_la_LDFLAGS = -version-info 7:1:0
+
+$(libkrb5_la_OBJECTS): $(srcdir)/krb5-protos.h $(srcdir)/krb5-private.h
+
+$(srcdir)/krb5-protos.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -o krb5-protos.h $(libkrb5_la_SOURCES) || rm -f krb5-protos.h
+
+$(srcdir)/krb5-private.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -p krb5-private.h $(libkrb5_la_SOURCES) || rm -f krb5-private.h
+
+libkrb5_la_LIBADD = ../com_err/error.lo ../com_err/com_err.lo
+
+man_MANS = krb5.conf.5 krb5_warn.3 krb5_openlog.3 \
+ krb5_425_conv_principal.3 krb5_build_principal.3 krb5_free_principal.3 \
+ krb5_parse_name.3 krb5_sname_to_principal.3 krb5_unparse_name.3
+
+include_HEADERS = krb5.h krb5-protos.h krb5-private.h krb5_err.h heim_err.h
+
+CLEANFILES = krb5_err.c krb5_err.h heim_err.c heim_err.h
+
+$(libkrb5_la_OBJECTS): krb5_err.h heim_err.h
+
+# to help stupid solaris make
+
+krb5_err.h: krb5_err.et
+
+heim_err.h: heim_err.et
diff --git a/crypto/heimdal/lib/krb5/Makefile.in b/crypto/heimdal/lib/krb5/Makefile.in
new file mode 100644
index 000000000000..6f3652eaae48
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/Makefile.in
@@ -0,0 +1,956 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.95 2000/01/08 17:03:51 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+bin_PROGRAMS = verify_krb5_conf
+
+noinst_PROGRAMS = dump_config
+
+check_PROGRAMS = n-fold-test string-to-key-test
+TESTS = n-fold-test string-to-key-test
+
+@KRB4_TRUE@KRB4LIB = $(LIB_krb4)
+@KRB4_TRUE@keytab_krb4_c = keytab_krb4.c
+
+LDADD = libkrb5.la $(KRB4LIB) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken)
+
+
+lib_LTLIBRARIES = libkrb5.la
+
+ERR_FILES = krb5_err.c heim_err.c
+
+libkrb5_la_SOURCES = add_et_list.c addr_families.c address.c aname_to_localname.c asn1_glue.c auth_context.c build_ap_req.c build_auth.c cache.c changepw.c codec.c config_file.c config_file_netinfo.c convert_creds.c constants.c context.c copy_host_realm.c crc.c creds.c crypto.c data.c expand_hostname.c fcache.c free.c free_host_realm.c generate_seq_number.c generate_subkey.c get_addrs.c get_cred.c get_default_principal.c get_default_realm.c get_for_creds.c get_host_realm.c get_in_tkt.c get_in_tkt_pw.c get_in_tkt_with_keytab.c get_in_tkt_with_skey.c get_port.c init_creds.c init_creds_pw.c keyblock.c keytab.c keytab_file.c keytab_memory.c $(keytab_krb4_c) keytab_keyfile.c krbhst.c kuserok.c log.c mcache.c misc.c mk_error.c mk_priv.c mk_rep.c mk_req.c mk_req_ext.c mk_safe.c net_read.c net_write.c n-fold.c padata.c principal.c prog_setup.c prompter_posix.c rd_cred.c rd_error.c rd_priv.c rd_rep.c rd_req.c rd_safe.c read_message.c recvauth.c send_to_kdc.c sendauth.c set_default_realm.c sock_principal.c store.c store_emem.c store_fd.c store_mem.c ticket.c time.c transited.c verify_init.c verify_user.c version.c warn.c write_message.c $(ERR_FILES)
+
+
+EXTRA_libkrb5_la_SOURCES = keytab_krb4.c
+
+libkrb5_la_LDFLAGS = -version-info 7:1:0
+
+libkrb5_la_LIBADD = ../com_err/error.lo ../com_err/com_err.lo
+
+man_MANS = krb5.conf.5 krb5_warn.3 krb5_openlog.3 krb5_425_conv_principal.3 krb5_build_principal.3 krb5_free_principal.3 krb5_parse_name.3 krb5_sname_to_principal.3 krb5_unparse_name.3
+
+
+include_HEADERS = krb5.h krb5-protos.h krb5-private.h krb5_err.h heim_err.h
+
+CLEANFILES = krb5_err.c krb5_err.h heim_err.c heim_err.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libkrb5_la_DEPENDENCIES = ../com_err/error.lo ../com_err/com_err.lo
+@KRB4_TRUE@libkrb5_la_OBJECTS = add_et_list.lo addr_families.lo \
+@KRB4_TRUE@address.lo aname_to_localname.lo asn1_glue.lo \
+@KRB4_TRUE@auth_context.lo build_ap_req.lo build_auth.lo cache.lo \
+@KRB4_TRUE@changepw.lo codec.lo config_file.lo config_file_netinfo.lo \
+@KRB4_TRUE@convert_creds.lo constants.lo context.lo copy_host_realm.lo \
+@KRB4_TRUE@crc.lo creds.lo crypto.lo data.lo expand_hostname.lo \
+@KRB4_TRUE@fcache.lo free.lo free_host_realm.lo generate_seq_number.lo \
+@KRB4_TRUE@generate_subkey.lo get_addrs.lo get_cred.lo \
+@KRB4_TRUE@get_default_principal.lo get_default_realm.lo \
+@KRB4_TRUE@get_for_creds.lo get_host_realm.lo get_in_tkt.lo \
+@KRB4_TRUE@get_in_tkt_pw.lo get_in_tkt_with_keytab.lo \
+@KRB4_TRUE@get_in_tkt_with_skey.lo get_port.lo init_creds.lo \
+@KRB4_TRUE@init_creds_pw.lo keyblock.lo keytab.lo keytab_file.lo \
+@KRB4_TRUE@keytab_memory.lo keytab_krb4.lo keytab_keyfile.lo krbhst.lo \
+@KRB4_TRUE@kuserok.lo log.lo mcache.lo misc.lo mk_error.lo mk_priv.lo \
+@KRB4_TRUE@mk_rep.lo mk_req.lo mk_req_ext.lo mk_safe.lo net_read.lo \
+@KRB4_TRUE@net_write.lo n-fold.lo padata.lo principal.lo prog_setup.lo \
+@KRB4_TRUE@prompter_posix.lo rd_cred.lo rd_error.lo rd_priv.lo \
+@KRB4_TRUE@rd_rep.lo rd_req.lo rd_safe.lo read_message.lo recvauth.lo \
+@KRB4_TRUE@send_to_kdc.lo sendauth.lo set_default_realm.lo \
+@KRB4_TRUE@sock_principal.lo store.lo store_emem.lo store_fd.lo \
+@KRB4_TRUE@store_mem.lo ticket.lo time.lo transited.lo verify_init.lo \
+@KRB4_TRUE@verify_user.lo version.lo warn.lo write_message.lo \
+@KRB4_TRUE@krb5_err.lo heim_err.lo
+@KRB4_FALSE@libkrb5_la_OBJECTS = add_et_list.lo addr_families.lo \
+@KRB4_FALSE@address.lo aname_to_localname.lo asn1_glue.lo \
+@KRB4_FALSE@auth_context.lo build_ap_req.lo build_auth.lo cache.lo \
+@KRB4_FALSE@changepw.lo codec.lo config_file.lo config_file_netinfo.lo \
+@KRB4_FALSE@convert_creds.lo constants.lo context.lo copy_host_realm.lo \
+@KRB4_FALSE@crc.lo creds.lo crypto.lo data.lo expand_hostname.lo \
+@KRB4_FALSE@fcache.lo free.lo free_host_realm.lo generate_seq_number.lo \
+@KRB4_FALSE@generate_subkey.lo get_addrs.lo get_cred.lo \
+@KRB4_FALSE@get_default_principal.lo get_default_realm.lo \
+@KRB4_FALSE@get_for_creds.lo get_host_realm.lo get_in_tkt.lo \
+@KRB4_FALSE@get_in_tkt_pw.lo get_in_tkt_with_keytab.lo \
+@KRB4_FALSE@get_in_tkt_with_skey.lo get_port.lo init_creds.lo \
+@KRB4_FALSE@init_creds_pw.lo keyblock.lo keytab.lo keytab_file.lo \
+@KRB4_FALSE@keytab_memory.lo keytab_keyfile.lo krbhst.lo kuserok.lo \
+@KRB4_FALSE@log.lo mcache.lo misc.lo mk_error.lo mk_priv.lo mk_rep.lo \
+@KRB4_FALSE@mk_req.lo mk_req_ext.lo mk_safe.lo net_read.lo net_write.lo \
+@KRB4_FALSE@n-fold.lo padata.lo principal.lo prog_setup.lo \
+@KRB4_FALSE@prompter_posix.lo rd_cred.lo rd_error.lo rd_priv.lo \
+@KRB4_FALSE@rd_rep.lo rd_req.lo rd_safe.lo read_message.lo recvauth.lo \
+@KRB4_FALSE@send_to_kdc.lo sendauth.lo set_default_realm.lo \
+@KRB4_FALSE@sock_principal.lo store.lo store_emem.lo store_fd.lo \
+@KRB4_FALSE@store_mem.lo ticket.lo time.lo transited.lo verify_init.lo \
+@KRB4_FALSE@verify_user.lo version.lo warn.lo write_message.lo \
+@KRB4_FALSE@krb5_err.lo heim_err.lo
+bin_PROGRAMS = verify_krb5_conf$(EXEEXT)
+check_PROGRAMS = n-fold-test$(EXEEXT) string-to-key-test$(EXEEXT)
+noinst_PROGRAMS = dump_config$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+
+verify_krb5_conf_SOURCES = verify_krb5_conf.c
+verify_krb5_conf_OBJECTS = verify_krb5_conf.$(OBJEXT)
+verify_krb5_conf_LDADD = $(LDADD)
+@KRB4_TRUE@verify_krb5_conf_DEPENDENCIES = libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@verify_krb5_conf_DEPENDENCIES = libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+verify_krb5_conf_LDFLAGS =
+n_fold_test_SOURCES = n-fold-test.c
+n_fold_test_OBJECTS = n-fold-test.$(OBJEXT)
+n_fold_test_LDADD = $(LDADD)
+@KRB4_TRUE@n_fold_test_DEPENDENCIES = libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@n_fold_test_DEPENDENCIES = libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+n_fold_test_LDFLAGS =
+string_to_key_test_SOURCES = string-to-key-test.c
+string_to_key_test_OBJECTS = string-to-key-test.$(OBJEXT)
+string_to_key_test_LDADD = $(LDADD)
+@KRB4_TRUE@string_to_key_test_DEPENDENCIES = libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@string_to_key_test_DEPENDENCIES = libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+string_to_key_test_LDFLAGS =
+dump_config_SOURCES = dump_config.c
+dump_config_OBJECTS = dump_config.$(OBJEXT)
+dump_config_LDADD = $(LDADD)
+@KRB4_TRUE@dump_config_DEPENDENCIES = libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@dump_config_DEPENDENCIES = libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+dump_config_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man3dir = $(mandir)/man3
+man5dir = $(mandir)/man5
+MANS = $(man_MANS)
+HEADERS = $(include_HEADERS)
+
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libkrb5_la_SOURCES) $(EXTRA_libkrb5_la_SOURCES) verify_krb5_conf.c n-fold-test.c string-to-key-test.c dump_config.c
+OBJECTS = $(libkrb5_la_OBJECTS) verify_krb5_conf.$(OBJEXT) n-fold-test.$(OBJEXT) string-to-key-test.$(OBJEXT) dump_config.$(OBJEXT)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/krb5/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libkrb5.la: $(libkrb5_la_OBJECTS) $(libkrb5_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libkrb5_la_LDFLAGS) $(libkrb5_la_OBJECTS) $(libkrb5_la_LIBADD) $(LIBS)
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-checkPROGRAMS:
+
+clean-checkPROGRAMS:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+
+distclean-checkPROGRAMS:
+
+maintainer-clean-checkPROGRAMS:
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+verify_krb5_conf$(EXEEXT): $(verify_krb5_conf_OBJECTS) $(verify_krb5_conf_DEPENDENCIES)
+ @rm -f verify_krb5_conf$(EXEEXT)
+ $(LINK) $(verify_krb5_conf_LDFLAGS) $(verify_krb5_conf_OBJECTS) $(verify_krb5_conf_LDADD) $(LIBS)
+
+n-fold-test$(EXEEXT): $(n_fold_test_OBJECTS) $(n_fold_test_DEPENDENCIES)
+ @rm -f n-fold-test$(EXEEXT)
+ $(LINK) $(n_fold_test_LDFLAGS) $(n_fold_test_OBJECTS) $(n_fold_test_LDADD) $(LIBS)
+
+string-to-key-test$(EXEEXT): $(string_to_key_test_OBJECTS) $(string_to_key_test_DEPENDENCIES)
+ @rm -f string-to-key-test$(EXEEXT)
+ $(LINK) $(string_to_key_test_LDFLAGS) $(string_to_key_test_OBJECTS) $(string_to_key_test_LDADD) $(LIBS)
+
+dump_config$(EXEEXT): $(dump_config_OBJECTS) $(dump_config_DEPENDENCIES)
+ @rm -f dump_config$(EXEEXT)
+ $(LINK) $(dump_config_LDFLAGS) $(dump_config_OBJECTS) $(dump_config_LDADD) $(LIBS)
+
+install-man3:
+ $(mkinstalldirs) $(DESTDIR)$(man3dir)
+ @list='$(man3_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst; \
+ done
+
+uninstall-man3:
+ @list='$(man3_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man3dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man3dir)/$$inst; \
+ done
+
+install-man5:
+ $(mkinstalldirs) $(DESTDIR)$(man5dir)
+ @list='$(man5_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst; \
+ done
+
+uninstall-man5:
+ @list='$(man5_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man5dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man5dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man3 install-man5
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man3 uninstall-man5
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/krb5
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+check-TESTS: $(TESTS)
+ @failed=0; all=0; \
+ srcdir=$(srcdir); export srcdir; \
+ for tst in $(TESTS); do \
+ if test -f $$tst; then dir=.; \
+ else dir="$(srcdir)"; fi; \
+ if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \
+ all=`expr $$all + 1`; \
+ echo "PASS: $$tst"; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES install-binPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-man install-includeHEADERS install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-binPROGRAMS \
+ uninstall-man uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) \
+ $(DESTDIR)$(mandir)/man3 $(DESTDIR)$(mandir)/man5 \
+ $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-binPROGRAMS \
+ mostlyclean-checkPROGRAMS mostlyclean-noinstPROGRAMS \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \
+ clean-binPROGRAMS clean-checkPROGRAMS \
+ clean-noinstPROGRAMS clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-binPROGRAMS \
+ distclean-checkPROGRAMS distclean-noinstPROGRAMS \
+ distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-binPROGRAMS \
+ maintainer-clean-checkPROGRAMS \
+ maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool mostlyclean-binPROGRAMS distclean-binPROGRAMS \
+clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \
+install-binPROGRAMS mostlyclean-checkPROGRAMS distclean-checkPROGRAMS \
+clean-checkPROGRAMS maintainer-clean-checkPROGRAMS \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS install-man3 \
+uninstall-man3 install-man5 uninstall-man5 install-man uninstall-man \
+uninstall-includeHEADERS install-includeHEADERS tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir check-TESTS \
+info-am info dvi-am dvi check-local check check-am installcheck-am \
+installcheck install-exec-am install-exec install-data-local \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-local all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+$(libkrb5_la_OBJECTS): $(srcdir)/krb5-protos.h $(srcdir)/krb5-private.h
+
+$(srcdir)/krb5-protos.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -o krb5-protos.h $(libkrb5_la_SOURCES) || rm -f krb5-protos.h
+
+$(srcdir)/krb5-private.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -p krb5-private.h $(libkrb5_la_SOURCES) || rm -f krb5-private.h
+
+$(libkrb5_la_OBJECTS): krb5_err.h heim_err.h
+
+# to help stupid solaris make
+
+krb5_err.h: krb5_err.et
+
+heim_err.h: heim_err.et
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/krb5/add_et_list.c b/crypto/heimdal/lib/krb5/add_et_list.c
new file mode 100644
index 000000000000..cfc42f493ca9
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/add_et_list.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: add_et_list.c,v 1.2 1999/12/02 17:05:07 joda Exp $");
+
+/*
+ * Add a specified list of error messages to the et list in context.
+ * Call func (probably a comerr-generated function) with a pointer to
+ * the current et_list.
+ */
+
+krb5_error_code
+krb5_add_et_list (krb5_context context,
+ void (*func)(struct et_list **))
+{
+ (*func)(&context->et_list);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/addr_families.c b/crypto/heimdal/lib/krb5/addr_families.c
new file mode 100644
index 000000000000..e8214ba7f212
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/addr_families.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: addr_families.c,v 1.22 1999/12/04 17:53:33 assar Exp $");
+
+struct addr_operations {
+ int af;
+ krb5_address_type atype;
+ size_t max_sockaddr_size;
+ krb5_error_code (*sockaddr2addr)(const struct sockaddr *, krb5_address *);
+ krb5_error_code (*sockaddr2port)(const struct sockaddr *, int16_t *);
+ void (*addr2sockaddr)(const krb5_address *, struct sockaddr *,
+ int *sa_size, int port);
+ void (*h_addr2sockaddr)(const char *, struct sockaddr *, int *, int);
+ krb5_error_code (*h_addr2addr)(const char *, krb5_address *);
+ krb5_boolean (*uninteresting)(const struct sockaddr *);
+ void (*anyaddr)(struct sockaddr *, int *, int);
+ int (*print_addr)(const krb5_address *, char *, size_t);
+ int (*parse_addr)(const char*, krb5_address *);
+};
+
+/*
+ * AF_INET - aka IPv4 implementation
+ */
+
+static krb5_error_code
+ipv4_sockaddr2addr (const struct sockaddr *sa, krb5_address *a)
+{
+ const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
+ unsigned char buf[4];
+
+ a->addr_type = KRB5_ADDRESS_INET;
+ memcpy (buf, &sin->sin_addr, 4);
+ return krb5_data_copy(&a->address, buf, 4);
+}
+
+static krb5_error_code
+ipv4_sockaddr2port (const struct sockaddr *sa, int16_t *port)
+{
+ const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
+
+ *port = sin->sin_port;
+ return 0;
+}
+
+static void
+ipv4_addr2sockaddr (const krb5_address *a,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port)
+{
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ memset (sin, 0, sizeof(*sin));
+ sin->sin_family = AF_INET;
+ memcpy (&sin->sin_addr, a->address.data, 4);
+ sin->sin_port = port;
+ *sa_size = sizeof(*sin);
+}
+
+static void
+ipv4_h_addr2sockaddr(const char *addr,
+ struct sockaddr *sa, int *sa_size, int port)
+{
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ memset (sin, 0, sizeof(*sin));
+ *sa_size = sizeof(*sin);
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ sin->sin_addr = *((const struct in_addr *)addr);
+}
+
+static krb5_error_code
+ipv4_h_addr2addr (const char *addr,
+ krb5_address *a)
+{
+ unsigned char buf[4];
+
+ a->addr_type = KRB5_ADDRESS_INET;
+ memcpy(buf, addr, 4);
+ return krb5_data_copy(&a->address, buf, 4);
+}
+
+/*
+ * Are there any addresses that should be considered `uninteresting'?
+ */
+
+static krb5_boolean
+ipv4_uninteresting (const struct sockaddr *sa)
+{
+ const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
+
+ if (sin->sin_addr.s_addr == INADDR_ANY)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+ipv4_anyaddr (struct sockaddr *sa, int *sa_size, int port)
+{
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ memset (sin, 0, sizeof(*sin));
+ *sa_size = sizeof(*sin);
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ sin->sin_addr.s_addr = INADDR_ANY;
+}
+
+static int
+ipv4_print_addr (const krb5_address *addr, char *str, size_t len)
+{
+ struct in_addr ia;
+
+ memcpy (&ia, addr->address.data, 4);
+
+ return snprintf (str, len, "IPv4:%s", inet_ntoa(ia));
+}
+
+static int
+ipv4_parse_addr (const char *address, krb5_address *addr)
+{
+ const char *p;
+ struct in_addr a;
+
+ p = strchr(address, ':');
+ if(p) {
+ p++;
+ if(strncasecmp(address, "ip:", p - address) != 0 &&
+ strncasecmp(address, "ip4:", p - address) != 0 &&
+ strncasecmp(address, "ipv4:", p - address) != 0 &&
+ strncasecmp(address, "inet:", p - address) != 0)
+ return -1;
+ } else
+ p = address;
+#ifdef HAVE_INET_ATON
+ if(inet_aton(p, &a) == 0)
+ return -1;
+#elif defined(HAVE_INET_ADDR)
+ a.s_addr = inet_addr(p);
+ if(a.s_addr == INADDR_NONE)
+ return -1;
+#else
+ return -1;
+#endif
+ addr->addr_type = KRB5_ADDRESS_INET;
+ if(krb5_data_alloc(&addr->address, 4) != 0)
+ return -1;
+ _krb5_put_int(addr->address.data, ntohl(a.s_addr), addr->address.length);
+ return 0;
+}
+
+/*
+ * AF_INET6 - aka IPv6 implementation
+ */
+
+#ifdef HAVE_IPV6
+
+static krb5_error_code
+ipv6_sockaddr2addr (const struct sockaddr *sa, krb5_address *a)
+{
+ const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+
+ if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
+ unsigned char buf[4];
+
+ a->addr_type = KRB5_ADDRESS_INET;
+#ifndef IN6_ADDR_V6_TO_V4
+#ifdef IN6_EXTRACT_V4ADDR
+#define IN6_ADDR_V6_TO_V4(x) (&IN6_EXTRACT_V4ADDR(x))
+#else
+#define IN6_ADDR_V6_TO_V4(x) ((const struct in_addr *)&(x)->s6_addr[12])
+#endif
+#endif
+ memcpy (buf, IN6_ADDR_V6_TO_V4(&sin6->sin6_addr), 4);
+ return krb5_data_copy(&a->address, buf, 4);
+ } else {
+ a->addr_type = KRB5_ADDRESS_INET6;
+ return krb5_data_copy(&a->address,
+ &sin6->sin6_addr,
+ sizeof(sin6->sin6_addr));
+ }
+}
+
+static krb5_error_code
+ipv6_sockaddr2port (const struct sockaddr *sa, int16_t *port)
+{
+ const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+
+ *port = sin6->sin6_port;
+ return 0;
+}
+
+static void
+ipv6_addr2sockaddr (const krb5_address *a,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port)
+{
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ memset (sin6, 0, sizeof(*sin6));
+ sin6->sin6_family = AF_INET6;
+ memcpy (&sin6->sin6_addr, a->address.data, sizeof(sin6->sin6_addr));
+ sin6->sin6_port = port;
+ *sa_size = sizeof(*sin6);
+}
+
+static void
+ipv6_h_addr2sockaddr(const char *addr,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port)
+{
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ memset (sin6, 0, sizeof(*sin6));
+ *sa_size = sizeof(*sin6);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = port;
+ sin6->sin6_addr = *((const struct in6_addr *)addr);
+}
+
+static krb5_error_code
+ipv6_h_addr2addr (const char *addr,
+ krb5_address *a)
+{
+ a->addr_type = KRB5_ADDRESS_INET6;
+ return krb5_data_copy(&a->address, addr, sizeof(struct in6_addr));
+}
+
+/*
+ *
+ */
+
+static krb5_boolean
+ipv6_uninteresting (const struct sockaddr *sa)
+{
+ const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+ const struct in6_addr *in6 = (const struct in6_addr *)&sin6->sin6_addr;
+
+ return
+ IN6_IS_ADDR_LINKLOCAL(in6)
+ || IN6_IS_ADDR_V4COMPAT(in6);
+}
+
+static void
+ipv6_anyaddr (struct sockaddr *sa, int *sa_size, int port)
+{
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ memset (sin6, 0, sizeof(*sin6));
+ *sa_size = sizeof(*sin6);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = port;
+ sin6->sin6_addr = in6addr_any;
+}
+
+static int
+ipv6_print_addr (const krb5_address *addr, char *str, size_t len)
+{
+ char buf[128], buf2[3];
+#ifdef HAVE_INET_NTOP
+ if(inet_ntop(AF_INET6, addr->address.data, buf, sizeof(buf)) == NULL)
+#endif
+ {
+ /* XXX this is pretty ugly, but better than abort() */
+ int i;
+ unsigned char *p = addr->address.data;
+ buf[0] = '\0';
+ for(i = 0; i < addr->address.length; i++) {
+ snprintf(buf2, sizeof(buf2), "%02x", p[i]);
+ if(i > 0 && (i & 1) == 0)
+ strlcat(buf, ":", sizeof(buf));
+ strlcat(buf, buf2, sizeof(buf));
+ }
+ }
+ return snprintf(str, len, "IPv6:%s", buf);
+}
+
+static int
+ipv6_parse_addr (const char *address, krb5_address *addr)
+{
+ int ret;
+ struct in6_addr in6;
+
+ ret = inet_pton(AF_INET6, address, &in6.s6_addr);
+ if(ret == 1) {
+ addr->addr_type = KRB5_ADDRESS_INET6;
+ ret = krb5_data_alloc(&addr->address, sizeof(in6.s6_addr));
+ if (ret)
+ return -1;
+ memcpy(addr->address.data, in6.s6_addr, sizeof(in6.s6_addr));
+ return 0;
+ }
+ return -1;
+}
+
+#endif /* IPv6 */
+
+/*
+ * table
+ */
+
+static struct addr_operations at[] = {
+ {AF_INET, KRB5_ADDRESS_INET, sizeof(struct sockaddr_in),
+ ipv4_sockaddr2addr,
+ ipv4_sockaddr2port,
+ ipv4_addr2sockaddr,
+ ipv4_h_addr2sockaddr,
+ ipv4_h_addr2addr,
+ ipv4_uninteresting, ipv4_anyaddr, ipv4_print_addr, ipv4_parse_addr},
+#ifdef HAVE_IPV6
+ {AF_INET6, KRB5_ADDRESS_INET6, sizeof(struct sockaddr_in6),
+ ipv6_sockaddr2addr,
+ ipv6_sockaddr2port,
+ ipv6_addr2sockaddr,
+ ipv6_h_addr2sockaddr,
+ ipv6_h_addr2addr,
+ ipv6_uninteresting, ipv6_anyaddr, ipv6_print_addr, ipv6_parse_addr}
+#endif
+};
+
+static int num_addrs = sizeof(at) / sizeof(at[0]);
+
+static size_t max_sockaddr_size = 0;
+
+/*
+ * generic functions
+ */
+
+static struct addr_operations *
+find_af(int af)
+{
+ struct addr_operations *a;
+
+ for (a = at; a < at + num_addrs; ++a)
+ if (af == a->af)
+ return a;
+ return NULL;
+}
+
+static struct addr_operations *
+find_atype(int atype)
+{
+ struct addr_operations *a;
+
+ for (a = at; a < at + num_addrs; ++a)
+ if (atype == a->atype)
+ return a;
+ return NULL;
+}
+
+krb5_error_code
+krb5_sockaddr2address (const struct sockaddr *sa, krb5_address *addr)
+{
+ struct addr_operations *a = find_af(sa->sa_family);
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+ return (*a->sockaddr2addr)(sa, addr);
+}
+
+krb5_error_code
+krb5_sockaddr2port (const struct sockaddr *sa, int16_t *port)
+{
+ struct addr_operations *a = find_af(sa->sa_family);
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+ return (*a->sockaddr2port)(sa, port);
+}
+
+krb5_error_code
+krb5_addr2sockaddr (const krb5_address *addr,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port)
+{
+ struct addr_operations *a = find_atype(addr->addr_type);
+
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+ (*a->addr2sockaddr)(addr, sa, sa_size, port);
+ return 0;
+}
+
+size_t
+krb5_max_sockaddr_size (void)
+{
+ if (max_sockaddr_size == 0) {
+ struct addr_operations *a;
+
+ for(a = at; a < at + num_addrs; ++a)
+ max_sockaddr_size = max(max_sockaddr_size, a->max_sockaddr_size);
+ }
+ return max_sockaddr_size;
+}
+
+krb5_boolean
+krb5_sockaddr_uninteresting(const struct sockaddr *sa)
+{
+ struct addr_operations *a = find_af(sa->sa_family);
+ if (a == NULL)
+ return TRUE;
+ return (*a->uninteresting)(sa);
+}
+
+krb5_error_code
+krb5_h_addr2sockaddr (int af,
+ const char *addr, struct sockaddr *sa, int *sa_size,
+ int port)
+{
+ struct addr_operations *a = find_af(af);
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+ (*a->h_addr2sockaddr)(addr, sa, sa_size, port);
+ return 0;
+}
+
+krb5_error_code
+krb5_h_addr2addr (int af,
+ const char *haddr, krb5_address *addr)
+{
+ struct addr_operations *a = find_af(af);
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+ return (*a->h_addr2addr)(haddr, addr);
+}
+
+krb5_error_code
+krb5_anyaddr (int af,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port)
+{
+ struct addr_operations *a = find_af (af);
+
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+
+ (*a->anyaddr)(sa, sa_size, port);
+ return 0;
+}
+
+krb5_error_code
+krb5_print_address (const krb5_address *addr,
+ char *str, size_t len, size_t *ret_len)
+{
+ struct addr_operations *a = find_atype(addr->addr_type);
+
+ if (a == NULL) {
+ char *s;
+ size_t l;
+ int i;
+ s = str;
+ l = snprintf(s, len, "TYPE_%d:", addr->addr_type);
+ s += l;
+ len -= len;
+ for(i = 0; i < addr->address.length; i++) {
+ l = snprintf(s, len, "%02x", ((char*)addr->address.data)[i]);
+ len -= l;
+ s += l;
+ }
+ *ret_len = s - str;
+ return 0;
+ }
+ *ret_len = (*a->print_addr)(addr, str, len);
+ return 0;
+}
+
+krb5_error_code
+krb5_parse_address(krb5_context context,
+ const char *string,
+ krb5_addresses *addresses)
+{
+ int i, n;
+ struct addrinfo *ai, *a;
+ int error;
+
+ for(i = 0; i < num_addrs; i++) {
+ if(at[i].parse_addr) {
+ krb5_address a;
+ if((*at[i].parse_addr)(string, &a) == 0) {
+ ALLOC_SEQ(addresses, 1);
+ addresses->val[0] = a;
+ return 0;
+ }
+ }
+ }
+
+ error = getaddrinfo (string, NULL, NULL, &ai);
+ if (error)
+ return -1;
+
+ n = 0;
+ for (a = ai; a != NULL; a = a->ai_next)
+ ++n;
+
+ ALLOC_SEQ(addresses, n);
+
+ for (a = ai, i = 0; a != NULL; a = a->ai_next, ++i) {
+ struct addr_operations *aop = find_af (ai->ai_family);
+
+ addresses->val[i].addr_type = aop->atype;
+ krb5_data_copy (&addresses->val[i].address,
+ ai->ai_addr,
+ ai->ai_addrlen);
+ }
+ freeaddrinfo (ai);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/address.c b/crypto/heimdal/lib/krb5/address.c
new file mode 100644
index 000000000000..8b0704f6e1ea
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/address.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: address.c,v 1.14 1999/12/02 17:05:07 joda Exp $");
+
+#if 0
+/* This is the supposedly MIT-api version */
+
+krb5_boolean
+krb5_address_search(krb5_context context,
+ const krb5_address *addr,
+ krb5_address *const *addrlist)
+{
+ krb5_address *a;
+
+ while((a = *addrlist++))
+ if (krb5_address_compare (context, addr, a))
+ return TRUE;
+ return FALSE;
+}
+#endif
+
+krb5_boolean
+krb5_address_search(krb5_context context,
+ const krb5_address *addr,
+ const krb5_addresses *addrlist)
+{
+ int i;
+
+ for (i = 0; i < addrlist->len; ++i)
+ if (krb5_address_compare (context, addr, &addrlist->val[i]))
+ return TRUE;
+ return FALSE;
+}
+
+int
+krb5_address_order(krb5_context context,
+ const krb5_address *addr1,
+ const krb5_address *addr2)
+{
+ return (addr1->addr_type - addr2->addr_type)
+ || memcmp (addr1->address.data,
+ addr2->address.data,
+ addr1->address.length);
+}
+
+krb5_boolean
+krb5_address_compare(krb5_context context,
+ const krb5_address *addr1,
+ const krb5_address *addr2)
+{
+ return krb5_address_order (context, addr1, addr2) == 0;
+}
+
+krb5_error_code
+krb5_copy_address(krb5_context context,
+ const krb5_address *inaddr,
+ krb5_address *outaddr)
+{
+ copy_HostAddress(inaddr, outaddr);
+ return 0;
+}
+
+krb5_error_code
+krb5_copy_addresses(krb5_context context,
+ const krb5_addresses *inaddr,
+ krb5_addresses *outaddr)
+{
+ copy_HostAddresses(inaddr, outaddr);
+ return 0;
+}
+
+krb5_error_code
+krb5_free_address(krb5_context context,
+ krb5_address *address)
+{
+ krb5_data_free (&address->address);
+ return 0;
+}
+
+krb5_error_code
+krb5_free_addresses(krb5_context context,
+ krb5_addresses *addresses)
+{
+ free_HostAddresses(addresses);
+ return 0;
+}
+
+krb5_error_code
+krb5_append_addresses(krb5_context context,
+ krb5_addresses *dest,
+ const krb5_addresses *source)
+{
+ krb5_address *tmp;
+ krb5_error_code ret;
+ int i;
+ if(source->len > 0) {
+ tmp = realloc(dest->val, (dest->len + source->len) * sizeof(*tmp));
+ if(tmp == NULL)
+ return ENOMEM;
+ dest->val = tmp;
+ for(i = 0; i < source->len; i++) {
+ /* skip duplicates */
+ if(krb5_address_search(context, &source->val[i], dest))
+ continue;
+ ret = krb5_copy_address(context,
+ &source->val[i],
+ &dest->val[dest->len]);
+ if(ret)
+ return ret;
+ dest->len++;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Create an address of type KRB5_ADDRESS_ADDRPORT from (addr, port)
+ */
+
+krb5_error_code
+krb5_make_addrport (krb5_address **res, const krb5_address *addr, int16_t port)
+{
+ krb5_error_code ret;
+ size_t len = addr->address.length + 2 + 4 * 4;
+ u_char *p;
+
+ *res = malloc (sizeof(**res));
+ if (*res == NULL)
+ return ENOMEM;
+ (*res)->addr_type = KRB5_ADDRESS_ADDRPORT;
+ ret = krb5_data_alloc (&(*res)->address, len);
+ if (ret) {
+ free (*res);
+ return ret;
+ }
+ p = (*res)->address.data;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = (addr->addr_type ) & 0xFF;
+ *p++ = (addr->addr_type >> 8) & 0xFF;
+
+ *p++ = (addr->address.length ) & 0xFF;
+ *p++ = (addr->address.length >> 8) & 0xFF;
+ *p++ = (addr->address.length >> 16) & 0xFF;
+ *p++ = (addr->address.length >> 24) & 0xFF;
+
+ memcpy (p, addr->address.data, addr->address.length);
+ p += addr->address.length;
+
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = (KRB5_ADDRESS_IPPORT ) & 0xFF;
+ *p++ = (KRB5_ADDRESS_IPPORT >> 8) & 0xFF;
+
+ *p++ = (2 ) & 0xFF;
+ *p++ = (2 >> 8) & 0xFF;
+ *p++ = (2 >> 16) & 0xFF;
+ *p++ = (2 >> 24) & 0xFF;
+
+ memcpy (p, &port, 2);
+ p += 2;
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/aname_to_localname.c b/crypto/heimdal/lib/krb5/aname_to_localname.c
new file mode 100644
index 000000000000..c125580a7c13
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/aname_to_localname.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: aname_to_localname.c,v 1.3 1999/12/02 17:05:07 joda Exp $");
+
+krb5_error_code
+krb5_aname_to_localname (krb5_context context,
+ krb5_const_principal aname,
+ size_t lnsize,
+ char *lname)
+{
+ krb5_error_code ret;
+ krb5_realm *lrealms, *r;
+ int foo = 1;
+ size_t len;
+ char *res;
+
+ ret = krb5_get_default_realms (context, &lrealms);
+ if (ret)
+ return ret;
+
+ for (r = lrealms; *r != NULL; ++r) {
+ foo = strcmp (*r, aname->realm);
+ if (foo == 0)
+ break;
+ }
+ krb5_free_host_realm (context, lrealms);
+ if (foo != 0)
+ return KRB5_NO_LOCALNAME;
+
+ if (aname->name.name_string.len == 1)
+ res = aname->name.name_string.val[0];
+ else if (aname->name.name_string.len == 2
+ && strcmp (aname->name.name_string.val[1], "root") == 0)
+ res = "root";
+ else
+ return KRB5_NO_LOCALNAME;
+
+ len = strlen (res);
+ if (len >= lnsize)
+ return ERANGE;
+ strcpy (lname, res);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/asn1_glue.c b/crypto/heimdal/lib/krb5/asn1_glue.c
new file mode 100644
index 000000000000..ac83ff78bdce
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/asn1_glue.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/*
+ *
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: asn1_glue.c,v 1.7 1999/12/02 17:05:07 joda Exp $");
+
+krb5_error_code
+krb5_principal2principalname (PrincipalName *p,
+ const krb5_principal from)
+{
+ return copy_PrincipalName(&from->name, p);
+}
+
+krb5_error_code
+principalname2krb5_principal (krb5_principal *principal,
+ const PrincipalName from,
+ const Realm realm)
+{
+ krb5_principal p = malloc(sizeof(*p));
+ copy_PrincipalName(&from, &p->name);
+ p->realm = strdup(realm);
+ *principal = p;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/auth_context.c b/crypto/heimdal/lib/krb5/auth_context.c
new file mode 100644
index 000000000000..94b1376297a6
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/auth_context.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: auth_context.c,v 1.50 1999/12/02 17:05:07 joda Exp $");
+
+krb5_error_code
+krb5_auth_con_init(krb5_context context,
+ krb5_auth_context *auth_context)
+{
+ krb5_auth_context p;
+
+ ALLOC(p, 1);
+ if(!p)
+ return ENOMEM;
+ memset(p, 0, sizeof(*p));
+ ALLOC(p->authenticator, 1);
+ if (!p->authenticator) {
+ free(p);
+ return ENOMEM;
+ }
+ memset (p->authenticator, 0, sizeof(*p->authenticator));
+ p->flags = KRB5_AUTH_CONTEXT_DO_TIME;
+
+ p->local_address = NULL;
+ p->remote_address = NULL;
+ p->local_port = 0;
+ p->remote_port = 0;
+ p->keytype = KEYTYPE_NULL;
+ p->cksumtype = CKSUMTYPE_NONE;
+ *auth_context = p;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_con_free(krb5_context context,
+ krb5_auth_context auth_context)
+{
+ krb5_free_authenticator(context, &auth_context->authenticator);
+ if(auth_context->local_address){
+ free_HostAddress(auth_context->local_address);
+ free(auth_context->local_address);
+ }
+ if(auth_context->remote_address){
+ free_HostAddress(auth_context->remote_address);
+ free(auth_context->remote_address);
+ }
+ if(auth_context->keyblock)
+ krb5_free_keyblock(context, auth_context->keyblock);
+ krb5_free_keyblock(context, auth_context->remote_subkey);
+ krb5_free_keyblock(context, auth_context->local_subkey);
+ free (auth_context);
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_con_setflags(krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t flags)
+{
+ auth_context->flags = flags;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_auth_con_getflags(krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *flags)
+{
+ *flags = auth_context->flags;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_auth_con_setaddrs(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_address *local_addr,
+ krb5_address *remote_addr)
+{
+ if (local_addr) {
+ if (auth_context->local_address)
+ krb5_free_address (context, auth_context->local_address);
+ else
+ auth_context->local_address = malloc(sizeof(krb5_address));
+ krb5_copy_address(context, local_addr, auth_context->local_address);
+ }
+ if (remote_addr) {
+ if (auth_context->remote_address)
+ krb5_free_address (context, auth_context->remote_address);
+ else
+ auth_context->remote_address = malloc(sizeof(krb5_address));
+ krb5_copy_address(context, remote_addr, auth_context->remote_address);
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_con_setaddrs_from_fd (krb5_context context,
+ krb5_auth_context auth_context,
+ void *p_fd)
+{
+ int fd = *((int *)p_fd);
+ krb5_error_code ret;
+ krb5_address local_k_address, remote_k_address;
+ krb5_address *lptr = NULL, *rptr = NULL;
+ struct sockaddr_storage ss_local, ss_remote;
+ struct sockaddr *local = (struct sockaddr *)&ss_local;
+ struct sockaddr *remote = (struct sockaddr *)&ss_remote;
+ int len;
+
+ if (auth_context->local_address == NULL) {
+ len = sizeof(ss_local);
+ if(getsockname(fd, local, &len) < 0) {
+ ret = errno;
+ goto out;
+ }
+ krb5_sockaddr2address (local, &local_k_address);
+ krb5_sockaddr2port (local, &auth_context->local_port);
+ lptr = &local_k_address;
+ }
+ if (auth_context->remote_address == NULL) {
+ len = sizeof(ss_remote);
+ if(getpeername(fd, remote, &len) < 0) {
+ ret = errno;
+ goto out;
+ }
+ krb5_sockaddr2address (remote, &remote_k_address);
+ krb5_sockaddr2port (remote, &auth_context->remote_port);
+ rptr = &remote_k_address;
+ }
+ ret = krb5_auth_con_setaddrs (context,
+ auth_context,
+ lptr,
+ rptr);
+out:
+ if (lptr)
+ krb5_free_address (context, lptr);
+ if (rptr)
+ krb5_free_address (context, rptr);
+ return ret;
+}
+
+krb5_error_code
+krb5_auth_con_getaddrs(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_address **local_addr,
+ krb5_address **remote_addr)
+{
+ if(*local_addr)
+ krb5_free_address (context, *local_addr);
+ *local_addr = malloc (sizeof(**local_addr));
+ if (*local_addr == NULL)
+ return ENOMEM;
+ krb5_copy_address(context,
+ auth_context->local_address,
+ *local_addr);
+
+ if(*remote_addr)
+ krb5_free_address (context, *remote_addr);
+ *remote_addr = malloc (sizeof(**remote_addr));
+ if (*remote_addr == NULL)
+ return ENOMEM;
+ krb5_copy_address(context,
+ auth_context->remote_address,
+ *remote_addr);
+ return 0;
+}
+
+static krb5_error_code
+copy_key(krb5_context context,
+ krb5_keyblock *in,
+ krb5_keyblock **out)
+{
+ if(in)
+ return krb5_copy_keyblock(context, in, out);
+ *out = NULL; /* is this right? */
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_con_getkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock)
+{
+ return copy_key(context, auth_context->keyblock, keyblock);
+}
+
+krb5_error_code
+krb5_auth_con_getlocalsubkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock)
+{
+ return copy_key(context, auth_context->local_subkey, keyblock);
+}
+
+krb5_error_code
+krb5_auth_con_getremotesubkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock)
+{
+ return copy_key(context, auth_context->remote_subkey, keyblock);
+}
+
+krb5_error_code
+krb5_auth_con_setkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock)
+{
+ if(auth_context->keyblock)
+ krb5_free_keyblock(context, auth_context->keyblock);
+ return copy_key(context, keyblock, &auth_context->keyblock);
+}
+
+krb5_error_code
+krb5_auth_con_setlocalsubkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock)
+{
+ if(auth_context->local_subkey)
+ krb5_free_keyblock(context, auth_context->local_subkey);
+ return copy_key(context, keyblock, &auth_context->local_subkey);
+}
+
+krb5_error_code
+krb5_auth_con_setremotesubkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock)
+{
+ if(auth_context->remote_subkey)
+ krb5_free_keyblock(context, auth_context->remote_subkey);
+ return copy_key(context, keyblock, &auth_context->remote_subkey);
+}
+
+krb5_error_code
+krb5_auth_setcksumtype(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_cksumtype cksumtype)
+{
+ auth_context->cksumtype = cksumtype;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_getcksumtype(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_cksumtype *cksumtype)
+{
+ *cksumtype = auth_context->cksumtype;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_setkeytype (krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keytype keytype)
+{
+ auth_context->keytype = keytype;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_getkeytype (krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keytype *keytype)
+{
+ *keytype = auth_context->keytype;
+ return 0;
+}
+
+#if 0
+krb5_error_code
+krb5_auth_setenctype(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_enctype etype)
+{
+ if(auth_context->keyblock)
+ krb5_free_keyblock(context, auth_context->keyblock);
+ ALLOC(auth_context->keyblock, 1);
+ if(auth_context->keyblock == NULL)
+ return ENOMEM;
+ auth_context->keyblock->keytype = etype;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_getenctype(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_enctype *etype)
+{
+ krb5_abortx(context, "unimplemented krb5_auth_getenctype called");
+}
+#endif
+
+krb5_error_code
+krb5_auth_getlocalseqnumber(krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *seqnumber)
+{
+ *seqnumber = auth_context->local_seqnumber;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_setlocalseqnumber (krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t seqnumber)
+{
+ auth_context->local_seqnumber = seqnumber;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_getremoteseqnumber(krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *seqnumber)
+{
+ *seqnumber = auth_context->remote_seqnumber;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_setremoteseqnumber (krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t seqnumber)
+{
+ auth_context->remote_seqnumber = seqnumber;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_auth_getauthenticator(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_authenticator *authenticator)
+{
+ *authenticator = malloc(sizeof(**authenticator));
+ if (*authenticator == NULL)
+ return ENOMEM;
+
+ copy_Authenticator(auth_context->authenticator,
+ *authenticator);
+ return 0;
+}
+
+
+void
+krb5_free_authenticator(krb5_context context,
+ krb5_authenticator *authenticator)
+{
+ free_Authenticator (*authenticator);
+ free (*authenticator);
+ *authenticator = NULL;
+}
+
+
+krb5_error_code
+krb5_auth_con_setuserkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock)
+{
+ if(auth_context->keyblock)
+ krb5_free_keyblock(context, auth_context->keyblock);
+ return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock);
+}
+
+#if 0 /* not implemented */
+
+krb5_error_code
+krb5_auth_con_initivector(krb5_context context,
+ krb5_auth_context auth_context)
+{
+ krb5_abortx(context, "unimplemented krb5_auth_con_initivector called");
+}
+
+
+krb5_error_code
+krb5_auth_con_setivector(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_pointer ivector)
+{
+ krb5_abortx(context, "unimplemented krb5_auth_con_setivector called");
+}
+
+
+krb5_error_code
+krb5_auth_con_setrcache(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_rcache rcache)
+{
+ krb5_abortx(context, "unimplemented krb5_auth_con_setrcache called");
+}
+
+#endif /* not implemented */
diff --git a/crypto/heimdal/lib/krb5/build_ap_req.c b/crypto/heimdal/lib/krb5/build_ap_req.c
new file mode 100644
index 000000000000..c8a89caa7e18
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/build_ap_req.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: build_ap_req.c,v 1.16 1999/12/02 17:05:07 joda Exp $");
+
+krb5_error_code
+krb5_build_ap_req (krb5_context context,
+ krb5_enctype enctype,
+ krb5_creds *cred,
+ krb5_flags ap_options,
+ krb5_data authenticator,
+ krb5_data *retdata)
+{
+ krb5_error_code ret = 0;
+ AP_REQ ap;
+ Ticket t;
+ size_t len;
+
+ ap.pvno = 5;
+ ap.msg_type = krb_ap_req;
+ memset(&ap.ap_options, 0, sizeof(ap.ap_options));
+ ap.ap_options.use_session_key = (ap_options & AP_OPTS_USE_SESSION_KEY) > 0;
+ ap.ap_options.mutual_required = (ap_options & AP_OPTS_MUTUAL_REQUIRED) > 0;
+
+ ap.ticket.tkt_vno = 5;
+ copy_Realm(&cred->server->realm, &ap.ticket.realm);
+ copy_PrincipalName(&cred->server->name, &ap.ticket.sname);
+
+ decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len);
+ copy_EncryptedData(&t.enc_part, &ap.ticket.enc_part);
+ free_Ticket(&t);
+
+ ap.authenticator.etype = enctype;
+ ap.authenticator.kvno = NULL;
+ ap.authenticator.cipher = authenticator;
+
+ retdata->length = length_AP_REQ(&ap);
+ retdata->data = malloc(retdata->length);
+ if(retdata->data == NULL)
+ ret = ENOMEM;
+ else
+ encode_AP_REQ((unsigned char *)retdata->data + retdata->length - 1,
+ retdata->length, &ap, &len);
+ free_AP_REQ(&ap);
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/build_auth.c b/crypto/heimdal/lib/krb5/build_auth.c
new file mode 100644
index 000000000000..a38393bbf359
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/build_auth.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: build_auth.c,v 1.32 1999/12/02 17:05:08 joda Exp $");
+
+krb5_error_code
+krb5_build_authenticator (krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_enctype enctype,
+ krb5_creds *cred,
+ Checksum *cksum,
+ Authenticator **auth_result,
+ krb5_data *result)
+{
+ Authenticator *auth;
+ u_char *buf = NULL;
+ size_t buf_size;
+ size_t len;
+ krb5_error_code ret;
+ krb5_crypto crypto;
+
+ auth = malloc(sizeof(*auth));
+ if (auth == NULL)
+ return ENOMEM;
+
+ memset (auth, 0, sizeof(*auth));
+ auth->authenticator_vno = 5;
+ copy_Realm(&cred->client->realm, &auth->crealm);
+ copy_PrincipalName(&cred->client->name, &auth->cname);
+
+ {
+ int32_t sec, usec;
+
+ krb5_us_timeofday (context, &sec, &usec);
+ auth->ctime = sec;
+ auth->cusec = usec;
+ }
+ ret = krb5_auth_con_getlocalsubkey(context, auth_context, &auth->subkey);
+ if(ret)
+ goto fail;
+
+ if(auth->subkey == NULL) {
+ krb5_generate_subkey (context, &cred->session, &auth->subkey);
+ ret = krb5_auth_con_setlocalsubkey(context, auth_context, auth->subkey);
+ if(ret)
+ goto fail;
+ }
+
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ krb5_generate_seq_number (context,
+ &cred->session,
+ &auth_context->local_seqnumber);
+ ALLOC(auth->seq_number, 1);
+ *auth->seq_number = auth_context->local_seqnumber;
+ } else
+ auth->seq_number = NULL;
+ auth->authorization_data = NULL;
+ auth->cksum = cksum;
+
+ /* XXX - Copy more to auth_context? */
+
+ if (auth_context) {
+ auth_context->authenticator->ctime = auth->ctime;
+ auth_context->authenticator->cusec = auth->cusec;
+ }
+
+ buf_size = 1024;
+ buf = malloc (buf_size);
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ do {
+ ret = krb5_encode_Authenticator (context,
+ buf + buf_size - 1,
+ buf_size,
+ auth, &len);
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ buf = tmp;
+ } else {
+ goto fail;
+ }
+ }
+ } while(ret == ASN1_OVERFLOW);
+
+ ret = krb5_crypto_init(context, &cred->session, enctype, &crypto);
+ ret = krb5_encrypt (context,
+ crypto,
+ KRB5_KU_AP_REQ_AUTH,
+ buf + buf_size - len,
+ len,
+ result);
+ krb5_crypto_destroy(context, crypto);
+
+ if (ret)
+ goto fail;
+
+ free (buf);
+
+ if (auth_result)
+ *auth_result = auth;
+ else {
+ /* Don't free the `cksum', it's allocated by the caller */
+ auth->cksum = NULL;
+ free_Authenticator (auth);
+ free (auth);
+ }
+ return ret;
+fail:
+ free_Authenticator (auth);
+ free (auth);
+ free (buf);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/cache.c b/crypto/heimdal/lib/krb5/cache.c
new file mode 100644
index 000000000000..e78d4deb23da
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/cache.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: cache.c,v 1.44 1999/12/02 17:05:08 joda Exp $");
+
+/*
+ * Add a new ccache type with operations `ops', overwriting any
+ * existing one if `override'.
+ * Return an error code or 0.
+ */
+
+krb5_error_code
+krb5_cc_register(krb5_context context,
+ const krb5_cc_ops *ops,
+ krb5_boolean override)
+{
+ int i;
+
+ for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
+ if(strcmp(context->cc_ops[i].prefix, ops->prefix) == 0) {
+ if(override)
+ free(context->cc_ops[i].prefix);
+ else
+ return KRB5_CC_TYPE_EXISTS;
+ }
+ }
+ if(i == context->num_cc_ops) {
+ krb5_cc_ops *o = realloc(context->cc_ops,
+ (context->num_cc_ops + 1) *
+ sizeof(*context->cc_ops));
+ if(o == NULL)
+ return KRB5_CC_NOMEM;
+ context->num_cc_ops++;
+ context->cc_ops = o;
+ memset(context->cc_ops + i, 0,
+ (context->num_cc_ops - i) * sizeof(*context->cc_ops));
+ }
+ memcpy(&context->cc_ops[i], ops, sizeof(context->cc_ops[i]));
+ context->cc_ops[i].prefix = strdup(ops->prefix);
+ if(context->cc_ops[i].prefix == NULL)
+ return KRB5_CC_NOMEM;
+
+ return 0;
+}
+
+/*
+ * Allocate memory for a new ccache in `id' with operations `ops'
+ * and name `residual'.
+ * Return 0 or an error code.
+ */
+
+static krb5_error_code
+allocate_ccache (krb5_context context,
+ const krb5_cc_ops *ops,
+ const char *residual,
+ krb5_ccache *id)
+{
+ krb5_error_code ret;
+ krb5_ccache p;
+
+ p = malloc(sizeof(*p));
+ if(p == NULL)
+ return KRB5_CC_NOMEM;
+ p->ops = ops;
+ *id = p;
+ ret = p->ops->resolve(context, id, residual);
+ if(ret)
+ free(p);
+ return ret;
+}
+
+/*
+ * Find and allocate a ccache in `id' from the specification in `residual'.
+ * If the ccache name doesn't contain any colon, interpret it as a file name.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_resolve(krb5_context context,
+ const char *name,
+ krb5_ccache *id)
+{
+ int i;
+
+ for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
+ size_t prefix_len = strlen(context->cc_ops[i].prefix);
+
+ if(strncmp(context->cc_ops[i].prefix, name, prefix_len) == 0
+ && name[prefix_len] == ':') {
+ return allocate_ccache (context, &context->cc_ops[i],
+ name + prefix_len + 1,
+ id);
+ }
+ }
+ if (strchr (name, ':') == NULL)
+ return allocate_ccache (context, &krb5_fcc_ops, name, id);
+ else
+ return KRB5_CC_UNKNOWN_TYPE;
+}
+
+/*
+ * Generate a new ccache of type `ops' in `id'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_gen_new(krb5_context context,
+ const krb5_cc_ops *ops,
+ krb5_ccache *id)
+{
+ krb5_ccache p;
+
+ p = malloc (sizeof(*p));
+ if (p == NULL)
+ return KRB5_CC_NOMEM;
+ p->ops = ops;
+ *id = p;
+ return p->ops->gen_new(context, id);
+}
+
+/*
+ * Return the name of the ccache `id'
+ */
+
+const char*
+krb5_cc_get_name(krb5_context context,
+ krb5_ccache id)
+{
+ return id->ops->get_name(context, id);
+}
+
+/*
+ * Return the type of the ccache `id'.
+ */
+
+const char*
+krb5_cc_get_type(krb5_context context,
+ krb5_ccache id)
+{
+ return id->ops->prefix;
+}
+
+/*
+ * Return a pointer to a static string containing the default ccache name.
+ */
+
+const char*
+krb5_cc_default_name(krb5_context context)
+{
+ static char name[1024];
+ char *p;
+
+ p = getenv("KRB5CCNAME");
+ if(p)
+ strlcpy (name, p, sizeof(name));
+ else
+ snprintf(name,
+ sizeof(name),
+ "FILE:/tmp/krb5cc_%u",
+ (unsigned)getuid());
+ return name;
+}
+
+/*
+ * Open the default ccache in `id'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_default(krb5_context context,
+ krb5_ccache *id)
+{
+ return krb5_cc_resolve(context,
+ krb5_cc_default_name(context),
+ id);
+}
+
+/*
+ * Create a new ccache in `id' for `primary_principal'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_initialize(krb5_context context,
+ krb5_ccache id,
+ krb5_principal primary_principal)
+{
+ return id->ops->init(context, id, primary_principal);
+}
+
+
+/*
+ * Remove the ccache `id'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_destroy(krb5_context context,
+ krb5_ccache id)
+{
+ krb5_error_code ret;
+
+ ret = id->ops->destroy(context, id);
+ krb5_cc_close (context, id);
+ return ret;
+}
+
+/*
+ * Stop using the ccache `id' and free the related resources.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_close(krb5_context context,
+ krb5_ccache id)
+{
+ krb5_error_code ret;
+ ret = id->ops->close(context, id);
+ free(id);
+ return ret;
+}
+
+/*
+ * Store `creds' in the ccache `id'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_store_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_creds *creds)
+{
+ return id->ops->store(context, id, creds);
+}
+
+/*
+ * Retrieve the credential identified by `mcreds' (and `whichfields')
+ * from `id' in `creds'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_retrieve_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_flags whichfields,
+ const krb5_creds *mcreds,
+ krb5_creds *creds)
+{
+ krb5_error_code ret;
+ krb5_cc_cursor cursor;
+ krb5_cc_start_seq_get(context, id, &cursor);
+ while((ret = krb5_cc_next_cred(context, id, creds, &cursor)) == 0){
+ if(krb5_compare_creds(context, whichfields, mcreds, creds)){
+ ret = 0;
+ break;
+ }
+ krb5_free_creds_contents (context, creds);
+ }
+ krb5_cc_end_seq_get(context, id, &cursor);
+ return ret;
+}
+
+/*
+ * Return the principal of `id' in `principal'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_get_principal(krb5_context context,
+ krb5_ccache id,
+ krb5_principal *principal)
+{
+ return id->ops->get_princ(context, id, principal);
+}
+
+/*
+ * Start iterating over `id', `cursor' is initialized to the
+ * beginning.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_start_seq_get (krb5_context context,
+ const krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ return id->ops->get_first(context, id, cursor);
+}
+
+/*
+ * Retrieve the next cred pointed to by (`id', `cursor') in `creds'
+ * and advance `cursor'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_next_cred (krb5_context context,
+ const krb5_ccache id,
+ krb5_creds *creds,
+ krb5_cc_cursor *cursor)
+{
+ return id->ops->get_next(context, id, cursor, creds);
+}
+
+/*
+ * Destroy the cursor `cursor'.
+ */
+
+krb5_error_code
+krb5_cc_end_seq_get (krb5_context context,
+ const krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ return id->ops->end_get(context, id, cursor);
+}
+
+/*
+ * Remove the credential identified by `cred', `which' from `id'.
+ */
+
+krb5_error_code
+krb5_cc_remove_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_flags which,
+ krb5_creds *cred)
+{
+ return id->ops->remove_cred(context, id, which, cred);
+}
+
+/*
+ * Set the flags of `id' to `flags'.
+ */
+
+krb5_error_code
+krb5_cc_set_flags(krb5_context context,
+ krb5_ccache id,
+ krb5_flags flags)
+{
+ return id->ops->set_flags(context, id, flags);
+}
+
+/*
+ * Copy the contents of `from' to `to'.
+ */
+
+krb5_error_code
+krb5_cc_copy_cache(krb5_context context,
+ const krb5_ccache from,
+ krb5_ccache to)
+{
+ krb5_error_code ret;
+ krb5_cc_cursor cursor;
+ krb5_creds cred;
+ krb5_principal princ;
+
+ ret = krb5_cc_get_principal(context, from, &princ);
+ if(ret)
+ return ret;
+ ret = krb5_cc_initialize(context, to, princ);
+ if(ret){
+ krb5_free_principal(context, princ);
+ return ret;
+ }
+ ret = krb5_cc_start_seq_get(context, from, &cursor);
+ if(ret){
+ krb5_free_principal(context, princ);
+ return ret;
+ }
+ while(ret == 0 && krb5_cc_next_cred(context, from, &cred, &cursor) == 0){
+ ret = krb5_cc_store_cred(context, to, &cred);
+ krb5_free_creds_contents (context, &cred);
+ }
+ krb5_cc_end_seq_get(context, from, &cursor);
+ krb5_free_principal(context, princ);
+ return ret;
+}
+
+/*
+ * Return the version of `id'.
+ */
+
+krb5_error_code
+krb5_cc_get_version(krb5_context context,
+ const krb5_ccache id)
+{
+ if(id->ops->get_version)
+ return id->ops->get_version(context, id);
+ else
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/changepw.c b/crypto/heimdal/lib/krb5/changepw.c
new file mode 100644
index 000000000000..fd9444062934
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/changepw.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: changepw.c,v 1.19 1999/12/11 23:14:51 assar Exp $");
+
+static krb5_error_code
+get_kdc_address (krb5_context context,
+ krb5_realm realm,
+ struct addrinfo **ai)
+{
+ struct addrinfo hints;
+ krb5_error_code ret;
+ char **hostlist;
+ int port = 0;
+ char portstr[NI_MAXSERV];
+ int error;
+ char *host;
+ char *dot;
+
+ ret = krb5_get_krb_changepw_hst (context,
+ &realm,
+ &hostlist);
+ if (ret)
+ return ret;
+
+ host = *hostlist;
+
+ dot = strchr (host, ':');
+ if (dot != NULL) {
+ char *end;
+
+ *dot++ = '\0';
+ port = strtol (dot, &end, 0);
+ }
+ if (port == 0)
+ port = krb5_getportbyname (context, "kpasswd", "udp", KPASSWD_PORT);
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(port));
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+
+ error = getaddrinfo (host, portstr, &hints, ai);
+ krb5_free_krbhst (context, hostlist);
+ return error;
+}
+
+static krb5_error_code
+send_request (krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_creds *creds,
+ int sock,
+ struct sockaddr *sa,
+ int sa_size,
+ char *passwd)
+{
+ krb5_error_code ret;
+ krb5_data ap_req_data;
+ krb5_data krb_priv_data;
+ krb5_data passwd_data;
+ size_t len;
+ u_char header[6];
+ u_char *p;
+ struct iovec iov[3];
+ struct msghdr msghdr;
+
+ krb5_data_zero (&ap_req_data);
+
+ ret = krb5_mk_req_extended (context,
+ auth_context,
+ AP_OPTS_MUTUAL_REQUIRED,
+ NULL, /* in_data */
+ creds,
+ &ap_req_data);
+ if (ret)
+ return ret;
+
+ passwd_data.data = passwd;
+ passwd_data.length = strlen(passwd);
+
+ krb5_data_zero (&krb_priv_data);
+
+ ret = krb5_mk_priv (context,
+ *auth_context,
+ &passwd_data,
+ &krb_priv_data,
+ NULL);
+ if (ret)
+ goto out2;
+
+ len = 6 + ap_req_data.length + krb_priv_data.length;
+ p = header;
+ *p++ = (len >> 8) & 0xFF;
+ *p++ = (len >> 0) & 0xFF;
+ *p++ = 0;
+ *p++ = 1;
+ *p++ = (ap_req_data.length >> 8) & 0xFF;
+ *p++ = (ap_req_data.length >> 0) & 0xFF;
+
+ memset(&msghdr, 0, sizeof(msghdr));
+ msghdr.msg_name = (void *)sa;
+ msghdr.msg_namelen = sa_size;
+ msghdr.msg_iov = iov;
+ msghdr.msg_iovlen = sizeof(iov)/sizeof(*iov);
+#if 0
+ msghdr.msg_control = NULL;
+ msghdr.msg_controllen = 0;
+#endif
+
+ iov[0].iov_base = (void*)header;
+ iov[0].iov_len = 6;
+ iov[1].iov_base = ap_req_data.data;
+ iov[1].iov_len = ap_req_data.length;
+ iov[2].iov_base = krb_priv_data.data;
+ iov[2].iov_len = krb_priv_data.length;
+
+ if (sendmsg (sock, &msghdr, 0) < 0)
+ ret = errno;
+
+ krb5_data_free (&krb_priv_data);
+out2:
+ krb5_data_free (&ap_req_data);
+ return ret;
+}
+
+static void
+str2data (krb5_data *d,
+ char *fmt,
+ ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ d->length = vasprintf ((char **)&d->data, fmt, args);
+ va_end(args);
+}
+
+static krb5_error_code
+process_reply (krb5_context context,
+ krb5_auth_context auth_context,
+ int sock,
+ int *result_code,
+ krb5_data *result_code_string,
+ krb5_data *result_string)
+{
+ krb5_error_code ret;
+ u_char reply[BUFSIZ];
+ size_t len;
+ u_int16_t pkt_len, pkt_ver;
+ krb5_data ap_rep_data;
+
+ ret = recvfrom (sock, reply, sizeof(reply), 0, NULL, NULL);
+ if (ret < 0)
+ return errno;
+
+ len = ret;
+ pkt_len = (reply[0] << 8) | (reply[1]);
+ pkt_ver = (reply[2] << 8) | (reply[3]);
+
+ if (pkt_len != len) {
+ str2data (result_string, "client: wrong len in reply");
+ *result_code = KRB5_KPASSWD_MALFORMED;
+ return 0;
+ }
+ if (pkt_ver != 0x0001) {
+ str2data (result_string,
+ "client: wrong version number (%d)", pkt_ver);
+ *result_code = KRB5_KPASSWD_MALFORMED;
+ return 0;
+ }
+
+ ap_rep_data.data = reply + 6;
+ ap_rep_data.length = (reply[4] << 8) | (reply[5]);
+
+ if (ap_rep_data.length) {
+ krb5_ap_rep_enc_part *ap_rep;
+ krb5_data priv_data;
+ u_char *p;
+
+ ret = krb5_rd_rep (context,
+ auth_context,
+ &ap_rep_data,
+ &ap_rep);
+ if (ret)
+ return ret;
+
+ krb5_free_ap_rep_enc_part (context, ap_rep);
+
+ priv_data.data = (u_char*)ap_rep_data.data + ap_rep_data.length;
+ priv_data.length = len - ap_rep_data.length - 6;
+
+ ret = krb5_rd_priv (context,
+ auth_context,
+ &priv_data,
+ result_code_string,
+ NULL);
+ if (ret) {
+ krb5_data_free (result_code_string);
+ return ret;
+ }
+
+ if (result_code_string->length < 2) {
+ *result_code = KRB5_KPASSWD_MALFORMED;
+ str2data (result_string,
+ "client: bad length in result");
+ return 0;
+ }
+ p = result_code_string->data;
+
+ *result_code = (p[0] << 8) | p[1];
+ krb5_data_copy (result_string,
+ (unsigned char*)result_code_string->data + 2,
+ result_code_string->length - 2);
+ return 0;
+ } else {
+ KRB_ERROR error;
+ size_t size;
+ u_char *p;
+
+ ret = decode_KRB_ERROR(reply + 6, len - 6, &error, &size);
+ if (ret) {
+ return ret;
+ }
+ if (error.e_data->length < 2) {
+ krb5_warnx (context, "too short e_data to print anything usable");
+ return 1;
+ }
+
+ p = error.e_data->data;
+ *result_code = (p[0] << 8) | p[1];
+ krb5_data_copy (result_string,
+ p + 2,
+ error.e_data->length - 2);
+ return 0;
+ }
+}
+
+krb5_error_code
+krb5_change_password (krb5_context context,
+ krb5_creds *creds,
+ char *newpw,
+ int *result_code,
+ krb5_data *result_code_string,
+ krb5_data *result_string)
+{
+ krb5_error_code ret;
+ krb5_auth_context auth_context = NULL;
+ int sock;
+ int i;
+ struct addrinfo *ai, *a;
+
+ ret = krb5_auth_con_init (context, &auth_context);
+ if (ret)
+ return ret;
+
+ ret = get_kdc_address (context, creds->client->realm, &ai);
+ if (ret)
+ goto out;
+
+ krb5_auth_con_setflags (context, auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ sock = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (sock < 0)
+ continue;
+
+ for (i = 0; i < 5; ++i) {
+ fd_set fdset;
+ struct timeval tv;
+
+ ret = send_request (context,
+ &auth_context,
+ creds,
+ sock,
+ a->ai_addr,
+ a->ai_addrlen,
+ newpw);
+ if (ret)
+ goto out;
+
+ FD_ZERO(&fdset);
+ FD_SET(sock, &fdset);
+ tv.tv_usec = 0;
+ tv.tv_sec = 1 << i;
+
+ ret = select (sock + 1, &fdset, NULL, NULL, &tv);
+ if (ret < 0 && errno != EINTR)
+ goto out;
+ if (ret == 1)
+ break;
+ }
+ if (i == 5) {
+ ret = KRB5_KDC_UNREACH;
+ close (sock);
+ continue;
+ }
+
+ ret = process_reply (context,
+ auth_context,
+ sock,
+ result_code,
+ result_code_string,
+ result_string);
+ close (sock);
+ if (ret == 0)
+ break;
+ }
+ freeaddrinfo (ai);
+
+out:
+ krb5_auth_con_free (context, auth_context);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/codec.c b/crypto/heimdal/lib/krb5/codec.c
new file mode 100644
index 000000000000..1d946135c4c8
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/codec.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 1998 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: codec.c,v 1.6 1999/12/02 17:05:08 joda Exp $");
+
+/* these functions does what the normal asn.1-functions does, but
+ converts the keytype to/from the on-the-wire enctypes */
+
+#if 1
+#define DECODE(T, K) return decode_ ## T(data, length, t, len)
+#define ENCODE(T, K) return encode_ ## T(data, length, t, len)
+#else
+#define DECODE(T, K) \
+{ \
+ krb5_error_code ret; \
+ ret = decode_ ## T((void*)data, length, t, len); \
+ if(ret) \
+ return ret; \
+ if(K) \
+ ret = krb5_decode_keyblock(context, (K), 1); \
+ return ret; \
+}
+
+#define ENCODE(T, K) \
+{ \
+ krb5_error_code ret = 0; \
+ if(K) \
+ ret = krb5_decode_keyblock(context, (K), 0); \
+ if(ret) \
+ return ret; \
+ return encode_ ## T(data, length, t, len); \
+}
+#endif
+
+krb5_error_code
+krb5_decode_EncTicketPart (krb5_context context,
+ const void *data,
+ size_t length,
+ EncTicketPart *t,
+ size_t *len)
+{
+ DECODE(EncTicketPart, &t->key);
+}
+
+krb5_error_code
+krb5_encode_EncTicketPart (krb5_context context,
+ void *data,
+ size_t length,
+ EncTicketPart *t,
+ size_t *len)
+{
+ ENCODE(EncTicketPart, &t->key);
+}
+
+krb5_error_code
+krb5_decode_EncASRepPart (krb5_context context,
+ const void *data,
+ size_t length,
+ EncASRepPart *t,
+ size_t *len)
+{
+ DECODE(EncASRepPart, &t->key);
+}
+
+krb5_error_code
+krb5_encode_EncASRepPart (krb5_context context,
+ void *data,
+ size_t length,
+ EncASRepPart *t,
+ size_t *len)
+{
+ ENCODE(EncASRepPart, &t->key);
+}
+
+krb5_error_code
+krb5_decode_EncTGSRepPart (krb5_context context,
+ const void *data,
+ size_t length,
+ EncTGSRepPart *t,
+ size_t *len)
+{
+ DECODE(EncTGSRepPart, &t->key);
+}
+
+krb5_error_code
+krb5_encode_EncTGSRepPart (krb5_context context,
+ void *data,
+ size_t length,
+ EncTGSRepPart *t,
+ size_t *len)
+{
+ ENCODE(EncTGSRepPart, &t->key);
+}
+
+krb5_error_code
+krb5_decode_EncAPRepPart (krb5_context context,
+ const void *data,
+ size_t length,
+ EncAPRepPart *t,
+ size_t *len)
+{
+ DECODE(EncAPRepPart, t->subkey);
+}
+
+krb5_error_code
+krb5_encode_EncAPRepPart (krb5_context context,
+ void *data,
+ size_t length,
+ EncAPRepPart *t,
+ size_t *len)
+{
+ ENCODE(EncAPRepPart, t->subkey);
+}
+
+krb5_error_code
+krb5_decode_Authenticator (krb5_context context,
+ const void *data,
+ size_t length,
+ Authenticator *t,
+ size_t *len)
+{
+ DECODE(Authenticator, t->subkey);
+}
+
+krb5_error_code
+krb5_encode_Authenticator (krb5_context context,
+ void *data,
+ size_t length,
+ Authenticator *t,
+ size_t *len)
+{
+ ENCODE(Authenticator, t->subkey);
+}
+
+krb5_error_code
+krb5_decode_EncKrbCredPart (krb5_context context,
+ const void *data,
+ size_t length,
+ EncKrbCredPart *t,
+ size_t *len)
+{
+#if 1
+ return decode_EncKrbCredPart(data, length, t, len);
+#else
+ krb5_error_code ret;
+ int i;
+ ret = decode_EncKrbCredPart((void*)data, length, t, len);
+ if(ret)
+ return ret;
+ for(i = 0; i < t->ticket_info.len; i++)
+ if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 1)))
+ break;
+ return ret;
+#endif
+}
+
+krb5_error_code
+krb5_encode_EncKrbCredPart (krb5_context context,
+ void *data,
+ size_t length,
+ EncKrbCredPart *t,
+ size_t *len)
+{
+#if 0
+ krb5_error_code ret = 0;
+ int i;
+
+ for(i = 0; i < t->ticket_info.len; i++)
+ if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 0)))
+ break;
+ if(ret) return ret;
+#endif
+ return encode_EncKrbCredPart (data, length, t, len);
+}
+
+krb5_error_code
+krb5_decode_ETYPE_INFO (krb5_context context,
+ const void *data,
+ size_t length,
+ ETYPE_INFO *t,
+ size_t *len)
+{
+#if 1
+ return decode_ETYPE_INFO(data, length, t, len);
+#else
+ krb5_error_code ret;
+ int i;
+
+ ret = decode_ETYPE_INFO((void*)data, length, t, len);
+ if(ret)
+ return ret;
+ for(i = 0; i < t->len; i++) {
+ if((ret = krb5_decode_keytype(context, &t->val[i].etype, 1)))
+ break;
+ }
+ return ret;
+#endif
+}
+
+krb5_error_code
+krb5_encode_ETYPE_INFO (krb5_context context,
+ void *data,
+ size_t length,
+ ETYPE_INFO *t,
+ size_t *len)
+{
+#if 0
+ krb5_error_code ret = 0;
+
+ int i;
+ /* XXX this will break, since we need one key-info for each enctype */
+ /* XXX or do we? */
+ for(i = 0; i < t->len; i++)
+ if((ret = krb5_decode_keytype(context, &t->val[i].etype, 0)))
+ break;
+ if(ret) return ret;
+#endif
+ return encode_ETYPE_INFO (data, length, t, len);
+}
diff --git a/crypto/heimdal/lib/krb5/config_file.c b/crypto/heimdal/lib/krb5/config_file.c
new file mode 100644
index 000000000000..3d1ff1e7a23e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/config_file.c
@@ -0,0 +1,750 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+RCSID("$Id: config_file.c,v 1.38 1999/12/02 17:05:08 joda Exp $");
+
+#ifndef HAVE_NETINFO
+
+static int parse_section(char *p, krb5_config_section **s,
+ krb5_config_section **res,
+ char **error_message);
+static int parse_binding(FILE *f, unsigned *lineno, char *p,
+ krb5_config_binding **b,
+ krb5_config_binding **parent,
+ char **error_message);
+static int parse_list(FILE *f, unsigned *lineno, krb5_config_binding **parent,
+ char **error_message);
+
+/*
+ * Parse a section:
+ *
+ * [section]
+ * foo = bar
+ * b = {
+ * a
+ * }
+ * ...
+ *
+ * starting at the line in `p', storing the resulting structure in
+ * `s' and hooking it into `parent'.
+ * Store the error message in `error_message'.
+ */
+
+static int
+parse_section(char *p, krb5_config_section **s, krb5_config_section **parent,
+ char **error_message)
+{
+ char *p1;
+ krb5_config_section *tmp;
+
+ p1 = strchr (p + 1, ']');
+ if (p1 == NULL) {
+ *error_message = "missing ]";
+ return -1;
+ }
+ *p1 = '\0';
+ tmp = malloc(sizeof(*tmp));
+ if (tmp == NULL) {
+ *error_message = "out of memory";
+ return -1;
+ }
+ tmp->name = strdup(p+1);
+ if (tmp->name == NULL) {
+ *error_message = "out of memory";
+ return -1;
+ }
+ tmp->type = krb5_config_list;
+ tmp->u.list = NULL;
+ tmp->next = NULL;
+ if (*s)
+ (*s)->next = tmp;
+ else
+ *parent = tmp;
+ *s = tmp;
+ return 0;
+}
+
+/*
+ * Parse a brace-enclosed list from `f', hooking in the structure at
+ * `parent'.
+ * Store the error message in `error_message'.
+ */
+
+static int
+parse_list(FILE *f, unsigned *lineno, krb5_config_binding **parent,
+ char **error_message)
+{
+ char buf[BUFSIZ];
+ int ret;
+ krb5_config_binding *b = NULL;
+ unsigned beg_lineno = *lineno;
+
+ while(fgets(buf, sizeof(buf), f) != NULL) {
+ char *p;
+
+ ++*lineno;
+ if (buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ p = buf;
+ while(isspace((unsigned char)*p))
+ ++p;
+ if (*p == '#' || *p == ';' || *p == '\0')
+ continue;
+ while(isspace((unsigned char)*p))
+ ++p;
+ if (*p == '}')
+ return 0;
+ if (*p == '\0')
+ continue;
+ ret = parse_binding (f, lineno, p, &b, parent, error_message);
+ if (ret)
+ return ret;
+ }
+ *lineno = beg_lineno;
+ *error_message = "unclosed {";
+ return -1;
+}
+
+/*
+ *
+ */
+
+static int
+parse_binding(FILE *f, unsigned *lineno, char *p,
+ krb5_config_binding **b, krb5_config_binding **parent,
+ char **error_message)
+{
+ krb5_config_binding *tmp;
+ char *p1, *p2;
+ int ret = 0;
+
+ p1 = p;
+ while (*p && *p != '=' && !isspace((unsigned char)*p))
+ ++p;
+ if (*p == '\0') {
+ *error_message = "no =";
+ return -1;
+ }
+ p2 = p;
+ while (isspace((unsigned char)*p))
+ ++p;
+ if (*p != '=') {
+ *error_message = "no =";
+ return -1;
+ }
+ ++p;
+ while(isspace((unsigned char)*p))
+ ++p;
+ tmp = malloc(sizeof(*tmp));
+ if (tmp == NULL) {
+ *error_message = "out of memory";
+ return -1;
+ }
+ *p2 = '\0';
+ tmp->name = strdup(p1);
+ tmp->next = NULL;
+ if (*p == '{') {
+ tmp->type = krb5_config_list;
+ tmp->u.list = NULL;
+ ret = parse_list (f, lineno, &tmp->u.list, error_message);
+ } else {
+ p1 = p;
+ p = p1 + strlen(p1);
+ while(p > p1 && isspace((unsigned char)*(p-1)))
+ --p;
+ *p = '\0';
+ tmp->type = krb5_config_string;
+ tmp->u.string = strdup(p1);
+ }
+ if (*b)
+ (*b)->next = tmp;
+ else
+ *parent = tmp;
+ *b = tmp;
+ return ret;
+}
+
+/*
+ * Parse the config file `fname', generating the structures into `res'
+ * returning error messages in `error_message'
+ */
+
+krb5_error_code
+krb5_config_parse_file_debug (const char *fname,
+ krb5_config_section **res,
+ unsigned *lineno,
+ char **error_message)
+{
+ FILE *f;
+ krb5_config_section *s;
+ krb5_config_binding *b;
+ char buf[BUFSIZ];
+ int ret;
+
+ s = NULL;
+ b = NULL;
+ *lineno = 0;
+ f = fopen (fname, "r");
+ if (f == NULL) {
+ *error_message = "cannot open file";
+ return -1;
+ }
+ *res = NULL;
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ char *p;
+
+ ++*lineno;
+ if(buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ p = buf;
+ while(isspace((unsigned char)*p))
+ ++p;
+ if (*p == '#' || *p == ';')
+ continue;
+ if (*p == '[') {
+ ret = parse_section(p, &s, res, error_message);
+ if (ret)
+ return ret;
+ b = NULL;
+ } else if (*p == '}') {
+ *error_message = "unmatched }";
+ return -1;
+ } else if(*p != '\0') {
+ ret = parse_binding(f, lineno, p, &b, &s->u.list, error_message);
+ if (ret)
+ return ret;
+ }
+ }
+ fclose (f);
+ return 0;
+}
+
+krb5_error_code
+krb5_config_parse_file (const char *fname, krb5_config_section **res)
+{
+ char *foo;
+ unsigned lineno;
+
+ return krb5_config_parse_file_debug (fname, res, &lineno, &foo);
+}
+
+#endif /* !HAVE_NETINFO */
+
+static void
+free_binding (krb5_context context, krb5_config_binding *b)
+{
+ krb5_config_binding *next_b;
+
+ while (b) {
+ free (b->name);
+ if (b->type == krb5_config_string)
+ free (b->u.string);
+ else if (b->type == krb5_config_list)
+ free_binding (context, b->u.list);
+ else
+ krb5_abortx(context, "unknown binding type (%d) in free_binding",
+ b->type);
+ next_b = b->next;
+ free (b);
+ b = next_b;
+ }
+}
+
+krb5_error_code
+krb5_config_file_free (krb5_context context, krb5_config_section *s)
+{
+ free_binding (context, s);
+ return 0;
+}
+
+const void *
+krb5_config_get_next (krb5_context context,
+ krb5_config_section *c,
+ krb5_config_binding **pointer,
+ int type,
+ ...)
+{
+ const char *ret;
+ va_list args;
+
+ va_start(args, type);
+ ret = krb5_config_vget_next (context, c, pointer, type, args);
+ va_end(args);
+ return ret;
+}
+
+const void *
+krb5_config_vget_next (krb5_context context,
+ krb5_config_section *c,
+ krb5_config_binding **pointer,
+ int type,
+ va_list args)
+{
+ krb5_config_binding *b;
+ const char *p;
+
+ if(c == NULL)
+ c = context->cf;
+
+ if (c == NULL)
+ return NULL;
+
+ if (*pointer == NULL) {
+ b = (c != NULL) ? c : context->cf;
+ p = va_arg(args, const char *);
+ if (p == NULL)
+ return NULL;
+ } else {
+ b = *pointer;
+ p = b->name;
+ b = b->next;
+ }
+
+ while (b) {
+ if (strcmp (b->name, p) == 0) {
+ if (*pointer == NULL)
+ p = va_arg(args, const char *);
+ else
+ p = NULL;
+ if (type == b->type && p == NULL) {
+ *pointer = b;
+ return b->u.generic;
+ } else if(b->type == krb5_config_list && p != NULL) {
+ b = b->u.list;
+ } else {
+ return NULL;
+ }
+ } else {
+ b = b->next;
+ }
+ }
+ return NULL;
+}
+
+const void *
+krb5_config_get (krb5_context context,
+ krb5_config_section *c,
+ int type,
+ ...)
+{
+ const void *ret;
+ va_list args;
+
+ va_start(args, type);
+ ret = krb5_config_vget (context, c, type, args);
+ va_end(args);
+ return ret;
+}
+
+const void *
+krb5_config_vget (krb5_context context,
+ krb5_config_section *c,
+ int type,
+ va_list args)
+{
+ krb5_config_binding *foo = NULL;
+
+ return krb5_config_vget_next (context, c, &foo, type, args);
+}
+
+const krb5_config_binding *
+krb5_config_get_list (krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ const krb5_config_binding *ret;
+ va_list args;
+
+ va_start(args, c);
+ ret = krb5_config_vget_list (context, c, args);
+ va_end(args);
+ return ret;
+}
+
+const krb5_config_binding *
+krb5_config_vget_list (krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ return krb5_config_vget (context, c, krb5_config_list, args);
+}
+
+const char *
+krb5_config_get_string (krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ const char *ret;
+ va_list args;
+
+ va_start(args, c);
+ ret = krb5_config_vget_string (context, c, args);
+ va_end(args);
+ return ret;
+}
+
+const char *
+krb5_config_vget_string (krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ return krb5_config_vget (context, c, krb5_config_string, args);
+}
+
+char **
+krb5_config_vget_strings(krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ char **strings = NULL;
+ int nstr = 0;
+ krb5_config_binding *b = NULL;
+ const char *p;
+
+ while((p = krb5_config_vget_next(context, c, &b,
+ krb5_config_string, args))) {
+ char *tmp = strdup(p);
+ char *pos = NULL;
+ char *s;
+ if(tmp == NULL)
+ goto cleanup;
+ s = strtok_r(tmp, " \t", &pos);
+ while(s){
+ char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
+ if(tmp == NULL)
+ goto cleanup;
+ strings = tmp;
+ strings[nstr] = strdup(s);
+ nstr++;
+ if(strings[nstr-1] == NULL)
+ goto cleanup;
+ s = strtok_r(NULL, " \t", &pos);
+ }
+ free(tmp);
+ }
+ if(nstr){
+ char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
+ if(strings == NULL)
+ goto cleanup;
+ strings = tmp;
+ strings[nstr] = NULL;
+ }
+ return strings;
+cleanup:
+ while(nstr--)
+ free(strings[nstr]);
+ free(strings);
+ return NULL;
+
+}
+
+char**
+krb5_config_get_strings(krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ va_list ap;
+ char **ret;
+ va_start(ap, c);
+ ret = krb5_config_vget_strings(context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+void
+krb5_config_free_strings(char **strings)
+{
+ char **s = strings;
+ while(s && *s){
+ free(*s);
+ s++;
+ }
+ free(strings);
+}
+
+krb5_boolean
+krb5_config_vget_bool_default (krb5_context context,
+ krb5_config_section *c,
+ krb5_boolean def_value,
+ va_list args)
+{
+ const char *str;
+ str = krb5_config_vget_string (context, c, args);
+ if(str == NULL)
+ return def_value;
+ if(strcasecmp(str, "yes") == 0 ||
+ strcasecmp(str, "true") == 0 ||
+ atoi(str)) return TRUE;
+ return FALSE;
+}
+
+krb5_boolean
+krb5_config_vget_bool (krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ return krb5_config_vget_bool_default (context, c, FALSE, args);
+}
+
+krb5_boolean
+krb5_config_get_bool_default (krb5_context context,
+ krb5_config_section *c,
+ krb5_boolean def_value,
+ ...)
+{
+ va_list ap;
+ krb5_boolean ret;
+ va_start(ap, def_value);
+ ret = krb5_config_vget_bool_default(context, c, def_value, ap);
+ va_end(ap);
+ return ret;
+}
+
+krb5_boolean
+krb5_config_get_bool (krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ va_list ap;
+ krb5_boolean ret;
+ va_start(ap, c);
+ ret = krb5_config_vget_bool (context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+krb5_config_vget_time_default (krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ va_list args)
+{
+ const char *str;
+ str = krb5_config_vget_string (context, c, args);
+ if(str == NULL)
+ return def_value;
+ return parse_time (str, NULL);
+}
+
+int
+krb5_config_vget_time (krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ return krb5_config_vget_time_default (context, c, -1, args);
+}
+
+int
+krb5_config_get_time_default (krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, def_value);
+ ret = krb5_config_vget_time_default(context, c, def_value, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+krb5_config_get_time (krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, c);
+ ret = krb5_config_vget_time (context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+
+int
+krb5_config_vget_int_default (krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ va_list args)
+{
+ const char *str;
+ str = krb5_config_vget_string (context, c, args);
+ if(str == NULL)
+ return def_value;
+ else {
+ char *endptr;
+ long l;
+ l = strtol(str, &endptr, 0);
+ if (endptr == str)
+ return def_value;
+ else
+ return l;
+ }
+}
+
+int
+krb5_config_vget_int (krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ return krb5_config_vget_int_default (context, c, -1, args);
+}
+
+int
+krb5_config_get_int_default (krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, def_value);
+ ret = krb5_config_vget_int_default(context, c, def_value, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+krb5_config_get_int (krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, c);
+ ret = krb5_config_vget_int (context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+#ifdef TEST
+
+static int print_list (krb5_context context, FILE *f,
+ krb5_config_binding *l, unsigned level);
+static int print_binding (krb5_context context, FILE *f,
+ krb5_config_binding *b, unsigned level);
+static int print_section (krb5_context context, FILE *f,
+ krb5_config_section *s, unsigned level);
+static int print_config (krb5_context context, FILE *f,
+ krb5_config_section *c);
+
+static void
+tab (FILE *f, unsigned count)
+{
+ while(count--)
+ fprintf (f, "\t");
+}
+
+static int
+print_list (krb5_context context,
+ FILE *f,
+ krb5_config_binding *l,
+ unsigned level)
+{
+ while(l) {
+ print_binding (context, f, l, level);
+ l = l->next;
+ }
+ return 0;
+}
+
+static int
+print_binding (krb5_context context,
+ FILE *f,
+ krb5_config_binding *b,
+ unsigned level)
+{
+ tab (f, level);
+ fprintf (f, "%s = ", b->name);
+ if (b->type == krb5_config_string)
+ fprintf (f, "%s\n", b->u.string);
+ else if (b->type == krb5_config_list) {
+ fprintf (f, "{\n");
+ print_list (f, b->u.list, level + 1);
+ tab (f, level);
+ fprintf (f, "}\n");
+ } else
+ krb5_abortx(context, "unknown binding type (%d) in print_binding",
+ b->type);
+ return 0;
+}
+
+static int
+print_section (FILE *f, krb5_config_section *s, unsigned level)
+{
+ fprintf (f, "[%s]\n", s->name);
+ print_list (f, s->u.list, level + 1);
+ return 0;
+}
+
+static int
+print_config (FILE *f, krb5_config_section *c)
+{
+ while (c) {
+ print_section (f, c, 0);
+ c = c->next;
+ }
+ return 0;
+}
+
+
+int
+main(void)
+{
+ krb5_config_section *c;
+
+ printf ("%d\n", krb5_config_parse_file ("/etc/krb5.conf", &c));
+ print_config (stdout, c);
+ printf ("[libdefaults]ticket_lifetime = %s\n",
+ krb5_config_get_string (context, c,
+ "libdefaults",
+ "ticket_lifetime",
+ NULL));
+ printf ("[realms]foo = %s\n",
+ krb5_config_get_string (context, c,
+ "realms",
+ "foo",
+ NULL));
+ printf ("[realms]ATHENA.MIT.EDU/v4_instance_convert/lithium = %s\n",
+ krb5_config_get_string (context, c,
+ "realms",
+ "ATHENA.MIT.EDU",
+ "v4_instance_convert",
+ "lithium",
+ NULL));
+ return 0;
+}
+
+#endif /* TEST */
diff --git a/crypto/heimdal/lib/krb5/config_file_netinfo.c b/crypto/heimdal/lib/krb5/config_file_netinfo.c
new file mode 100644
index 000000000000..aeb939a3cb5a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/config_file_netinfo.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+RCSID("$Id: config_file_netinfo.c,v 1.2 1999/12/02 17:05:08 joda Exp $");
+
+/*
+ * Netinfo implementation from Luke Howard <lukeh@xedoc.com.au>
+ */
+
+#ifdef HAVE_NETINFO
+#include <netinfo/ni.h>
+static ni_status
+ni_proplist2binding(ni_proplist *pl, krb5_config_section **ret)
+{
+ int i, j;
+ krb5_config_section **next = NULL;
+
+ for (i = 0; i < pl->ni_proplist_len; i++) {
+ if (!strcmp(pl->nipl_val[i].nip_name, "name"))
+ continue;
+
+ for (j = 0; j < pl->nipl_val[i].nip_val.ni_namelist_len; j++) {
+ krb5_config_binding *b;
+
+ b = malloc(sizeof(*b));
+ if (b == NULL)
+ return NI_FAILED;
+
+ b->next = NULL;
+ b->type = krb5_config_string;
+ b->name = ni_name_dup(pl->nipl_val[i].nip_name);
+ b->u.string = ni_name_dup(pl->nipl_val[i].nip_val.ninl_val[j]);
+
+ if (next == NULL) {
+ *ret = b;
+ } else {
+ *next = b;
+ }
+ next = &b->next;
+ }
+ }
+ return NI_OK;
+}
+
+static ni_status
+ni_idlist2binding(void *ni, ni_idlist *idlist, krb5_config_section **ret)
+{
+ int i;
+ ni_status nis;
+ krb5_config_section **next;
+
+ for (i = 0; i < idlist->ni_idlist_len; i++) {
+ ni_proplist pl;
+ ni_id nid;
+ ni_idlist children;
+ krb5_config_binding *b;
+ ni_index index;
+
+ nid.nii_instance = 0;
+ nid.nii_object = idlist->ni_idlist_val[i];
+
+ nis = ni_read(ni, &nid, &pl);
+
+ if (nis != NI_OK) {
+ return nis;
+ }
+ index = ni_proplist_match(pl, "name", NULL);
+ b = malloc(sizeof(*b));
+ if (b == NULL) return NI_FAILED;
+
+ if (i == 0) {
+ *ret = b;
+ } else {
+ *next = b;
+ }
+
+ b->type = krb5_config_list;
+ b->name = ni_name_dup(pl.nipl_val[index].nip_val.ninl_val[0]);
+ b->next = NULL;
+ b->u.list = NULL;
+
+ /* get the child directories */
+ nis = ni_children(ni, &nid, &children);
+ if (nis == NI_OK) {
+ nis = ni_idlist2binding(ni, &children, &b->u.list);
+ if (nis != NI_OK) {
+ return nis;
+ }
+ }
+
+ nis = ni_proplist2binding(&pl, b->u.list == NULL ? &b->u.list : &b->u.list->next);
+ ni_proplist_free(&pl);
+ if (nis != NI_OK) {
+ return nis;
+ }
+ next = &b->next;
+ }
+ ni_idlist_free(idlist);
+ return NI_OK;
+}
+
+krb5_error_code
+krb5_config_parse_file (const char *fname, krb5_config_section **res)
+{
+ void *ni = NULL, *lastni = NULL;
+ int i;
+ ni_status nis;
+ ni_id nid;
+ ni_idlist children;
+
+ krb5_config_section *s;
+ int ret;
+
+ s = NULL;
+
+ for (i = 0; i < 256; i++) {
+ if (i == 0) {
+ nis = ni_open(NULL, ".", &ni);
+ } else {
+ if (lastni != NULL) ni_free(lastni);
+ lastni = ni;
+ nis = ni_open(lastni, "..", &ni);
+ }
+ if (nis != NI_OK)
+ break;
+ nis = ni_pathsearch(ni, &nid, "/locations/kerberos");
+ if (nis == NI_OK) {
+ nis = ni_children(ni, &nid, &children);
+ if (nis != NI_OK)
+ break;
+ nis = ni_idlist2binding(ni, &children, &s);
+ break;
+ }
+ }
+
+ if (ni != NULL) ni_free(ni);
+ if (ni != lastni && lastni != NULL) ni_free(lastni);
+
+ ret = (nis == NI_OK) ? 0 : -1;
+ if (ret == 0) {
+ *res = s;
+ } else {
+ *res = NULL;
+ }
+ return ret;
+}
+#endif /* HAVE_NETINFO */
diff --git a/crypto/heimdal/lib/krb5/constants.c b/crypto/heimdal/lib/krb5/constants.c
new file mode 100644
index 000000000000..8314c2698925
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/constants.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: constants.c,v 1.4 1999/12/02 17:05:08 joda Exp $");
+
+const char krb5_config_file[] = "/etc/krb5.conf";
+const char krb5_defkeyname[] = "/etc/v5srvtab";
diff --git a/crypto/heimdal/lib/krb5/context.c b/crypto/heimdal/lib/krb5/context.c
new file mode 100644
index 000000000000..cf25f7b2026a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/context.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: context.c,v 1.51 1999/12/02 17:05:08 joda Exp $");
+
+#define INIT_FIELD(C, T, E, D, F) \
+ (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \
+ "libdefaults", F, NULL)
+
+#ifdef KRB4
+extern krb5_kt_ops krb4_fkt_ops;
+#endif
+
+/*
+ * Set the list of etypes `ret_etypes' from the configuration variable
+ * `name'
+ */
+
+static krb5_error_code
+set_etypes (krb5_context context,
+ const char *name,
+ krb5_enctype **ret_enctypes)
+{
+ char **etypes_str;
+ krb5_enctype *etypes;
+
+ etypes_str = krb5_config_get_strings(context, NULL, "libdefaults",
+ name, NULL);
+ if(etypes_str){
+ int i, j, k;
+ for(i = 0; etypes_str[i]; i++);
+ etypes = malloc((i+1) * sizeof(*etypes));
+ if (etypes == NULL) {
+ krb5_config_free_strings (etypes_str);
+ return ENOMEM;
+ }
+ for(j = 0, k = 0; j < i; j++) {
+ if(krb5_string_to_enctype(context, etypes_str[j], &etypes[k]) == 0)
+ k++;
+ }
+ etypes[k] = ETYPE_NULL;
+ krb5_config_free_strings(etypes_str);
+ *ret_enctypes = etypes;
+ }
+ return 0;
+}
+
+/*
+ * read variables from the configuration file and set in `context'
+ */
+
+static krb5_error_code
+init_context_from_config_file(krb5_context context)
+{
+ const char * tmp;
+ INIT_FIELD(context, time, max_skew, 5 * 60, "clockskew");
+ INIT_FIELD(context, time, kdc_timeout, 3, "kdc_timeout");
+ INIT_FIELD(context, int, max_retries, 3, "max_retries");
+
+ context->http_proxy = krb5_config_get_string(context, NULL, "libdefaults",
+ "http_proxy", NULL);
+
+ set_etypes (context, "default_etypes", &context->etypes);
+ set_etypes (context, "default_etypes_des", &context->etypes_des);
+
+ /* default keytab name */
+ context->default_keytab = krb5_config_get_string(context, NULL,
+ "libdefaults",
+ "default_keytab_name",
+ NULL);
+ if(context->default_keytab == NULL)
+ context->default_keytab = KEYTAB_DEFAULT;
+
+ context->time_fmt = krb5_config_get_string(context, NULL, "libdefaults",
+ "time_format", NULL);
+ if(context->time_fmt == NULL)
+ context->time_fmt = "%d-%b-%Y %H:%M:%S";
+ context->log_utc = krb5_config_get_bool(context, NULL, "libdefaults",
+ "log_utc", NULL);
+
+ /* init dns-proxy slime */
+ tmp = krb5_config_get_string(context, NULL, "libdefaults",
+ "dns_proxy", NULL);
+ if(tmp)
+ roken_gethostby_setup(context->http_proxy, tmp);
+ context->default_realms = NULL;
+
+ {
+ krb5_addresses addresses;
+ char **adr, **a;
+ adr = krb5_config_get_strings(context, NULL,
+ "libdefaults",
+ "extra_addresses",
+ NULL);
+ memset(&addresses, 0, sizeof(addresses));
+ for(a = adr; a && *a; a++) {
+ krb5_parse_address(context, *a, &addresses);
+ krb5_add_extra_addresses(context, &addresses);
+ krb5_free_addresses(context, &addresses);
+ }
+ krb5_config_free_strings(adr);
+ }
+
+ INIT_FIELD(context, bool, scan_interfaces, TRUE, "scan_interfaces");
+ INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup");
+ INIT_FIELD(context, bool, srv_try_txt, FALSE, "srv_try_txt");
+ INIT_FIELD(context, bool, srv_try_rfc2052, TRUE, "srv_try_rfc2052");
+ INIT_FIELD(context, int, fcache_vno, 0, "fcache_version");
+
+ context->cc_ops = NULL;
+ context->num_cc_ops = 0;
+ krb5_cc_register(context, &krb5_fcc_ops, TRUE);
+ krb5_cc_register(context, &krb5_mcc_ops, TRUE);
+
+ context->num_kt_types = 0;
+ context->kt_types = NULL;
+ krb5_kt_register (context, &krb5_fkt_ops);
+ krb5_kt_register (context, &krb5_mkt_ops);
+#ifdef KRB4
+ krb5_kt_register (context, &krb4_fkt_ops);
+#endif
+ krb5_kt_register (context, &krb5_akf_ops);
+ return 0;
+}
+
+krb5_error_code
+krb5_init_context(krb5_context *context)
+{
+ krb5_context p;
+ const char *config_file = NULL;
+ krb5_config_section *tmp_cf;
+ krb5_error_code ret;
+
+ ALLOC(p, 1);
+ if(!p)
+ return ENOMEM;
+ memset(p, 0, sizeof(krb5_context_data));
+
+ /* init error tables */
+ krb5_init_ets(p);
+
+ if(!issuid())
+ config_file = getenv("KRB5_CONFIG");
+ if (config_file == NULL)
+ config_file = krb5_config_file;
+
+ ret = krb5_config_parse_file (config_file, &tmp_cf);
+
+ if (ret == 0)
+ p->cf = tmp_cf;
+#if 0
+ else
+ krb5_warnx (p, "Unable to parse config file %s. Ignoring.",
+ config_file); /* XXX */
+#endif
+
+ ret = init_context_from_config_file(p);
+ if(ret)
+ return ret;
+
+ *context = p;
+ return 0;
+}
+
+void
+krb5_free_context(krb5_context context)
+{
+ int i;
+
+ free(context->etypes);
+ free(context->etypes_des);
+ krb5_free_host_realm (context, context->default_realms);
+ krb5_config_file_free (context, context->cf);
+ free_error_table (context->et_list);
+ for(i = 0; i < context->num_cc_ops; ++i)
+ free(context->cc_ops[i].prefix);
+ free(context->cc_ops);
+ free(context->kt_types);
+ free(context);
+}
+
+static krb5_error_code
+default_etypes(krb5_enctype **etype)
+{
+ krb5_enctype p[] = {
+ ETYPE_DES3_CBC_SHA1,
+ ETYPE_DES3_CBC_MD5,
+ ETYPE_DES_CBC_MD5,
+ ETYPE_DES_CBC_MD4,
+ ETYPE_DES_CBC_CRC,
+ ETYPE_NULL
+ };
+ *etype = malloc(sizeof(p));
+ if(*etype == NULL)
+ return ENOMEM;
+ memcpy(*etype, p, sizeof(p));
+ return 0;
+}
+
+krb5_error_code
+krb5_set_default_in_tkt_etypes(krb5_context context,
+ const krb5_enctype *etypes)
+{
+ int i;
+ krb5_enctype *p = NULL;
+
+ if(etypes) {
+ i = 0;
+ while(etypes[i])
+ if(!krb5_enctype_valid(context, etypes[i++]))
+ return KRB5_PROG_ETYPE_NOSUPP;
+ ++i;
+ ALLOC(p, i);
+ if(!p)
+ return ENOMEM;
+ memmove(p, etypes, i * sizeof(krb5_enctype));
+ }
+ if(context->etypes)
+ free(context->etypes);
+ context->etypes = p;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_get_default_in_tkt_etypes(krb5_context context,
+ krb5_enctype **etypes)
+{
+ krb5_enctype *p;
+ int i;
+
+ if(context->etypes) {
+ for(i = 0; context->etypes[i]; i++);
+ ++i;
+ ALLOC(p, i);
+ if(!p)
+ return ENOMEM;
+ memmove(p, context->etypes, i * sizeof(krb5_enctype));
+ } else
+ if(default_etypes(&p))
+ return ENOMEM;
+ *etypes = p;
+ return 0;
+}
+
+const char *
+krb5_get_err_text(krb5_context context, krb5_error_code code)
+{
+ const char *p = com_right(context->et_list, code);
+ if(p == NULL)
+ p = strerror(code);
+ return p;
+}
+
+void
+krb5_init_ets(krb5_context context)
+{
+ if(context->et_list == NULL){
+ initialize_krb5_error_table_r(&context->et_list);
+ initialize_asn1_error_table_r(&context->et_list);
+ initialize_heim_error_table_r(&context->et_list);
+ }
+}
+
+void
+krb5_set_use_admin_kdc (krb5_context context, krb5_boolean flag)
+{
+ context->use_admin_kdc = flag;
+}
+
+krb5_boolean
+krb5_get_use_admin_kdc (krb5_context context)
+{
+ return context->use_admin_kdc;
+}
+
+krb5_error_code
+krb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses)
+{
+
+ if(context->extra_addresses)
+ return krb5_append_addresses(context,
+ context->extra_addresses, addresses);
+ else
+ return krb5_set_extra_addresses(context, addresses);
+}
+
+krb5_error_code
+krb5_set_extra_addresses(krb5_context context, krb5_addresses *addresses)
+{
+ if(context->extra_addresses) {
+ krb5_free_addresses(context, context->extra_addresses);
+ free(context->extra_addresses);
+ }
+ if(context->extra_addresses == NULL) {
+ context->extra_addresses = malloc(sizeof(*context->extra_addresses));
+ if(context->extra_addresses == NULL)
+ return ENOMEM;
+ }
+ return copy_HostAddresses(addresses, context->extra_addresses);
+}
+
+krb5_error_code
+krb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses)
+{
+ if(context->extra_addresses == NULL) {
+ memset(addresses, 0, sizeof(*addresses));
+ return 0;
+ }
+ return copy_HostAddresses(context->extra_addresses, addresses);
+}
+
+krb5_error_code
+krb5_set_fcache_version(krb5_context context, int version)
+{
+ context->fcache_vno = version;
+ return 0;
+}
+
+krb5_error_code
+krb5_get_fcache_version(krb5_context context, int *version)
+{
+ *version = context->fcache_vno;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/convert_creds.c b/crypto/heimdal/lib/krb5/convert_creds.c
new file mode 100644
index 000000000000..24dea0b3283d
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/convert_creds.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+RCSID("$Id: convert_creds.c,v 1.13 1999/12/02 17:05:08 joda Exp $");
+
+static krb5_error_code
+check_ticket_flags(TicketFlags f)
+{
+ return 0; /* maybe add some more tests here? */
+}
+
+/* include this here, to avoid dependencies on libkrb */
+
+#define MAX_KTXT_LEN 1250
+
+#define ANAME_SZ 40
+#define REALM_SZ 40
+#define SNAME_SZ 40
+#define INST_SZ 40
+
+struct ktext {
+ unsigned int length; /* Length of the text */
+ unsigned char dat[MAX_KTXT_LEN]; /* The data itself */
+ u_int32_t mbz; /* zero to catch runaway strings */
+};
+
+struct credentials {
+ char service[ANAME_SZ]; /* Service name */
+ char instance[INST_SZ]; /* Instance */
+ char realm[REALM_SZ]; /* Auth domain */
+ des_cblock session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ struct ktext ticket_st; /* The ticket itself */
+ int32_t issue_date; /* The issue time */
+ char pname[ANAME_SZ]; /* Principal's name */
+ char pinst[INST_SZ]; /* Principal's instance */
+};
+
+
+#define TKTLIFENUMFIXED 64
+#define TKTLIFEMINFIXED 0x80
+#define TKTLIFEMAXFIXED 0xBF
+#define TKTLIFENOEXPIRE 0xFF
+#define MAXTKTLIFETIME (30*24*3600) /* 30 days */
+#ifndef NEVERDATE
+#define NEVERDATE ((time_t)0x7fffffffL)
+#endif
+
+static const int _tkt_lifetimes[TKTLIFENUMFIXED] = {
+ 38400, 41055, 43894, 46929, 50174, 53643, 57352, 61318,
+ 65558, 70091, 74937, 80119, 85658, 91581, 97914, 104684,
+ 111922, 119661, 127935, 136781, 146239, 156350, 167161, 178720,
+ 191077, 204289, 218415, 233517, 249664, 266926, 285383, 305116,
+ 326213, 348769, 372885, 398668, 426234, 455705, 487215, 520904,
+ 556921, 595430, 636601, 680618, 727680, 777995, 831789, 889303,
+ 950794, 1016537, 1086825, 1161973, 1242318, 1328218, 1420057, 1518247,
+ 1623226, 1735464, 1855462, 1983758, 2120925, 2267576, 2424367, 2592000
+};
+
+static int
+_krb_time_to_life(time_t start, time_t end)
+{
+ int i;
+ time_t life = end - start;
+
+ if (life > MAXTKTLIFETIME || life <= 0)
+ return 0;
+#if 0
+ if (krb_no_long_lifetimes)
+ return (life + 5*60 - 1)/(5*60);
+#endif
+
+ if (end >= NEVERDATE)
+ return TKTLIFENOEXPIRE;
+ if (life < _tkt_lifetimes[0])
+ return (life + 5*60 - 1)/(5*60);
+ for (i=0; i<TKTLIFENUMFIXED; i++)
+ if (life <= _tkt_lifetimes[i])
+ return i + TKTLIFEMINFIXED;
+ return 0;
+
+}
+
+/* Convert the v5 credentials in `in_cred' to v4-dito in `v4creds'.
+ * This is done by sending them to the 524 function in the KDC. If
+ * `in_cred' doesn't contain a DES session key, then a new one is
+ * gotten from the KDC and stored in the cred cache `ccache'.
+ */
+
+krb5_error_code
+krb524_convert_creds_kdc(krb5_context context,
+ krb5_ccache ccache,
+ krb5_creds *in_cred,
+ struct credentials *v4creds)
+{
+ krb5_error_code ret;
+ krb5_data reply;
+ krb5_storage *sp;
+ int32_t tmp;
+ krb5_data ticket;
+ char realm[REALM_SZ];
+ krb5_creds *v5_creds = in_cred;
+ krb5_keytype keytype;
+
+ ret = krb5_enctype_to_keytype (context, v5_creds->session.keytype,
+ &keytype);
+ if (ret)
+ return ret;
+
+ if (keytype != KEYTYPE_DES) {
+ krb5_creds template;
+
+ memset (&template, 0, sizeof(template));
+ template.session.keytype = KEYTYPE_DES;
+ ret = krb5_copy_principal (context, in_cred->client, &template.client);
+ if (ret) {
+ krb5_free_creds_contents (context, &template);
+ return ret;
+ }
+ ret = krb5_copy_principal (context, in_cred->server, &template.server);
+ if (ret) {
+ krb5_free_creds_contents (context, &template);
+ return ret;
+ }
+
+ ret = krb5_get_credentials (context, 0, ccache,
+ &template, &v5_creds);
+ krb5_free_creds_contents (context, &template);
+ if (ret)
+ return ret;
+ }
+
+ ret = check_ticket_flags(v5_creds->flags.b);
+ if(ret)
+ goto out2;
+
+ ret = krb5_sendto_kdc (context,
+ &v5_creds->ticket,
+ krb5_princ_realm(context, v5_creds->server),
+ &reply);
+ if (ret)
+ goto out2;
+ sp = krb5_storage_from_mem(reply.data, reply.length);
+ if(sp == NULL) {
+ ret = ENOMEM;
+ goto out2;
+ }
+ krb5_ret_int32(sp, &tmp);
+ ret = tmp;
+ if(ret == 0) {
+ memset(v4creds, 0, sizeof(*v4creds));
+ ret = krb5_ret_int32(sp, &tmp);
+ if(ret) goto out;
+ v4creds->kvno = tmp;
+ ret = krb5_ret_data(sp, &ticket);
+ if(ret) goto out;
+ v4creds->ticket_st.length = ticket.length;
+ memcpy(v4creds->ticket_st.dat, ticket.data, ticket.length);
+ krb5_data_free(&ticket);
+ ret = krb5_524_conv_principal(context,
+ v5_creds->server,
+ v4creds->service,
+ v4creds->instance,
+ v4creds->realm);
+ if(ret) goto out;
+ v4creds->issue_date = v5_creds->times.authtime;
+ v4creds->lifetime = _krb_time_to_life(v4creds->issue_date,
+ v5_creds->times.endtime);
+ ret = krb5_524_conv_principal(context, v5_creds->client,
+ v4creds->pname,
+ v4creds->pinst,
+ realm);
+ if(ret) goto out;
+ memcpy(v4creds->session, v5_creds->session.keyvalue.data, 8);
+ }
+out:
+ krb5_storage_free(sp);
+ krb5_data_free(&reply);
+out2:
+ if (v5_creds != in_cred)
+ krb5_free_creds (context, v5_creds);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/copy_host_realm.c b/crypto/heimdal/lib/krb5/copy_host_realm.c
new file mode 100644
index 000000000000..4a8f3ecd5a63
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/copy_host_realm.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: copy_host_realm.c,v 1.3 1999/12/02 17:05:08 joda Exp $");
+
+/*
+ * Copy the list of realms from `from' to `to'.
+ */
+
+krb5_error_code
+krb5_copy_host_realm(krb5_context context,
+ const krb5_realm *from,
+ krb5_realm **to)
+{
+ int n, i;
+ const krb5_realm *p;
+
+ for (n = 0, p = from; *p != NULL; ++p)
+ ++n;
+ ++n;
+ *to = malloc (n * sizeof(**to));
+ if (*to == NULL)
+ return ENOMEM;
+ for (i = 0; i < n; ++i)
+ (*to)[i] = NULL;
+ for (i = 0, p = from; *p != NULL; ++p, ++i) {
+ (*to)[i] = strdup(*p);
+ if ((*to)[i] == NULL) {
+ krb5_free_host_realm (context, *to);
+ return ENOMEM;
+ }
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/crc.c b/crypto/heimdal/lib/krb5/crc.c
new file mode 100644
index 000000000000..2f9ef95028f3
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/crc.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: crc.c,v 1.8 1999/12/02 17:05:08 joda Exp $");
+
+static u_long table[256];
+
+#define CRC_GEN 0xEDB88320L
+
+void
+_krb5_crc_init_table(void)
+{
+ static int flag = 0;
+ unsigned long crc, poly;
+ int i, j;
+
+ if(flag) return;
+ poly = CRC_GEN;
+ for (i = 0; i < 256; i++) {
+ crc = i;
+ for (j = 8; j > 0; j--) {
+ if (crc & 1) {
+ crc = (crc >> 1) ^ poly;
+ } else {
+ crc >>= 1;
+ }
+ }
+ table[i] = crc;
+ }
+ flag = 1;
+}
+
+u_int32_t
+_krb5_crc_update (char *p, size_t len, u_int32_t res)
+{
+ while (len--)
+ res = table[(res ^ *p++) & 0xFF] ^ (res >> 8);
+ return res & 0xFFFFFFFF;
+}
diff --git a/crypto/heimdal/lib/krb5/creds.c b/crypto/heimdal/lib/krb5/creds.c
new file mode 100644
index 000000000000..705116871224
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/creds.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: creds.c,v 1.14 1999/12/02 17:05:08 joda Exp $");
+
+krb5_error_code
+krb5_free_cred_contents (krb5_context context, krb5_creds *c)
+{
+ return krb5_free_creds_contents (context, c);
+}
+
+krb5_error_code
+krb5_free_creds_contents (krb5_context context, krb5_creds *c)
+{
+ krb5_free_principal (context, c->client);
+ c->client = NULL;
+ krb5_free_principal (context, c->server);
+ c->server = NULL;
+ krb5_free_keyblock_contents (context, &c->session);
+ krb5_data_free (&c->ticket);
+ krb5_data_free (&c->second_ticket);
+ free_AuthorizationData (&c->authdata);
+ krb5_free_addresses (context, &c->addresses);
+ return 0;
+}
+
+krb5_error_code
+krb5_copy_creds_contents (krb5_context context,
+ const krb5_creds *incred,
+ krb5_creds *c)
+{
+ krb5_error_code ret;
+
+ memset(c, 0, sizeof(*c));
+ ret = krb5_copy_principal (context, incred->client, &c->client);
+ if (ret)
+ goto fail;
+ ret = krb5_copy_principal (context, incred->server, &c->server);
+ if (ret)
+ goto fail;
+ ret = krb5_copy_keyblock_contents (context, &incred->session, &c->session);
+ if (ret)
+ goto fail;
+ c->times = incred->times;
+ ret = krb5_data_copy (&c->ticket,
+ incred->ticket.data,
+ incred->ticket.length);
+ if (ret)
+ goto fail;
+ ret = krb5_data_copy (&c->second_ticket,
+ incred->second_ticket.data,
+ incred->second_ticket.length);
+ if (ret)
+ goto fail;
+ ret = copy_AuthorizationData(&incred->authdata, &c->authdata);
+ if (ret)
+ goto fail;
+ ret = krb5_copy_addresses (context,
+ &incred->addresses,
+ &c->addresses);
+ if (ret)
+ goto fail;
+ c->flags = incred->flags;
+ return 0;
+
+fail:
+ krb5_free_creds_contents (context, c);
+ return ret;
+}
+
+krb5_error_code
+krb5_copy_creds (krb5_context context,
+ const krb5_creds *incred,
+ krb5_creds **outcred)
+{
+ krb5_creds *c;
+
+ c = malloc (sizeof (*c));
+ if (c == NULL)
+ return ENOMEM;
+ memset (c, 0, sizeof(*c));
+ *outcred = c;
+ return krb5_copy_creds_contents (context, incred, c);
+}
+
+krb5_error_code
+krb5_free_creds (krb5_context context, krb5_creds *c)
+{
+ krb5_free_creds_contents (context, c);
+ free (c);
+ return 0;
+}
+
+/*
+ * Return TRUE if `mcreds' and `creds' are equal (`whichfields'
+ * determines what equal means).
+ */
+
+krb5_boolean
+krb5_compare_creds(krb5_context context, krb5_flags whichfields,
+ const krb5_creds *mcreds, const krb5_creds *creds)
+{
+ krb5_boolean match;
+
+ if(whichfields & KRB5_TC_DONT_MATCH_REALM)
+ match = krb5_principal_compare_any_realm(context,
+ mcreds->server,
+ creds->server);
+ else
+ match = krb5_principal_compare(context, mcreds->server, creds->server);
+ if(match && (whichfields & KRB5_TC_MATCH_KEYTYPE) &&
+ !krb5_enctypes_compatible_keys (context,
+ mcreds->session.keytype,
+ creds->session.keytype))
+ match = FALSE;
+ return match;
+}
diff --git a/crypto/heimdal/lib/krb5/crypto.c b/crypto/heimdal/lib/krb5/crypto.c
new file mode 100644
index 000000000000..b6db6ce85de9
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/crypto.c
@@ -0,0 +1,2314 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+RCSID("$Id: crypto.c,v 1.28 2000/01/06 20:21:13 assar Exp $");
+
+#undef CRYPTO_DEBUG
+#ifdef CRYPTO_DEBUG
+static void krb5_crypto_debug(krb5_context, int, size_t, krb5_keyblock*);
+#endif
+
+
+struct key_data {
+ krb5_keyblock *key;
+ krb5_data *schedule;
+};
+
+struct key_usage {
+ unsigned usage;
+ struct key_data key;
+};
+
+struct krb5_crypto_data {
+ struct encryption_type *et;
+ struct key_data key;
+ int num_key_usage;
+ struct key_usage *key_usage;
+};
+
+#define CRYPTO_ETYPE(C) ((C)->et->type)
+
+/* bits for `flags' below */
+#define F_KEYED 1 /* checksum is keyed */
+#define F_CPROOF 2 /* checksum is collision proof */
+#define F_DERIVED 4 /* uses derived keys */
+#define F_VARIANT 8 /* uses `variant' keys (6.4.3) */
+#define F_PSEUDO 16 /* not a real protocol type */
+
+struct salt_type {
+ krb5_salttype type;
+ const char *name;
+ krb5_error_code (*string_to_key)(krb5_context, krb5_enctype, krb5_data,
+ krb5_salt, krb5_keyblock*);
+};
+
+struct key_type {
+ krb5_keytype type; /* XXX */
+ const char *name;
+ size_t bits;
+ size_t size;
+ size_t schedule_size;
+#if 0
+ krb5_enctype best_etype;
+#endif
+ void (*random_key)(krb5_context, krb5_keyblock*);
+ void (*schedule)(krb5_context, struct key_data *);
+ struct salt_type *string_to_key;
+};
+
+struct checksum_type {
+ krb5_cksumtype type;
+ const char *name;
+ size_t blocksize;
+ size_t checksumsize;
+ unsigned flags;
+ void (*checksum)(krb5_context, struct key_data*, void*, size_t, Checksum*);
+ krb5_error_code (*verify)(krb5_context, struct key_data*,
+ void*, size_t, Checksum*);
+};
+
+struct encryption_type {
+ krb5_enctype type;
+ const char *name;
+ size_t blocksize;
+ size_t confoundersize;
+ struct key_type *keytype;
+ struct checksum_type *cksumtype;
+ struct checksum_type *keyed_checksum;
+ unsigned flags;
+ void (*encrypt)(struct key_data *, void *, size_t, int);
+};
+
+#define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA)
+#define INTEGRITY_USAGE(U) (((U) << 8) | 0x55)
+#define CHECKSUM_USAGE(U) (((U) << 8) | 0x99)
+
+static struct checksum_type *_find_checksum(krb5_cksumtype type);
+static struct encryption_type *_find_enctype(krb5_enctype type);
+static struct key_type *_find_keytype(krb5_keytype type);
+static krb5_error_code _get_derived_key(krb5_context, krb5_crypto,
+ unsigned, struct key_data**);
+static struct key_data *_new_derived_key(krb5_crypto crypto, unsigned usage);
+
+/************************************************************
+ * *
+ ************************************************************/
+
+static void
+DES_random_key(krb5_context context,
+ krb5_keyblock *key)
+{
+ des_cblock *k = key->keyvalue.data;
+ do {
+ krb5_generate_random_block(k, sizeof(des_cblock));
+ des_set_odd_parity(k);
+ } while(des_is_weak_key(k));
+}
+
+static void
+DES_schedule(krb5_context context,
+ struct key_data *key)
+{
+ des_set_key(key->key->keyvalue.data, key->schedule->data);
+}
+
+static krb5_error_code
+DES_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ char *s;
+ size_t len;
+ des_cblock tmp;
+
+ len = password.length + salt.saltvalue.length + 1;
+ s = malloc(len);
+ if(s == NULL)
+ return ENOMEM;
+ memcpy(s, password.data, password.length);
+ memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length);
+ s[len - 1] = '\0';
+ des_string_to_key(s, &tmp);
+ key->keytype = enctype;
+ krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp));
+ memset(&tmp, 0, sizeof(tmp));
+ memset(s, 0, len);
+ free(s);
+ return 0;
+}
+
+/* This defines the Andrew string_to_key function. It accepts a password
+ * string as input and converts its via a one-way encryption algorithm to a DES
+ * encryption key. It is compatible with the original Andrew authentication
+ * service password database.
+ */
+
+/*
+ * Short passwords, i.e 8 characters or less.
+ */
+static void
+DES_AFS3_CMU_string_to_key (krb5_data pw,
+ krb5_data cell,
+ des_cblock *key)
+{
+ char password[8+1]; /* crypt is limited to 8 chars anyway */
+ int i;
+
+ for(i = 0; i < 8; i++) {
+ char c = ((i < pw.length) ? ((char*)pw.data)[i] : 0) ^
+ ((i < cell.length) ? ((char*)cell.data)[i] : 0);
+ password[i] = c ? c : 'X';
+ }
+ password[8] = '\0';
+
+ memcpy(key, crypt(password, "#~") + 2, sizeof(des_cblock));
+
+ /* parity is inserted into the LSB so left shift each byte up one
+ bit. This allows ascii characters with a zero MSB to retain as
+ much significance as possible. */
+ for (i = 0; i < sizeof(des_cblock); i++)
+ ((unsigned char*)key)[i] <<= 1;
+ des_set_odd_parity (key);
+}
+
+/*
+ * Long passwords, i.e 9 characters or more.
+ */
+static void
+DES_AFS3_Transarc_string_to_key (krb5_data pw,
+ krb5_data cell,
+ des_cblock *key)
+{
+ des_key_schedule schedule;
+ des_cblock temp_key;
+ des_cblock ivec;
+ char password[512];
+ size_t passlen;
+
+ memcpy(password, pw.data, min(pw.length, sizeof(password)));
+ if(pw.length < sizeof(password))
+ memcpy(password + pw.length,
+ cell.data, min(cell.length,
+ sizeof(password) - pw.length));
+ passlen = min(sizeof(password), pw.length + cell.length);
+ memcpy(&ivec, "kerberos", 8);
+ memcpy(&temp_key, "kerberos", 8);
+ des_set_odd_parity (&temp_key);
+ des_set_key (&temp_key, schedule);
+ des_cbc_cksum ((des_cblock *)password, &ivec, passlen, schedule, &ivec);
+
+ memcpy(&temp_key, &ivec, 8);
+ des_set_odd_parity (&temp_key);
+ des_set_key (&temp_key, schedule);
+ des_cbc_cksum ((des_cblock *)password, key, passlen, schedule, &ivec);
+ memset(&schedule, 0, sizeof(schedule));
+ memset(&temp_key, 0, sizeof(temp_key));
+ memset(&ivec, 0, sizeof(ivec));
+ memset(password, 0, sizeof(password));
+
+ des_set_odd_parity (key);
+}
+
+static krb5_error_code
+DES_AFS3_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ des_cblock tmp;
+ if(password.length > 8)
+ DES_AFS3_Transarc_string_to_key(password, salt.saltvalue, &tmp);
+ else
+ DES_AFS3_CMU_string_to_key(password, salt.saltvalue, &tmp);
+ key->keytype = enctype;
+ krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp));
+ memset(&key, 0, sizeof(key));
+ return 0;
+}
+
+static void
+DES3_random_key(krb5_context context,
+ krb5_keyblock *key)
+{
+ des_cblock *k = key->keyvalue.data;
+ do {
+ krb5_generate_random_block(k, 3 * sizeof(des_cblock));
+ des_set_odd_parity(&k[0]);
+ des_set_odd_parity(&k[1]);
+ des_set_odd_parity(&k[2]);
+ } while(des_is_weak_key(&k[0]) ||
+ des_is_weak_key(&k[1]) ||
+ des_is_weak_key(&k[2]));
+}
+
+static void
+DES3_schedule(krb5_context context,
+ struct key_data *key)
+{
+ des_cblock *k = key->key->keyvalue.data;
+ des_key_schedule *s = key->schedule->data;
+ des_set_key(&k[0], s[0]);
+ des_set_key(&k[1], s[1]);
+ des_set_key(&k[2], s[2]);
+}
+
+/*
+ * A = A xor B. A & B are 8 bytes.
+ */
+
+static void
+xor (des_cblock *key, const unsigned char *b)
+{
+ unsigned char *a = (unsigned char*)key;
+ a[0] ^= b[0];
+ a[1] ^= b[1];
+ a[2] ^= b[2];
+ a[3] ^= b[3];
+ a[4] ^= b[4];
+ a[5] ^= b[5];
+ a[6] ^= b[6];
+ a[7] ^= b[7];
+}
+
+static krb5_error_code
+DES3_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ char *str;
+ size_t len;
+ unsigned char tmp[24];
+ des_cblock keys[3];
+
+ len = password.length + salt.saltvalue.length;
+ str = malloc(len);
+ if(len != 0 && str == NULL)
+ return ENOMEM;
+ memcpy(str, password.data, password.length);
+ memcpy(str + password.length, salt.saltvalue.data, salt.saltvalue.length);
+ {
+ des_cblock ivec;
+ des_key_schedule s[3];
+ int i;
+
+ _krb5_n_fold(str, len, tmp, 24);
+
+ for(i = 0; i < 3; i++){
+ memcpy(keys + i, tmp + i * 8, sizeof(keys[i]));
+ des_set_odd_parity(keys + i);
+ if(des_is_weak_key(keys + i))
+ xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
+ des_set_key(keys + i, s[i]);
+ }
+ memset(&ivec, 0, sizeof(ivec));
+ des_ede3_cbc_encrypt((void*)tmp, (void*)tmp, sizeof(tmp),
+ s[0], s[1], s[2], &ivec, DES_ENCRYPT);
+ memset(s, 0, sizeof(s));
+ memset(&ivec, 0, sizeof(ivec));
+ for(i = 0; i < 3; i++){
+ memcpy(keys + i, tmp + i * 8, sizeof(keys[i]));
+ des_set_odd_parity(keys + i);
+ if(des_is_weak_key(keys + i))
+ xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
+ }
+ memset(tmp, 0, sizeof(tmp));
+ }
+ key->keytype = enctype;
+ krb5_data_copy(&key->keyvalue, keys, sizeof(keys));
+ memset(keys, 0, sizeof(keys));
+ memset(str, 0, len);
+ free(str);
+ return 0;
+}
+
+static krb5_error_code
+DES3_string_to_key_derived(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ size_t len = password.length + salt.saltvalue.length;
+ char *s;
+
+ s = malloc(len);
+ if(len != 0 && s == NULL)
+ return ENOMEM;
+ memcpy(s, password.data, password.length);
+ memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length);
+ ret = krb5_string_to_key_derived(context,
+ s,
+ len,
+ enctype,
+ key);
+ memset(s, 0, len);
+ free(s);
+ return ret;
+}
+
+/*
+ * ARCFOUR
+ */
+
+static void
+ARCFOUR_random_key(krb5_context context, krb5_keyblock *key)
+{
+ krb5_generate_random_block (key->keyvalue.data,
+ key->keyvalue.length);
+}
+
+static void
+ARCFOUR_schedule(krb5_context context, struct key_data *kd)
+{
+ RC4_set_key (kd->schedule->data,
+ kd->key->keyvalue.length, kd->key->keyvalue.data);
+}
+
+static krb5_error_code
+ARCFOUR_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ char *s, *p;
+ size_t len;
+ int i;
+ struct md4 m;
+
+ len = 2 * (password.length + salt.saltvalue.length);
+ s = malloc (len);
+ if (len != 0 && s == NULL)
+ return ENOMEM;
+ for (p = s, i = 0; i < password.length; ++i) {
+ *p++ = ((char *)password.data)[i];
+ *p++ = 0;
+ }
+ for (i = 0; i < salt.saltvalue.length; ++i) {
+ *p++ = ((char *)salt.saltvalue.data)[i];
+ *p++ = 0;
+ }
+ md4_init(&m);
+ md4_update(&m, s, len);
+ key->keytype = enctype;
+ krb5_data_alloc (&key->keyvalue, 16);
+ md4_finito(&m, key->keyvalue.data);
+ memset (s, 0, len);
+ free (s);
+ return 0;
+}
+
+extern struct salt_type des_salt[],
+ des3_salt[], des3_salt_derived[], arcfour_salt[];
+
+struct key_type keytype_null = {
+ KEYTYPE_NULL,
+ "null",
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL
+};
+
+struct key_type keytype_des = {
+ KEYTYPE_DES,
+ "des",
+ 56,
+ sizeof(des_cblock),
+ sizeof(des_key_schedule),
+ DES_random_key,
+ DES_schedule,
+ des_salt
+};
+
+struct key_type keytype_des3 = {
+ KEYTYPE_DES3,
+ "des3",
+ 168,
+ 3 * sizeof(des_cblock),
+ 3 * sizeof(des_key_schedule),
+ DES3_random_key,
+ DES3_schedule,
+ des3_salt
+};
+
+struct key_type keytype_des3_derived = {
+ KEYTYPE_DES3,
+ "des3",
+ 168,
+ 3 * sizeof(des_cblock),
+ 3 * sizeof(des_key_schedule),
+ DES3_random_key,
+ DES3_schedule,
+ des3_salt_derived
+};
+
+struct key_type keytype_arcfour = {
+ KEYTYPE_ARCFOUR,
+ "arcfour",
+ 128,
+ 16,
+ sizeof(RC4_KEY),
+ ARCFOUR_random_key,
+ ARCFOUR_schedule,
+ arcfour_salt
+};
+
+struct key_type *keytypes[] = {
+ &keytype_null,
+ &keytype_des,
+ &keytype_des3_derived,
+ &keytype_des3,
+ &keytype_arcfour
+};
+
+static int num_keytypes = sizeof(keytypes) / sizeof(keytypes[0]);
+
+static struct key_type *
+_find_keytype(krb5_keytype type)
+{
+ int i;
+ for(i = 0; i < num_keytypes; i++)
+ if(keytypes[i]->type == type)
+ return keytypes[i];
+ return NULL;
+}
+
+
+struct salt_type des_salt[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ DES_string_to_key
+ },
+ {
+ KRB5_AFS3_SALT,
+ "afs3-salt",
+ DES_AFS3_string_to_key
+ },
+ { 0 }
+};
+
+struct salt_type des3_salt[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ DES3_string_to_key
+ },
+ { 0 }
+};
+
+struct salt_type des3_salt_derived[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ DES3_string_to_key_derived
+ },
+ { 0 }
+};
+
+struct salt_type arcfour_salt[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ ARCFOUR_string_to_key
+ },
+ { 0 }
+};
+
+krb5_error_code
+krb5_salttype_to_string (krb5_context context,
+ krb5_enctype etype,
+ krb5_salttype stype,
+ char **string)
+{
+ struct encryption_type *e;
+ struct salt_type *st;
+
+ e = _find_enctype (etype);
+ if (e == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ for (st = e->keytype->string_to_key; st && st->type; st++) {
+ if (st->type == stype) {
+ *string = strdup (st->name);
+ if (*string == NULL)
+ return ENOMEM;
+ return 0;
+ }
+ }
+ return HEIM_ERR_SALTTYPE_NOSUPP;
+}
+
+krb5_error_code
+krb5_string_to_salttype (krb5_context context,
+ krb5_enctype etype,
+ const char *string,
+ krb5_salttype *salttype)
+{
+ struct encryption_type *e;
+ struct salt_type *st;
+
+ e = _find_enctype (etype);
+ if (e == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ for (st = e->keytype->string_to_key; st && st->type; st++) {
+ if (strcasecmp (st->name, string) == 0) {
+ *salttype = st->type;
+ return 0;
+ }
+ }
+ return HEIM_ERR_SALTTYPE_NOSUPP;
+}
+
+krb5_error_code
+krb5_get_pw_salt(krb5_context context,
+ krb5_const_principal principal,
+ krb5_salt *salt)
+{
+ size_t len;
+ int i;
+ krb5_error_code ret;
+ char *p;
+
+ salt->salttype = KRB5_PW_SALT;
+ len = strlen(principal->realm);
+ for (i = 0; i < principal->name.name_string.len; ++i)
+ len += strlen(principal->name.name_string.val[i]);
+ ret = krb5_data_alloc (&salt->saltvalue, len);
+ if (ret)
+ return ret;
+ p = salt->saltvalue.data;
+ memcpy (p, principal->realm, strlen(principal->realm));
+ p += strlen(principal->realm);
+ for (i = 0; i < principal->name.name_string.len; ++i) {
+ memcpy (p,
+ principal->name.name_string.val[i],
+ strlen(principal->name.name_string.val[i]));
+ p += strlen(principal->name.name_string.val[i]);
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_free_salt(krb5_context context,
+ krb5_salt salt)
+{
+ krb5_data_free(&salt.saltvalue);
+ return 0;
+}
+
+krb5_error_code
+krb5_string_to_key_data (krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_principal principal,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ krb5_salt salt;
+
+ ret = krb5_get_pw_salt(context, principal, &salt);
+ if(ret)
+ return ret;
+ ret = krb5_string_to_key_data_salt(context, enctype, password, salt, key);
+ krb5_free_salt(context, salt);
+ return ret;
+}
+
+krb5_error_code
+krb5_string_to_key (krb5_context context,
+ krb5_enctype enctype,
+ const char *password,
+ krb5_principal principal,
+ krb5_keyblock *key)
+{
+ krb5_data pw;
+ pw.data = (void*)password;
+ pw.length = strlen(password);
+ return krb5_string_to_key_data(context, enctype, pw, principal, key);
+}
+
+krb5_error_code
+krb5_string_to_key_data_salt (krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ struct encryption_type *et =_find_enctype(enctype);
+ struct salt_type *st;
+ if(et == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ for(st = et->keytype->string_to_key; st && st->type; st++)
+ if(st->type == salt.salttype)
+ return (*st->string_to_key)(context, enctype, password, salt, key);
+ return HEIM_ERR_SALTTYPE_NOSUPP;
+}
+
+krb5_error_code
+krb5_string_to_key_salt (krb5_context context,
+ krb5_enctype enctype,
+ const char *password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ krb5_data pw;
+ pw.data = (void*)password;
+ pw.length = strlen(password);
+ return krb5_string_to_key_data_salt(context, enctype, pw, salt, key);
+}
+
+krb5_error_code
+krb5_keytype_to_string(krb5_context context,
+ krb5_keytype keytype,
+ char **string)
+{
+ struct key_type *kt = _find_keytype(keytype);
+ if(kt == NULL)
+ return KRB5_PROG_KEYTYPE_NOSUPP;
+ *string = strdup(kt->name);
+ if(*string == NULL)
+ return ENOMEM;
+ return 0;
+}
+
+krb5_error_code
+krb5_string_to_keytype(krb5_context context,
+ const char *string,
+ krb5_keytype *keytype)
+{
+ int i;
+ for(i = 0; i < num_keytypes; i++)
+ if(strcasecmp(keytypes[i]->name, string) == 0){
+ *keytype = keytypes[i]->type;
+ return 0;
+ }
+ return KRB5_PROG_KEYTYPE_NOSUPP;
+}
+
+krb5_error_code
+krb5_generate_random_keyblock(krb5_context context,
+ krb5_enctype type,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ struct encryption_type *et = _find_enctype(type);
+ if(et == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ ret = krb5_data_alloc(&key->keyvalue, et->keytype->size);
+ if(ret)
+ return ret;
+ key->keytype = type;
+ if(et->keytype->random_key)
+ (*et->keytype->random_key)(context, key);
+ else
+ krb5_generate_random_block(key->keyvalue.data,
+ key->keyvalue.length);
+ return 0;
+}
+
+static krb5_error_code
+_key_schedule(krb5_context context,
+ struct key_data *key)
+{
+ krb5_error_code ret;
+ struct encryption_type *et = _find_enctype(key->key->keytype);
+ struct key_type *kt = et->keytype;
+
+ if(kt->schedule == NULL)
+ return 0;
+ ALLOC(key->schedule, 1);
+ if(key->schedule == NULL)
+ return ENOMEM;
+ ret = krb5_data_alloc(key->schedule, kt->schedule_size);
+ if(ret) {
+ free(key->schedule);
+ key->schedule = NULL;
+ return ret;
+ }
+ (*kt->schedule)(context, key);
+ return 0;
+}
+
+/************************************************************
+ * *
+ ************************************************************/
+
+static void
+NONE_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+}
+
+static void
+CRC32_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ u_int32_t crc;
+ unsigned char *r = C->checksum.data;
+ _krb5_crc_init_table ();
+ crc = _krb5_crc_update (data, len, 0);
+ r[0] = crc & 0xff;
+ r[1] = (crc >> 8) & 0xff;
+ r[2] = (crc >> 16) & 0xff;
+ r[3] = (crc >> 24) & 0xff;
+}
+
+static void
+RSA_MD4_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md4 m;
+ md4_init(&m);
+ md4_update(&m, data, len);
+ md4_finito(&m, C->checksum.data);
+}
+
+static void
+RSA_MD4_DES_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *cksum)
+{
+ struct md4 md4;
+ des_cblock ivec;
+ unsigned char *p = cksum->checksum.data;
+
+ krb5_generate_random_block(p, 8);
+ md4_init(&md4);
+ md4_update(&md4, p, 8);
+ md4_update(&md4, data, len);
+ md4_finito(&md4, p + 8);
+ memset (&ivec, 0, sizeof(ivec));
+ des_cbc_encrypt((des_cblock*)p,
+ (des_cblock*)p,
+ 24,
+ key->schedule->data,
+ &ivec,
+ DES_ENCRYPT);
+}
+
+static krb5_error_code
+RSA_MD4_DES_verify(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md4 md4;
+ unsigned char tmp[24];
+ unsigned char res[16];
+ des_cblock ivec;
+ krb5_error_code ret = 0;
+
+ memset(&ivec, 0, sizeof(ivec));
+ des_cbc_encrypt(C->checksum.data,
+ (void*)tmp,
+ C->checksum.length,
+ key->schedule->data,
+ &ivec,
+ DES_DECRYPT);
+ md4_init(&md4);
+ md4_update(&md4, tmp, 8); /* confounder */
+ md4_update(&md4, data, len);
+ md4_finito(&md4, res);
+ if(memcmp(res, tmp + 8, sizeof(res)) != 0)
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ memset(tmp, 0, sizeof(tmp));
+ memset(res, 0, sizeof(res));
+ return ret;
+}
+
+static void
+RSA_MD5_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md5 m;
+ md5_init(&m);
+ md5_update(&m, data, len);
+ md5_finito(&m, C->checksum.data);
+}
+
+static void
+RSA_MD5_DES_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md5 md5;
+ des_cblock ivec;
+ unsigned char *p = C->checksum.data;
+
+ krb5_generate_random_block(p, 8);
+ md5_init(&md5);
+ md5_update(&md5, p, 8);
+ md5_update(&md5, data, len);
+ md5_finito(&md5, p + 8);
+ memset (&ivec, 0, sizeof(ivec));
+ des_cbc_encrypt((des_cblock*)p,
+ (des_cblock*)p,
+ 24,
+ key->schedule->data,
+ &ivec,
+ DES_ENCRYPT);
+}
+
+static krb5_error_code
+RSA_MD5_DES_verify(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md5 md5;
+ unsigned char tmp[24];
+ unsigned char res[16];
+ des_cblock ivec;
+ des_key_schedule *sched = key->schedule->data;
+ krb5_error_code ret = 0;
+
+ memset(&ivec, 0, sizeof(ivec));
+ des_cbc_encrypt(C->checksum.data,
+ (void*)tmp,
+ C->checksum.length,
+ sched[0],
+ &ivec,
+ DES_DECRYPT);
+ md5_init(&md5);
+ md5_update(&md5, tmp, 8); /* confounder */
+ md5_update(&md5, data, len);
+ md5_finito(&md5, res);
+ if(memcmp(res, tmp + 8, sizeof(res)) != 0)
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ memset(tmp, 0, sizeof(tmp));
+ memset(res, 0, sizeof(res));
+ return ret;
+}
+
+static void
+RSA_MD5_DES3_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md5 md5;
+ des_cblock ivec;
+ unsigned char *p = C->checksum.data;
+ des_key_schedule *sched = key->schedule->data;
+
+ krb5_generate_random_block(p, 8);
+ md5_init(&md5);
+ md5_update(&md5, p, 8);
+ md5_update(&md5, data, len);
+ md5_finito(&md5, p + 8);
+ memset (&ivec, 0, sizeof(ivec));
+ des_ede3_cbc_encrypt((des_cblock*)p,
+ (des_cblock*)p,
+ 24,
+ sched[0], sched[1], sched[2],
+ &ivec,
+ DES_ENCRYPT);
+}
+
+static krb5_error_code
+RSA_MD5_DES3_verify(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md5 md5;
+ unsigned char tmp[24];
+ unsigned char res[16];
+ des_cblock ivec;
+ des_key_schedule *sched = key->schedule->data;
+ krb5_error_code ret = 0;
+
+ memset(&ivec, 0, sizeof(ivec));
+ des_ede3_cbc_encrypt(C->checksum.data,
+ (void*)tmp,
+ C->checksum.length,
+ sched[0], sched[1], sched[2],
+ &ivec,
+ DES_DECRYPT);
+ md5_init(&md5);
+ md5_update(&md5, tmp, 8); /* confounder */
+ md5_update(&md5, data, len);
+ md5_finito(&md5, res);
+ if(memcmp(res, tmp + 8, sizeof(res)) != 0)
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ memset(tmp, 0, sizeof(tmp));
+ memset(res, 0, sizeof(res));
+ return ret;
+}
+
+static void
+SHA1_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct sha m;
+ sha_init(&m);
+ sha_update(&m, data, len);
+ sha_finito(&m, C->checksum.data);
+}
+
+/* HMAC according to RFC2104 */
+static void
+hmac(krb5_context context,
+ struct checksum_type *cm,
+ void *data,
+ size_t len,
+ struct key_data *keyblock,
+ Checksum *result)
+{
+ unsigned char *ipad, *opad;
+ unsigned char *key;
+ size_t key_len;
+ int i;
+
+ if(keyblock->key->keyvalue.length > cm->blocksize){
+ (*cm->checksum)(context,
+ keyblock,
+ keyblock->key->keyvalue.data,
+ keyblock->key->keyvalue.length,
+ result);
+ key = result->checksum.data;
+ key_len = result->checksum.length;
+ } else {
+ key = keyblock->key->keyvalue.data;
+ key_len = keyblock->key->keyvalue.length;
+ }
+ ipad = malloc(cm->blocksize + len);
+ opad = malloc(cm->blocksize + cm->checksumsize);
+ memset(ipad, 0x36, cm->blocksize);
+ memset(opad, 0x5c, cm->blocksize);
+ for(i = 0; i < key_len; i++){
+ ipad[i] ^= key[i];
+ opad[i] ^= key[i];
+ }
+ memcpy(ipad + cm->blocksize, data, len);
+ (*cm->checksum)(context, keyblock, ipad, cm->blocksize + len, result);
+ memcpy(opad + cm->blocksize, result->checksum.data,
+ result->checksum.length);
+ (*cm->checksum)(context, keyblock, opad,
+ cm->blocksize + cm->checksumsize, result);
+ memset(ipad, 0, cm->blocksize + len);
+ free(ipad);
+ memset(opad, 0, cm->blocksize + cm->checksumsize);
+ free(opad);
+}
+
+static void
+HMAC_SHA1_DES3_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *result)
+{
+ struct checksum_type *c = _find_checksum(CKSUMTYPE_SHA1);
+
+ hmac(context, c, data, len, key, result);
+}
+
+struct checksum_type checksum_none = {
+ CKSUMTYPE_NONE,
+ "none",
+ 1,
+ 0,
+ 0,
+ NONE_checksum,
+ NULL
+};
+struct checksum_type checksum_crc32 = {
+ CKSUMTYPE_CRC32,
+ "crc32",
+ 1,
+ 4,
+ 0,
+ CRC32_checksum,
+ NULL
+};
+struct checksum_type checksum_rsa_md4 = {
+ CKSUMTYPE_RSA_MD4,
+ "rsa-md4",
+ 64,
+ 16,
+ F_CPROOF,
+ RSA_MD4_checksum,
+ NULL
+};
+struct checksum_type checksum_rsa_md4_des = {
+ CKSUMTYPE_RSA_MD4_DES,
+ "rsa-md4-des",
+ 64,
+ 24,
+ F_KEYED | F_CPROOF | F_VARIANT,
+ RSA_MD4_DES_checksum,
+ RSA_MD4_DES_verify
+};
+#if 0
+struct checksum_type checksum_des_mac = {
+ CKSUMTYPE_DES_MAC,
+ "des-mac",
+ 0,
+ 0,
+ 0,
+ DES_MAC_checksum,
+};
+struct checksum_type checksum_des_mac_k = {
+ CKSUMTYPE_DES_MAC_K,
+ "des-mac-k",
+ 0,
+ 0,
+ 0,
+ DES_MAC_K_checksum,
+};
+struct checksum_type checksum_rsa_md4_des_k = {
+ CKSUMTYPE_RSA_MD4_DES_K,
+ "rsa-md4-des-k",
+ 0,
+ 0,
+ 0,
+ RSA_MD4_DES_K_checksum,
+ RSA_MD4_DES_K_verify,
+};
+#endif
+struct checksum_type checksum_rsa_md5 = {
+ CKSUMTYPE_RSA_MD5,
+ "rsa-md5",
+ 64,
+ 16,
+ F_CPROOF,
+ RSA_MD5_checksum,
+ NULL
+};
+struct checksum_type checksum_rsa_md5_des = {
+ CKSUMTYPE_RSA_MD5_DES,
+ "rsa-md5-des",
+ 64,
+ 24,
+ F_KEYED | F_CPROOF | F_VARIANT,
+ RSA_MD5_DES_checksum,
+ RSA_MD5_DES_verify,
+};
+struct checksum_type checksum_rsa_md5_des3 = {
+ CKSUMTYPE_RSA_MD5_DES3,
+ "rsa-md5-des3",
+ 64,
+ 24,
+ F_KEYED | F_CPROOF | F_VARIANT,
+ RSA_MD5_DES3_checksum,
+ RSA_MD5_DES3_verify,
+};
+struct checksum_type checksum_sha1 = {
+ CKSUMTYPE_SHA1,
+ "sha1",
+ 64,
+ 20,
+ F_CPROOF,
+ SHA1_checksum,
+ NULL
+};
+struct checksum_type checksum_hmac_sha1_des3 = {
+ CKSUMTYPE_HMAC_SHA1_DES3,
+ "hmac-sha1-des3",
+ 64,
+ 20,
+ F_KEYED | F_CPROOF | F_DERIVED,
+ HMAC_SHA1_DES3_checksum,
+ NULL
+};
+
+struct checksum_type *checksum_types[] = {
+ &checksum_none,
+ &checksum_crc32,
+ &checksum_rsa_md4,
+ &checksum_rsa_md4_des,
+#if 0
+ &checksum_des_mac,
+ &checksum_des_mac_k,
+ &checksum_rsa_md4_des_k,
+#endif
+ &checksum_rsa_md5,
+ &checksum_rsa_md5_des,
+ &checksum_rsa_md5_des3,
+ &checksum_sha1,
+ &checksum_hmac_sha1_des3
+};
+
+static int num_checksums = sizeof(checksum_types) / sizeof(checksum_types[0]);
+
+static struct checksum_type *
+_find_checksum(krb5_cksumtype type)
+{
+ int i;
+ for(i = 0; i < num_checksums; i++)
+ if(checksum_types[i]->type == type)
+ return checksum_types[i];
+ return NULL;
+}
+
+static krb5_error_code
+get_checksum_key(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage, /* not krb5_key_usage */
+ struct checksum_type *ct,
+ struct key_data **key)
+{
+ krb5_error_code ret = 0;
+
+ if(ct->flags & F_DERIVED)
+ ret = _get_derived_key(context, crypto, usage, key);
+ else if(ct->flags & F_VARIANT) {
+ int i;
+
+ *key = _new_derived_key(crypto, 0xff/* KRB5_KU_RFC1510_VARIANT */);
+ if(*key == NULL)
+ return ENOMEM;
+ ret = krb5_copy_keyblock(context, crypto->key.key, &(*key)->key);
+ if(ret)
+ return ret;
+ for(i = 0; i < (*key)->key->keyvalue.length; i++)
+ ((unsigned char*)(*key)->key->keyvalue.data)[i] ^= 0xF0;
+ } else {
+ *key = &crypto->key;
+ }
+ if(ret == 0)
+ ret = _key_schedule(context, *key);
+ return ret;
+}
+
+static krb5_error_code
+do_checksum (krb5_context context,
+ struct checksum_type *ct,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ Checksum *result)
+{
+ krb5_error_code ret;
+ struct key_data *dkey;
+ int keyed_checksum;
+
+ keyed_checksum = (ct->flags & F_KEYED) != 0;
+ if(keyed_checksum && crypto == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
+ if(keyed_checksum)
+ ret = get_checksum_key(context, crypto, usage, ct, &dkey);
+ else
+ dkey = NULL;
+ result->cksumtype = ct->type;
+ krb5_data_alloc(&result->checksum, ct->checksumsize);
+ (*ct->checksum)(context, dkey, data, len, result);
+ return 0;
+}
+
+static krb5_error_code
+create_checksum(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage, /* not krb5_key_usage */
+ krb5_cksumtype type, /* if crypto == NULL */
+ void *data,
+ size_t len,
+ Checksum *result)
+{
+ struct checksum_type *ct;
+
+ if(crypto) {
+ ct = crypto->et->keyed_checksum;
+ if(ct == NULL)
+ ct = crypto->et->cksumtype;
+ } else
+ ct = _find_checksum(type);
+ if(ct == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP;
+ return do_checksum (context, ct, crypto, usage, data, len, result);
+}
+
+krb5_error_code
+krb5_create_checksum(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage_or_type,
+ void *data,
+ size_t len,
+ Checksum *result)
+{
+ return create_checksum(context, crypto,
+ CHECKSUM_USAGE(usage_or_type),
+ usage_or_type, data, len, result);
+}
+
+static krb5_error_code
+verify_checksum(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage, /* not krb5_key_usage */
+ void *data,
+ size_t len,
+ Checksum *cksum)
+{
+ krb5_error_code ret;
+ struct key_data *dkey;
+ int keyed_checksum;
+ Checksum c;
+ struct checksum_type *ct;
+
+ ct = _find_checksum(cksum->cksumtype);
+ if(ct == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP;
+ if(ct->checksumsize != cksum->checksum.length)
+ return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */
+ keyed_checksum = (ct->flags & F_KEYED) != 0;
+ if(keyed_checksum && crypto == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
+ if(keyed_checksum)
+ ret = get_checksum_key(context, crypto, usage, ct, &dkey);
+ else
+ dkey = NULL;
+ if(ct->verify)
+ return (*ct->verify)(context, dkey, data, len, cksum);
+
+ ret = krb5_data_alloc (&c.checksum, ct->checksumsize);
+ if (ret)
+ return ret;
+
+ (*ct->checksum)(context, dkey, data, len, &c);
+
+ if(c.checksum.length != cksum->checksum.length ||
+ memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length))
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ else
+ ret = 0;
+ krb5_data_free (&c.checksum);
+ return ret;
+}
+
+krb5_error_code
+krb5_verify_checksum(krb5_context context,
+ krb5_crypto crypto,
+ krb5_key_usage usage,
+ void *data,
+ size_t len,
+ Checksum *cksum)
+{
+ return verify_checksum(context, crypto,
+ CHECKSUM_USAGE(usage), data, len, cksum);
+}
+
+krb5_error_code
+krb5_checksumsize(krb5_context context,
+ krb5_cksumtype type,
+ size_t *size)
+{
+ struct checksum_type *ct = _find_checksum(type);
+ if(ct == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP;
+ *size = ct->checksumsize;
+ return 0;
+}
+
+krb5_boolean
+krb5_checksum_is_keyed(krb5_context context,
+ krb5_cksumtype type)
+{
+ struct checksum_type *ct = _find_checksum(type);
+ if(ct == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP;
+ return ct->flags & F_KEYED;
+}
+
+krb5_boolean
+krb5_checksum_is_collision_proof(krb5_context context,
+ krb5_cksumtype type)
+{
+ struct checksum_type *ct = _find_checksum(type);
+ if(ct == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP;
+ return ct->flags & F_CPROOF;
+}
+
+/************************************************************
+ * *
+ ************************************************************/
+
+static void
+NULL_encrypt(struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encrypt)
+{
+}
+
+static void
+DES_CBC_encrypt_null_ivec(struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encrypt)
+{
+ des_cblock ivec;
+ des_key_schedule *s = key->schedule->data;
+ memset(&ivec, 0, sizeof(ivec));
+ des_cbc_encrypt(data, data, len, *s, &ivec, encrypt);
+}
+
+static void
+DES_CBC_encrypt_key_ivec(struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encrypt)
+{
+ des_cblock ivec;
+ des_key_schedule *s = key->schedule->data;
+ memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
+ des_cbc_encrypt(data, data, len, *s, &ivec, encrypt);
+}
+
+static void
+DES3_CBC_encrypt(struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encrypt)
+{
+ des_cblock ivec;
+ des_key_schedule *s = key->schedule->data;
+ memset(&ivec, 0, sizeof(ivec));
+ des_ede3_cbc_encrypt(data, data, len, s[0], s[1], s[2], &ivec, encrypt);
+}
+
+static void
+ARCFOUR_encrypt(struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encrypt)
+{
+
+}
+
+/*
+ * these should currently be in reverse preference order.
+ */
+
+static struct encryption_type etypes[] = {
+ {
+ ETYPE_NULL,
+ "null",
+ 1,
+ 0,
+ &keytype_null,
+ &checksum_none,
+ NULL,
+ 0,
+ NULL_encrypt,
+ },
+ {
+ ETYPE_DES_CBC_CRC,
+ "des-cbc-crc",
+ 8,
+ 8,
+ &keytype_des,
+ &checksum_crc32,
+ NULL,
+ 0,
+ DES_CBC_encrypt_key_ivec,
+ },
+ {
+ ETYPE_DES_CBC_MD4,
+ "des-cbc-md4",
+ 8,
+ 8,
+ &keytype_des,
+ &checksum_rsa_md4,
+ &checksum_rsa_md4_des,
+ 0,
+ DES_CBC_encrypt_null_ivec,
+ },
+ {
+ ETYPE_DES_CBC_MD5,
+ "des-cbc-md5",
+ 8,
+ 8,
+ &keytype_des,
+ &checksum_rsa_md5,
+ &checksum_rsa_md5_des,
+ 0,
+ DES_CBC_encrypt_null_ivec,
+ },
+ {
+ ETYPE_DES3_CBC_MD5,
+ "des3-cbc-md5",
+ 8,
+ 8,
+ &keytype_des3,
+ &checksum_rsa_md5,
+ &checksum_rsa_md5_des3,
+ 0,
+ DES3_CBC_encrypt,
+ },
+ {
+ ETYPE_DES3_CBC_SHA1,
+ "des3-cbc-sha1",
+ 8,
+ 8,
+ &keytype_des3_derived,
+ &checksum_sha1,
+ &checksum_hmac_sha1_des3,
+ F_DERIVED,
+ DES3_CBC_encrypt,
+ },
+ {
+ ETYPE_OLD_DES3_CBC_SHA1,
+ "old-des3-cbc-sha1",
+ 8,
+ 8,
+ &keytype_des3,
+ &checksum_sha1,
+ &checksum_hmac_sha1_des3,
+ 0,
+ DES3_CBC_encrypt,
+ },
+ {
+ ETYPE_DES_CBC_NONE,
+ "des-cbc-none",
+ 8,
+ 0,
+ &keytype_des,
+ &checksum_none,
+ NULL,
+ F_PSEUDO,
+ DES_CBC_encrypt_null_ivec,
+ },
+ {
+ ETYPE_DES3_CBC_NONE,
+ "des3-cbc-none",
+ 8,
+ 0,
+ &keytype_des3_derived,
+ &checksum_none,
+ NULL,
+ F_PSEUDO,
+ DES_CBC_encrypt_null_ivec,
+ },
+};
+
+static unsigned num_etypes = sizeof(etypes) / sizeof(etypes[0]);
+
+
+static struct encryption_type *
+_find_enctype(krb5_enctype type)
+{
+ int i;
+ for(i = 0; i < num_etypes; i++)
+ if(etypes[i].type == type)
+ return &etypes[i];
+ return NULL;
+}
+
+
+krb5_error_code
+krb5_enctype_to_string(krb5_context context,
+ krb5_enctype etype,
+ char **string)
+{
+ struct encryption_type *e;
+ e = _find_enctype(etype);
+ if(e == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ *string = strdup(e->name);
+ if(*string == NULL)
+ return ENOMEM;
+ return 0;
+}
+
+krb5_error_code
+krb5_string_to_enctype(krb5_context context,
+ const char *string,
+ krb5_enctype *etype)
+{
+ int i;
+ for(i = 0; i < num_etypes; i++)
+ if(strcasecmp(etypes[i].name, string) == 0){
+ *etype = etypes[i].type;
+ return 0;
+ }
+ return KRB5_PROG_ETYPE_NOSUPP;
+}
+
+krb5_error_code
+krb5_enctype_to_keytype(krb5_context context,
+ krb5_enctype etype,
+ krb5_keytype *keytype)
+{
+ struct encryption_type *e = _find_enctype(etype);
+ if(e == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ *keytype = e->keytype->type; /* XXX */
+ return 0;
+}
+
+#if 0
+krb5_error_code
+krb5_keytype_to_enctype(krb5_context context,
+ krb5_keytype keytype,
+ krb5_enctype *etype)
+{
+ struct key_type *kt = _find_keytype(keytype);
+ krb5_warnx(context, "krb5_keytype_to_enctype(%u)", keytype);
+ if(kt == NULL)
+ return KRB5_PROG_KEYTYPE_NOSUPP;
+ *etype = kt->best_etype;
+ return 0;
+}
+#endif
+
+krb5_error_code
+krb5_keytype_to_enctypes (krb5_context context,
+ krb5_keytype keytype,
+ unsigned *len,
+ int **val)
+{
+ int i;
+ unsigned n = 0;
+ int *ret;
+
+ for (i = num_etypes - 1; i >= 0; --i) {
+ if (etypes[i].keytype->type == keytype
+ && !(etypes[i].flags & F_PSEUDO))
+ ++n;
+ }
+ ret = malloc(n * sizeof(int));
+ if (ret == NULL && n != 0)
+ return ENOMEM;
+ n = 0;
+ for (i = num_etypes - 1; i >= 0; --i) {
+ if (etypes[i].keytype->type == keytype
+ && !(etypes[i].flags & F_PSEUDO))
+ ret[n++] = etypes[i].type;
+ }
+ *len = n;
+ *val = ret;
+ return 0;
+}
+
+/*
+ * First take the configured list of etypes for `keytype' if available,
+ * else, do `krb5_keytype_to_enctypes'.
+ */
+
+krb5_error_code
+krb5_keytype_to_enctypes_default (krb5_context context,
+ krb5_keytype keytype,
+ unsigned *len,
+ int **val)
+{
+ int i, n;
+ int *ret;
+
+ if (keytype != KEYTYPE_DES || context->etypes_des == NULL)
+ return krb5_keytype_to_enctypes (context, keytype, len, val);
+
+ for (n = 0; context->etypes_des[n]; ++n)
+ ;
+ ret = malloc (n * sizeof(*ret));
+ if (ret == NULL && n != 0)
+ return ENOMEM;
+ for (i = 0; i < n; ++i)
+ ret[i] = context->etypes_des[i];
+ *len = n;
+ *val = ret;
+ return 0;
+}
+
+krb5_error_code
+krb5_enctype_valid(krb5_context context,
+ krb5_enctype etype)
+{
+ return _find_enctype(etype) != NULL;
+}
+
+/* if two enctypes have compatible keys */
+krb5_boolean
+krb5_enctypes_compatible_keys(krb5_context context,
+ krb5_enctype etype1,
+ krb5_enctype etype2)
+{
+ struct encryption_type *e1 = _find_enctype(etype1);
+ struct encryption_type *e2 = _find_enctype(etype2);
+ return e1 != NULL && e2 != NULL && e1->keytype == e2->keytype;
+}
+
+static krb5_boolean
+derived_crypto(krb5_context context,
+ krb5_crypto crypto)
+{
+ return (crypto->et->flags & F_DERIVED) != 0;
+}
+
+
+#define CHECKSUMSIZE(C) ((C)->checksumsize)
+#define CHECKSUMTYPE(C) ((C)->type)
+
+static krb5_error_code
+encrypt_internal_derived(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ size_t sz, block_sz, checksum_sz;
+ Checksum cksum;
+ unsigned char *p, *q;
+ krb5_error_code ret;
+ struct key_data *dkey;
+ struct encryption_type *et = crypto->et;
+
+ checksum_sz = CHECKSUMSIZE(et->keyed_checksum);
+
+ sz = et->confoundersize + /* 4 - length */ len;
+ block_sz = (sz + et->blocksize - 1) &~ (et->blocksize - 1); /* pad */
+ p = calloc(1, block_sz + checksum_sz);
+ if(p == NULL)
+ return ENOMEM;
+
+ q = p;
+ krb5_generate_random_block(q, et->confoundersize); /* XXX */
+ q += et->confoundersize;
+ memcpy(q, data, len);
+
+ ret = create_checksum(context,
+ crypto,
+ INTEGRITY_USAGE(usage),
+ 0,
+ p,
+ block_sz,
+ &cksum);
+ if(ret == 0 && cksum.checksum.length != checksum_sz)
+ ret = KRB5_CRYPTO_INTERNAL;
+ if(ret) {
+ memset(p, 0, block_sz + checksum_sz);
+ free(p);
+ return ret;
+ }
+ memcpy(p + block_sz, cksum.checksum.data, cksum.checksum.length);
+ ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
+ if(ret) {
+ memset(p, 0, block_sz + checksum_sz);
+ free(p);
+ return ret;
+ }
+ ret = _key_schedule(context, dkey);
+ if(ret) {
+ memset(p, 0, block_sz);
+ free(p);
+ return ret;
+ }
+#ifdef CRYPTO_DEBUG
+ krb5_crypto_debug(context, 1, block_sz, dkey->key);
+#endif
+ (*et->encrypt)(dkey, p, block_sz, 1);
+ result->data = p;
+ result->length = block_sz + checksum_sz;
+ return 0;
+}
+
+static krb5_error_code
+encrypt_internal(krb5_context context,
+ krb5_crypto crypto,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ size_t sz, block_sz, checksum_sz;
+ Checksum cksum;
+ unsigned char *p, *q;
+ krb5_error_code ret;
+ struct encryption_type *et = crypto->et;
+
+ checksum_sz = CHECKSUMSIZE(et->cksumtype);
+
+ sz = et->confoundersize + checksum_sz + len;
+ block_sz = (sz + et->blocksize - 1) &~ (et->blocksize - 1); /* pad */
+ p = calloc(1, block_sz);
+ if(p == NULL)
+ return ENOMEM;
+
+ q = p;
+ krb5_generate_random_block(q, et->confoundersize); /* XXX */
+ q += et->confoundersize;
+ memset(q, 0, checksum_sz);
+ q += checksum_sz;
+ memcpy(q, data, len);
+
+ ret = create_checksum(context,
+ NULL,
+ 0,
+ CHECKSUMTYPE(et->cksumtype),
+ p,
+ block_sz,
+ &cksum);
+ if(ret == 0 && cksum.checksum.length != checksum_sz) {
+ free_Checksum (&cksum);
+ ret = KRB5_CRYPTO_INTERNAL;
+ }
+ if(ret) {
+ memset(p, 0, block_sz);
+ free(p);
+ free_Checksum(&cksum);
+ return ret;
+ }
+ memcpy(p + et->confoundersize, cksum.checksum.data, cksum.checksum.length);
+ free_Checksum(&cksum);
+ ret = _key_schedule(context, &crypto->key);
+ if(ret) {
+ memset(p, 0, block_sz);
+ free(p);
+ return ret;
+ }
+#ifdef CRYPTO_DEBUG
+ krb5_crypto_debug(context, 1, block_sz, crypto->key.key);
+#endif
+ (*et->encrypt)(&crypto->key, p, block_sz, 1);
+ result->data = p;
+ result->length = block_sz;
+ return 0;
+}
+
+static krb5_error_code
+decrypt_internal_derived(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ size_t checksum_sz;
+ Checksum cksum;
+ unsigned char *p;
+ krb5_error_code ret;
+ struct key_data *dkey;
+ struct encryption_type *et = crypto->et;
+ unsigned long l;
+
+ p = malloc(len);
+ if(len != 0 && p == NULL)
+ return ENOMEM;
+ memcpy(p, data, len);
+
+ checksum_sz = CHECKSUMSIZE(et->keyed_checksum);
+ len -= checksum_sz;
+
+ ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+ ret = _key_schedule(context, dkey);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+#ifdef CRYPTO_DEBUG
+ krb5_crypto_debug(context, 0, len, dkey->key);
+#endif
+ (*et->encrypt)(dkey, p, len, 0);
+
+ cksum.checksum.data = p + len;
+ cksum.checksum.length = checksum_sz;
+ cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum);
+
+ ret = verify_checksum(context,
+ crypto,
+ INTEGRITY_USAGE(usage),
+ p,
+ len,
+ &cksum);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+ l = len - et->confoundersize;
+ memmove(p, p + et->confoundersize, l);
+ result->data = realloc(p, l);
+ if(p == NULL) {
+ free(p);
+ return ENOMEM;
+ }
+ result->length = l;
+ return 0;
+}
+
+static krb5_error_code
+decrypt_internal(krb5_context context,
+ krb5_crypto crypto,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ krb5_error_code ret;
+ unsigned char *p;
+ Checksum cksum;
+ size_t checksum_sz, l;
+ struct encryption_type *et = crypto->et;
+
+ checksum_sz = CHECKSUMSIZE(et->cksumtype);
+ p = malloc(len);
+ if(len != 0 && p == NULL)
+ return ENOMEM;
+ memcpy(p, data, len);
+
+ ret = _key_schedule(context, &crypto->key);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+#ifdef CRYPTO_DEBUG
+ krb5_crypto_debug(context, 0, len, crypto->key.key);
+#endif
+ (*et->encrypt)(&crypto->key, p, len, 0);
+ ret = krb5_data_copy(&cksum.checksum, p + et->confoundersize, checksum_sz);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+ memset(p + et->confoundersize, 0, checksum_sz);
+ cksum.cksumtype = CHECKSUMTYPE(et->cksumtype);
+ ret = verify_checksum(context, NULL, 0, p, len, &cksum);
+ free_Checksum(&cksum);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+ l = len - et->confoundersize - checksum_sz;
+ memmove(p, p + et->confoundersize + checksum_sz, l);
+ result->data = realloc(p, l);
+ if(result->data == NULL) {
+ free(p);
+ return ENOMEM;
+ }
+ result->length = l;
+ return 0;
+}
+
+krb5_error_code
+krb5_encrypt(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ if(derived_crypto(context, crypto))
+ return encrypt_internal_derived(context, crypto, usage,
+ data, len, result);
+ else
+ return encrypt_internal(context, crypto, data, len, result);
+}
+
+krb5_error_code
+krb5_encrypt_EncryptedData(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ int kvno,
+ EncryptedData *result)
+{
+ result->etype = CRYPTO_ETYPE(crypto);
+ if(kvno){
+ ALLOC(result->kvno, 1);
+ *result->kvno = kvno;
+ }else
+ result->kvno = NULL;
+ return krb5_encrypt(context, crypto, usage, data, len, &result->cipher);
+}
+
+krb5_error_code
+krb5_decrypt(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ if(derived_crypto(context, crypto))
+ return decrypt_internal_derived(context, crypto, usage,
+ data, len, result);
+ else
+ return decrypt_internal(context, crypto, data, len, result);
+}
+
+krb5_error_code
+krb5_decrypt_EncryptedData(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ EncryptedData *e,
+ krb5_data *result)
+{
+ return krb5_decrypt(context, crypto, usage,
+ e->cipher.data, e->cipher.length, result);
+}
+
+/************************************************************
+ * *
+ ************************************************************/
+
+void
+krb5_generate_random_block(void *buf, size_t len)
+{
+ des_cblock key, out;
+ static des_cblock counter;
+ static des_key_schedule schedule;
+ int i;
+ static int initialized = 0;
+
+ if(!initialized) {
+ des_new_random_key(&key);
+ des_set_key(&key, schedule);
+ memset(&key, 0, sizeof(key));
+ des_new_random_key(&counter);
+ }
+ while(len > 0) {
+ des_ecb_encrypt(&counter, &out, schedule, DES_ENCRYPT);
+ for(i = 7; i >=0; i--)
+ if(counter[i]++)
+ break;
+ memcpy(buf, out, min(len, sizeof(out)));
+ len -= min(len, sizeof(out));
+ buf = (char*)buf + sizeof(out);
+ }
+}
+
+static void
+DES3_postproc(krb5_context context,
+ unsigned char *k, size_t len, struct key_data *key)
+{
+ unsigned char x[24];
+ int i, j;
+
+ memset(x, 0, sizeof(x));
+ for (i = 0; i < 3; ++i) {
+ unsigned char foo;
+
+ for (j = 0; j < 7; ++j) {
+ unsigned char b = k[7 * i + j];
+
+ x[8 * i + j] = b;
+ }
+ foo = 0;
+ for (j = 6; j >= 0; --j) {
+ foo |= k[7 * i + j] & 1;
+ foo <<= 1;
+ }
+ x[8 * i + 7] = foo;
+ }
+ k = key->key->keyvalue.data;
+ memcpy(k, x, 24);
+ memset(x, 0, sizeof(x));
+ if (key->schedule) {
+ krb5_free_data(context, key->schedule);
+ key->schedule = NULL;
+ }
+ des_set_odd_parity((des_cblock*)k);
+ des_set_odd_parity((des_cblock*)(k + 8));
+ des_set_odd_parity((des_cblock*)(k + 16));
+}
+
+static krb5_error_code
+derive_key(krb5_context context,
+ struct encryption_type *et,
+ struct key_data *key,
+ void *constant,
+ size_t len)
+{
+ unsigned char *k;
+ unsigned int nblocks = 0, i;
+ krb5_error_code ret = 0;
+
+ struct key_type *kt = et->keytype;
+ ret = _key_schedule(context, key);
+ if(ret)
+ return ret;
+ if(et->blocksize * 8 < kt->bits ||
+ len != et->blocksize) {
+ nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8);
+ k = malloc(nblocks * et->blocksize);
+ if(k == NULL)
+ return ENOMEM;
+ _krb5_n_fold(constant, len, k, et->blocksize);
+ for(i = 0; i < nblocks; i++) {
+ if(i > 0)
+ memcpy(k + i * et->blocksize,
+ k + (i - 1) * et->blocksize,
+ et->blocksize);
+ (*et->encrypt)(key, k + i * et->blocksize, et->blocksize, 1);
+ }
+ } else {
+ void *c = malloc(len);
+ size_t res_len = (kt->bits + 7) / 8;
+
+ if(len != 0 && c == NULL)
+ return ENOMEM;
+ memcpy(c, constant, len);
+ (*et->encrypt)(key, c, len, 1);
+ k = malloc(res_len);
+ if(res_len != 0 && k == NULL)
+ return ENOMEM;
+ _krb5_n_fold(c, len, k, res_len);
+ free(c);
+ }
+
+ /* XXX keytype dependent post-processing */
+ switch(kt->type) {
+ case KEYTYPE_DES3:
+ DES3_postproc(context, k, nblocks * et->blocksize, key);
+ break;
+ default:
+ krb5_warnx(context, "derive_key() called with unknown keytype (%u)",
+ kt->type);
+ ret = KRB5_CRYPTO_INTERNAL;
+ break;
+ }
+ memset(k, 0, nblocks * et->blocksize);
+ free(k);
+ return ret;
+}
+
+static struct key_data *
+_new_derived_key(krb5_crypto crypto, unsigned usage)
+{
+ struct key_usage *d = crypto->key_usage;
+ d = realloc(d, (crypto->num_key_usage + 1) * sizeof(*d));
+ if(d == NULL)
+ return NULL;
+ crypto->key_usage = d;
+ d += crypto->num_key_usage++;
+ memset(d, 0, sizeof(*d));
+ d->usage = usage;
+ return &d->key;
+}
+
+static krb5_error_code
+_get_derived_key(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ struct key_data **key)
+{
+ int i;
+ struct key_data *d;
+ unsigned char constant[5];
+
+ for(i = 0; i < crypto->num_key_usage; i++)
+ if(crypto->key_usage[i].usage == usage) {
+ *key = &crypto->key_usage[i].key;
+ return 0;
+ }
+ d = _new_derived_key(crypto, usage);
+ if(d == NULL)
+ return ENOMEM;
+ krb5_copy_keyblock(context, crypto->key.key, &d->key);
+ _krb5_put_int(constant, usage, 5);
+ derive_key(context, crypto->et, d, constant, sizeof(constant));
+ *key = d;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_crypto_init(krb5_context context,
+ krb5_keyblock *key,
+ krb5_enctype etype,
+ krb5_crypto *crypto)
+{
+ krb5_error_code ret;
+ ALLOC(*crypto, 1);
+ if(*crypto == NULL)
+ return ENOMEM;
+ if(etype == ETYPE_NULL)
+ etype = key->keytype;
+ (*crypto)->et = _find_enctype(etype);
+ if((*crypto)->et == NULL) {
+ free(*crypto);
+ return KRB5_PROG_ETYPE_NOSUPP;
+ }
+ ret = krb5_copy_keyblock(context, key, &(*crypto)->key.key);
+ if(ret) {
+ free(*crypto);
+ return ret;
+ }
+ (*crypto)->key.schedule = NULL;
+ (*crypto)->num_key_usage = 0;
+ (*crypto)->key_usage = NULL;
+ return 0;
+}
+
+static void
+free_key_data(krb5_context context, struct key_data *key)
+{
+ krb5_free_keyblock(context, key->key);
+ if(key->schedule) {
+ memset(key->schedule->data, 0, key->schedule->length);
+ krb5_free_data(context, key->schedule);
+ }
+}
+
+static void
+free_key_usage(krb5_context context, struct key_usage *ku)
+{
+ free_key_data(context, &ku->key);
+}
+
+krb5_error_code
+krb5_crypto_destroy(krb5_context context,
+ krb5_crypto crypto)
+{
+ int i;
+
+ for(i = 0; i < crypto->num_key_usage; i++)
+ free_key_usage(context, &crypto->key_usage[i]);
+ free(crypto->key_usage);
+ free_key_data(context, &crypto->key);
+ free (crypto);
+ return 0;
+}
+
+krb5_error_code
+krb5_string_to_key_derived(krb5_context context,
+ const void *str,
+ size_t len,
+ krb5_enctype etype,
+ krb5_keyblock *key)
+{
+ struct encryption_type *et = _find_enctype(etype);
+ krb5_error_code ret;
+ struct key_data kd;
+ u_char *tmp;
+
+ if(et == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ ALLOC(kd.key, 1);
+ kd.key->keytype = etype;
+ tmp = malloc (et->keytype->bits / 8);
+ _krb5_n_fold(str, len, tmp, et->keytype->bits / 8);
+ krb5_data_alloc(&kd.key->keyvalue, et->keytype->size);
+ kd.schedule = NULL;
+ DES3_postproc (context, tmp, et->keytype->bits / 8, &kd); /* XXX */
+ ret = derive_key(context,
+ et,
+ &kd,
+ "kerberos", /* XXX well known constant */
+ strlen("kerberos"));
+ ret = krb5_copy_keyblock_contents(context, kd.key, key);
+ free_key_data(context, &kd);
+ return ret;
+}
+
+/*
+ * Return the size of an encrypted packet of length `data_len'
+ */
+
+size_t
+krb5_get_wrapped_length (krb5_context context,
+ krb5_crypto crypto,
+ size_t data_len)
+{
+ struct encryption_type *et = crypto->et;
+ size_t blocksize = et->blocksize;
+ size_t res;
+
+ res = (data_len + blocksize - 1) / blocksize * blocksize;
+ res = res + et->confoundersize + et->cksumtype->checksumsize;
+ return res;
+}
+
+#ifdef CRYPTO_DEBUG
+
+static krb5_error_code
+krb5_get_keyid(krb5_context context,
+ krb5_keyblock *key,
+ u_int32_t *keyid)
+{
+ struct md5 md5;
+ unsigned char tmp[16];
+ md5_init(&md5);
+ md5_update(&md5, key->keyvalue.data, key->keyvalue.length);
+ md5_finito(&md5, tmp);
+ *keyid = (tmp[12] << 24) | (tmp[13] << 16) | (tmp[14] << 8) | tmp[15];
+ return 0;
+}
+
+static void
+krb5_crypto_debug(krb5_context context,
+ int encrypt,
+ size_t len,
+ krb5_keyblock *key)
+{
+ u_int32_t keyid;
+ char *kt;
+ krb5_get_keyid(context, key, &keyid);
+ krb5_enctype_to_string(context, key->keytype, &kt);
+ krb5_warnx(context, "%s %lu bytes with key-id %#x (%s)",
+ encrypt ? "encrypting" : "decrypting",
+ (unsigned long)len,
+ keyid,
+ kt);
+ free(kt);
+}
+
+#endif /* CRYPTO_DEBUG */
diff --git a/crypto/heimdal/lib/krb5/data.c b/crypto/heimdal/lib/krb5/data.c
new file mode 100644
index 000000000000..21191e25639c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/data.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: data.c,v 1.15 1999/12/02 17:05:09 joda Exp $");
+
+void
+krb5_data_zero(krb5_data *p)
+{
+ p->length = 0;
+ p->data = NULL;
+}
+
+void
+krb5_data_free(krb5_data *p)
+{
+ if(p->data != NULL)
+ free(p->data);
+ p->length = 0;
+}
+
+void
+krb5_free_data(krb5_context context,
+ krb5_data *p)
+{
+ krb5_data_free(p);
+ free(p);
+}
+
+krb5_error_code
+krb5_data_alloc(krb5_data *p, int len)
+{
+ p->data = malloc(len);
+ if(len && p->data == NULL)
+ return ENOMEM;
+ p->length = len;
+ return 0;
+}
+
+krb5_error_code
+krb5_data_realloc(krb5_data *p, int len)
+{
+ void *tmp;
+ tmp = realloc(p->data, len);
+ if(len && !tmp)
+ return ENOMEM;
+ p->data = tmp;
+ p->length = len;
+ return 0;
+}
+
+krb5_error_code
+krb5_data_copy(krb5_data *p, const void *data, size_t len)
+{
+ if (len) {
+ if(krb5_data_alloc(p, len))
+ return ENOMEM;
+ memmove(p->data, data, len);
+ } else
+ p->data = NULL;
+ p->length = len;
+ return 0;
+}
+
+krb5_error_code
+krb5_copy_data(krb5_context context,
+ const krb5_data *indata,
+ krb5_data **outdata)
+{
+ krb5_error_code ret;
+ ALLOC(*outdata, 1);
+ if(*outdata == NULL)
+ return ENOMEM;
+ ret = copy_octet_string(indata, *outdata);
+ if(ret)
+ free(*outdata);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/dump_config.c b/crypto/heimdal/lib/krb5/dump_config.c
new file mode 100644
index 000000000000..074595e2139c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/dump_config.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: dump_config.c,v 1.2 1999/10/28 23:22:41 assar Exp $");
+
+/* print contents of krb5.conf */
+
+static void
+print_tree(struct krb5_config_binding *b, int level)
+{
+ if (b == NULL)
+ return;
+
+ printf("%*s%s%s%s", level * 4, "",
+ (level == 0) ? "[" : "", b->name, (level == 0) ? "]" : "");
+ if(b->type == krb5_config_list) {
+ if(level > 0)
+ printf(" = {");
+ printf("\n");
+ print_tree(b->u.list, level + 1);
+ if(level > 0)
+ printf("%*s}\n", level * 4, "");
+ } else if(b->type == krb5_config_string) {
+ printf(" = %s\n", b->u.string);
+ }
+ if(b->next)
+ print_tree(b->next, level);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context;
+ krb5_error_code ret = krb5_init_context(&context);
+ if(ret == 0) {
+ print_tree(context->cf, 0);
+ return 0;
+ }
+ return 1;
+}
diff --git a/crypto/heimdal/lib/krb5/expand_hostname.c b/crypto/heimdal/lib/krb5/expand_hostname.c
new file mode 100644
index 000000000000..698b3007b15f
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/expand_hostname.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: expand_hostname.c,v 1.5 2000/01/08 08:07:18 assar Exp $");
+
+static krb5_error_code
+copy_hostname(krb5_context context,
+ const char *orig_hostname,
+ char **new_hostname)
+{
+ *new_hostname = strdup (orig_hostname);
+ if (*new_hostname == NULL)
+ return ENOMEM;
+ return 0;
+}
+
+/*
+ * Try to make `orig_hostname' into a more canonical one in the newly
+ * allocated space returned in `new_hostname'.
+ */
+
+krb5_error_code
+krb5_expand_hostname (krb5_context context,
+ const char *orig_hostname,
+ char **new_hostname)
+{
+ struct addrinfo *ai, *a, hints;
+ int error;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+
+ error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
+ if (error)
+ return copy_hostname (context, orig_hostname, new_hostname);
+ for (a = ai; a != NULL; a = a->ai_next) {
+ if (a->ai_canonname != NULL) {
+ *new_hostname = strdup (a->ai_canonname);
+ freeaddrinfo (ai);
+ if (*new_hostname == NULL)
+ return ENOMEM;
+ else
+ return 0;
+ }
+ }
+ freeaddrinfo (ai);
+ return copy_hostname (context, orig_hostname, new_hostname);
+}
diff --git a/crypto/heimdal/lib/krb5/fcache.c b/crypto/heimdal/lib/krb5/fcache.c
new file mode 100644
index 000000000000..df88e6f9c91e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/fcache.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: fcache.c,v 1.22 1999/12/02 17:05:09 joda Exp $");
+
+typedef struct krb5_fcache{
+ char *filename;
+ int version;
+}krb5_fcache;
+
+struct fcc_cursor {
+ int fd;
+ krb5_storage *sp;
+};
+
+#define KRB5_FCC_FVNO_1 1
+#define KRB5_FCC_FVNO_2 2
+#define KRB5_FCC_FVNO_3 3
+#define KRB5_FCC_FVNO_4 4
+
+#define FCC_TAG_DELTATIME 1
+
+#define FCACHE(X) ((krb5_fcache*)(X)->data.data)
+
+#define FILENAME(X) (FCACHE(X)->filename)
+
+#define FCC_CURSOR(C) ((struct fcc_cursor*)(C))
+
+static char*
+fcc_get_name(krb5_context context,
+ krb5_ccache id)
+{
+ return FILENAME(id);
+}
+
+static krb5_error_code
+fcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
+{
+ krb5_fcache *f;
+ f = malloc(sizeof(*f));
+ if(f == NULL)
+ return KRB5_CC_NOMEM;
+ f->filename = strdup(res);
+ if(f->filename == NULL){
+ free(f);
+ return KRB5_CC_NOMEM;
+ }
+ f->version = 0;
+ (*id)->data.data = f;
+ (*id)->data.length = sizeof(*f);
+ return 0;
+}
+
+static krb5_error_code
+erase_file(const char *filename)
+{
+ int fd;
+ off_t pos;
+ char buf[128];
+
+ fd = open(filename, O_RDWR | O_BINARY);
+ if(fd < 0){
+ if(errno == ENOENT)
+ return 0;
+ else
+ return errno;
+ }
+ pos = lseek(fd, 0, SEEK_END);
+ lseek(fd, 0, SEEK_SET);
+ memset(buf, 0, sizeof(buf));
+ while(pos > 0)
+ pos -= write(fd, buf, sizeof(buf));
+ close(fd);
+ unlink(filename);
+ return 0;
+}
+
+static krb5_error_code
+fcc_gen_new(krb5_context context, krb5_ccache *id)
+{
+ krb5_fcache *f;
+ int fd;
+ char *file;
+ f = malloc(sizeof(*f));
+ if(f == NULL)
+ return KRB5_CC_NOMEM;
+ asprintf(&file, "/tmp/krb5cc_XXXXXX"); /* XXX */
+ if(file == NULL) {
+ free(f);
+ return KRB5_CC_NOMEM;
+ }
+ fd = mkstemp(file);
+ if(fd < 0) {
+ free(f);
+ free(file);
+ return errno;
+ }
+ close(fd);
+ f->filename = file;
+ f->version = 0;
+ (*id)->data.data = f;
+ (*id)->data.length = sizeof(*f);
+ return 0;
+}
+
+static void
+storage_set_flags(krb5_context context, krb5_storage *sp, int vno)
+{
+ int flags = 0;
+ switch(vno) {
+ case KRB5_FCC_FVNO_1:
+ flags |= KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS;
+ flags |= KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE;
+ flags |= KRB5_STORAGE_HOST_BYTEORDER;
+ break;
+ case KRB5_FCC_FVNO_2:
+ flags |= KRB5_STORAGE_HOST_BYTEORDER;
+ break;
+ case KRB5_FCC_FVNO_3:
+ flags |= KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE;
+ break;
+ case KRB5_FCC_FVNO_4:
+ break;
+ default:
+ krb5_abortx(context,
+ "storage_set_flags called with bad vno (%x)", vno);
+ }
+ krb5_storage_set_flags(sp, flags);
+}
+
+static krb5_error_code
+fcc_initialize(krb5_context context,
+ krb5_ccache id,
+ krb5_principal primary_principal)
+{
+ krb5_fcache *f = FCACHE(id);
+ int ret;
+ int fd;
+ char *filename = f->filename;
+
+ if((ret = erase_file(filename)))
+ return ret;
+
+ fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
+ if(fd == -1)
+ return errno;
+ {
+ krb5_storage *sp;
+ sp = krb5_storage_from_fd(fd);
+ if(context->fcache_vno != 0)
+ f->version = context->fcache_vno;
+ else
+ f->version = KRB5_FCC_FVNO_4;
+ krb5_store_int8(sp, 5);
+ krb5_store_int8(sp, f->version);
+ storage_set_flags(context, sp, f->version);
+ if(f->version == KRB5_FCC_FVNO_4) {
+ /* V4 stuff */
+ if (context->kdc_sec_offset) {
+ krb5_store_int16 (sp, 12); /* length */
+ krb5_store_int16 (sp, FCC_TAG_DELTATIME); /* Tag */
+ krb5_store_int16 (sp, 8); /* length of data */
+ krb5_store_int32 (sp, context->kdc_sec_offset);
+ krb5_store_int32 (sp, context->kdc_usec_offset);
+ } else {
+ krb5_store_int16 (sp, 0);
+ }
+ }
+ krb5_store_principal(sp, primary_principal);
+ krb5_storage_free(sp);
+ }
+ close(fd);
+
+ return 0;
+}
+
+static krb5_error_code
+fcc_close(krb5_context context,
+ krb5_ccache id)
+{
+ free (FILENAME(id));
+ krb5_data_free(&id->data);
+ return 0;
+}
+
+static krb5_error_code
+fcc_destroy(krb5_context context,
+ krb5_ccache id)
+{
+ char *f;
+ f = FILENAME(id);
+
+ erase_file(f);
+
+ return 0;
+}
+
+static krb5_error_code
+fcc_store_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_creds *creds)
+{
+ int fd;
+ char *f;
+
+ f = FILENAME(id);
+
+ fd = open(f, O_WRONLY | O_APPEND | O_BINARY);
+ if(fd < 0)
+ return errno;
+ {
+ krb5_storage *sp;
+ sp = krb5_storage_from_fd(fd);
+ storage_set_flags(context, sp, FCACHE(id)->version);
+ krb5_store_creds(sp, creds);
+ krb5_storage_free(sp);
+ }
+ close(fd);
+ return 0; /* XXX */
+}
+
+static krb5_error_code
+fcc_read_cred (krb5_context context,
+ krb5_fcache *fc,
+ krb5_storage *sp,
+ krb5_creds *creds)
+{
+ krb5_error_code ret;
+
+ storage_set_flags(context, sp, fc->version);
+
+ ret = krb5_ret_creds(sp, creds);
+ return ret;
+}
+
+static krb5_error_code
+init_fcc (krb5_context context,
+ krb5_fcache *fcache,
+ krb5_storage **ret_sp,
+ int *ret_fd)
+{
+ int fd;
+ int8_t pvno, tag;
+ krb5_storage *sp;
+
+ fd = open(fcache->filename, O_RDONLY | O_BINARY);
+ if(fd < 0)
+ return errno;
+ sp = krb5_storage_from_fd(fd);
+ krb5_ret_int8(sp, &pvno);
+ if(pvno != 5) {
+ krb5_storage_free(sp);
+ close(fd);
+ return KRB5_CCACHE_BADVNO;
+ }
+ krb5_ret_int8(sp, &tag); /* should not be host byte order */
+ fcache->version = tag;
+ storage_set_flags(context, sp, fcache->version);
+ switch (tag) {
+ case KRB5_FCC_FVNO_4: {
+ int16_t length;
+
+ krb5_ret_int16 (sp, &length);
+ while(length > 0) {
+ int16_t tag, data_len;
+ int i;
+ int8_t dummy;
+
+ krb5_ret_int16 (sp, &tag);
+ krb5_ret_int16 (sp, &data_len);
+ switch (tag) {
+ case FCC_TAG_DELTATIME :
+ krb5_ret_int32 (sp, &context->kdc_sec_offset);
+ krb5_ret_int32 (sp, &context->kdc_usec_offset);
+ break;
+ default :
+ for (i = 0; i < data_len; ++i)
+ krb5_ret_int8 (sp, &dummy);
+ break;
+ }
+ length -= 4 + data_len;
+ }
+ break;
+ }
+ case KRB5_FCC_FVNO_3:
+ case KRB5_FCC_FVNO_2:
+ case KRB5_FCC_FVNO_1:
+ break;
+ default :
+ krb5_storage_free (sp);
+ close (fd);
+ return KRB5_CCACHE_BADVNO;
+ }
+ *ret_sp = sp;
+ *ret_fd = fd;
+ return 0;
+}
+
+static krb5_error_code
+fcc_get_principal(krb5_context context,
+ krb5_ccache id,
+ krb5_principal *principal)
+{
+ krb5_error_code ret;
+ krb5_fcache *f = FCACHE(id);
+ int fd;
+ krb5_storage *sp;
+
+ ret = init_fcc (context, f, &sp, &fd);
+ if (ret)
+ return ret;
+ krb5_ret_principal(sp, principal);
+ krb5_storage_free(sp);
+ close(fd);
+ return 0;
+}
+
+static krb5_error_code
+fcc_get_first (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ krb5_error_code ret;
+ krb5_principal principal;
+ krb5_fcache *f = FCACHE(id);
+
+ *cursor = malloc(sizeof(struct fcc_cursor));
+
+ ret = init_fcc (context, f, &FCC_CURSOR(*cursor)->sp,
+ &FCC_CURSOR(*cursor)->fd);
+ if (ret)
+ return ret;
+ krb5_ret_principal (FCC_CURSOR(*cursor)->sp, &principal);
+ krb5_free_principal (context, principal);
+ return 0;
+}
+
+static krb5_error_code
+fcc_get_next (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor,
+ krb5_creds *creds)
+{
+ return fcc_read_cred (context, FCACHE(id), FCC_CURSOR(*cursor)->sp, creds);
+}
+
+static krb5_error_code
+fcc_end_get (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ krb5_storage_free(FCC_CURSOR(*cursor)->sp);
+ close (FCC_CURSOR(*cursor)->fd);
+ free(*cursor);
+ return 0;
+}
+
+static krb5_error_code
+fcc_remove_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_flags which,
+ krb5_creds *cred)
+{
+ return 0; /* XXX */
+}
+
+static krb5_error_code
+fcc_set_flags(krb5_context context,
+ krb5_ccache id,
+ krb5_flags flags)
+{
+ return 0; /* XXX */
+}
+
+static krb5_error_code
+fcc_get_version(krb5_context context,
+ krb5_ccache id)
+{
+ return FCACHE(id)->version;
+}
+
+const krb5_cc_ops krb5_fcc_ops = {
+ "FILE",
+ fcc_get_name,
+ fcc_resolve,
+ fcc_gen_new,
+ fcc_initialize,
+ fcc_destroy,
+ fcc_close,
+ fcc_store_cred,
+ NULL, /* fcc_retrieve */
+ fcc_get_principal,
+ fcc_get_first,
+ fcc_get_next,
+ fcc_end_get,
+ fcc_remove_cred,
+ fcc_set_flags,
+ fcc_get_version
+};
diff --git a/crypto/heimdal/lib/krb5/free.c b/crypto/heimdal/lib/krb5/free.c
new file mode 100644
index 000000000000..251ec320106d
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/free.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: free.c,v 1.5 1999/12/02 17:05:09 joda Exp $");
+
+krb5_error_code
+krb5_free_kdc_rep(krb5_context context, krb5_kdc_rep *rep)
+{
+ free_KDC_REP(&rep->kdc_rep);
+ free_EncTGSRepPart(&rep->enc_part);
+ free_KRB_ERROR(&rep->error);
+ return 0;
+}
+
+krb5_error_code
+krb5_xfree (void *ptr)
+{
+ free (ptr);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/free_host_realm.c b/crypto/heimdal/lib/krb5/free_host_realm.c
new file mode 100644
index 000000000000..a69f29b988ff
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/free_host_realm.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: free_host_realm.c,v 1.4 1999/12/02 17:05:09 joda Exp $");
+
+/*
+ * Free all memory allocated by `realmlist'
+ */
+
+krb5_error_code
+krb5_free_host_realm(krb5_context context,
+ krb5_realm *realmlist)
+{
+ krb5_realm *p;
+
+ if(realmlist == NULL)
+ return 0;
+ for (p = realmlist; *p; ++p)
+ free (*p);
+ free (realmlist);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/generate_seq_number.c b/crypto/heimdal/lib/krb5/generate_seq_number.c
new file mode 100644
index 000000000000..a000ea1e6c36
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/generate_seq_number.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: generate_seq_number.c,v 1.6 1999/12/02 17:05:09 joda Exp $");
+
+krb5_error_code
+krb5_generate_seq_number(krb5_context context,
+ const krb5_keyblock *key,
+ int32_t *seqno)
+{
+ krb5_error_code ret;
+ krb5_keyblock *subkey;
+ u_int32_t q;
+ u_char *p;
+ int i;
+
+ ret = krb5_generate_subkey (context, key, &subkey);
+ if (ret)
+ return ret;
+
+ q = 0;
+ for (p = (u_char *)subkey->keyvalue.data, i = 0;
+ i < subkey->keyvalue.length;
+ ++i, ++p)
+ q = (q << 8) | *p;
+ q &= 0xffffffff;
+ *seqno = q;
+ krb5_free_keyblock_contents (context, subkey);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/generate_subkey.c b/crypto/heimdal/lib/krb5/generate_subkey.c
new file mode 100644
index 000000000000..a5b2e9ea9c00
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/generate_subkey.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: generate_subkey.c,v 1.7 1999/12/02 17:05:09 joda Exp $");
+
+krb5_error_code
+krb5_generate_subkey(krb5_context context,
+ const krb5_keyblock *key,
+ krb5_keyblock **subkey)
+{
+ krb5_error_code ret;
+
+ ALLOC(*subkey, 1);
+ if (*subkey == NULL)
+ return ENOMEM;
+ ret = krb5_generate_random_keyblock(context, key->keytype, *subkey);
+ if(ret)
+ free(*subkey);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/get_addrs.c b/crypto/heimdal/lib/krb5/get_addrs.c
new file mode 100644
index 000000000000..65a1b3c7bdd5
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_addrs.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_addrs.c,v 1.35 1999/12/02 17:05:09 joda Exp $");
+
+#ifdef __osf__
+/* hate */
+struct rtentry;
+struct mbuf;
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif /* HAVE_SYS_SOCKIO_H */
+
+#ifdef HAVE_NETINET_IN6_VAR_H
+#include <netinet/in6_var.h>
+#endif /* HAVE_NETINET_IN6_VAR_H */
+
+static krb5_error_code
+gethostname_fallback (krb5_addresses *res)
+{
+ krb5_error_code err;
+ char hostname[MAXHOSTNAMELEN];
+ struct hostent *hostent;
+
+ if (gethostname (hostname, sizeof(hostname)))
+ return errno;
+ hostent = roken_gethostbyname (hostname);
+ if (hostent == NULL)
+ return errno;
+ res->len = 1;
+ res->val = malloc (sizeof(*res->val));
+ if (res->val == NULL)
+ return ENOMEM;
+ res->val[0].addr_type = hostent->h_addrtype;
+ res->val[0].address.data = NULL;
+ res->val[0].address.length = 0;
+ err = krb5_data_copy (&res->val[0].address,
+ hostent->h_addr,
+ hostent->h_length);
+ if (err) {
+ free (res->val);
+ return err;
+ }
+ return 0;
+}
+
+enum {
+ LOOP = 1, /* do include loopback interfaces */
+ LOOP_IF_NONE = 2, /* include loopback if no other if's */
+ EXTRA_ADDRESSES = 4, /* include extra addresses */
+ SCAN_INTERFACES = 8 /* scan interfaces for addresses */
+};
+
+/*
+ * Try to figure out the addresses of all configured interfaces with a
+ * lot of magic ioctls.
+ */
+
+static krb5_error_code
+find_all_addresses (krb5_context context,
+ krb5_addresses *res, int flags,
+ int af, int siocgifconf, int siocgifflags,
+ size_t ifreq_sz)
+{
+ krb5_error_code ret;
+ int fd;
+ size_t buf_size;
+ char *buf;
+ struct ifconf ifconf;
+ int num, j = 0;
+ char *p;
+ size_t sz;
+ struct sockaddr sa_zero;
+ struct ifreq *ifr;
+ krb5_address lo_addr;
+ int got_lo = FALSE;
+
+ buf = NULL;
+ res->val = NULL;
+
+ memset (&sa_zero, 0, sizeof(sa_zero));
+ fd = socket(af, SOCK_DGRAM, 0);
+ if (fd < 0)
+ return -1;
+
+ buf_size = 8192;
+ for (;;) {
+ buf = malloc(buf_size);
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto error_out;
+ }
+ ifconf.ifc_len = buf_size;
+ ifconf.ifc_buf = buf;
+ if (ioctl (fd, siocgifconf, &ifconf) < 0) {
+ ret = errno;
+ goto error_out;
+ }
+ /*
+ * Can the difference between a full and a overfull buf
+ * be determined?
+ */
+
+ if (ifconf.ifc_len < buf_size)
+ break;
+ free (buf);
+ buf_size *= 2;
+ }
+
+ num = ifconf.ifc_len / ifreq_sz;
+ res->len = num;
+ res->val = calloc(num, sizeof(*res->val));
+ if (res->val == NULL) {
+ ret = ENOMEM;
+ goto error_out;
+ }
+
+ j = 0;
+ for (p = ifconf.ifc_buf;
+ p < ifconf.ifc_buf + ifconf.ifc_len;
+ p += sz) {
+ struct ifreq ifreq;
+ struct sockaddr *sa;
+
+ ifr = (struct ifreq *)p;
+ sa = &ifr->ifr_addr;
+
+ sz = ifreq_sz;
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ sz = max(sz, sizeof(ifr->ifr_name) + sa->sa_len);
+#endif
+#ifdef SA_LEN
+ sz = max(sz, SA_LEN(sa));
+#endif
+ memcpy (ifreq.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name));
+
+ if (ioctl(fd, siocgifflags, &ifreq) < 0) {
+ ret = errno;
+ goto error_out;
+ }
+
+ if (!(ifreq.ifr_flags & IFF_UP))
+ continue;
+ if (memcmp (sa, &sa_zero, sizeof(sa_zero)) == 0)
+ continue;
+ if (krb5_sockaddr_uninteresting (sa))
+ continue;
+
+ if (ifreq.ifr_flags & IFF_LOOPBACK) {
+ if (flags & LOOP_IF_NONE) {
+ ret = krb5_sockaddr2address (sa, &lo_addr);
+ if (ret)
+ goto error_out;
+ got_lo = TRUE;
+ continue;
+ } else if((flags & LOOP) == 0)
+ continue;
+ }
+
+ ret = krb5_sockaddr2address (sa, &res->val[j]);
+ if (ret)
+ goto error_out;
+ ++j;
+ }
+ if ((flags & LOOP_IF_NONE) && got_lo) {
+ if (j == 0)
+ res->val[j++] = lo_addr;
+ else
+ krb5_free_address (context, &lo_addr);
+ }
+
+ if (j != num) {
+ void *tmp;
+
+ res->len = j;
+ tmp = realloc (res->val, j * sizeof(*res->val));
+ if (j != 0 && tmp == NULL) {
+ ret = ENOMEM;
+ goto error_out;
+ }
+ res->val = tmp;
+ }
+ ret = 0;
+ goto cleanup;
+
+error_out:
+ if (got_lo)
+ krb5_free_address (context, &lo_addr);
+ while(j--) {
+ krb5_free_address (context, &res->val[j]);
+ }
+ free (res->val);
+cleanup:
+ close (fd);
+ free (buf);
+ return ret;
+}
+
+static krb5_error_code
+get_addrs_int (krb5_context context, krb5_addresses *res, int flags)
+{
+ krb5_error_code ret = -1;
+
+ if (flags & SCAN_INTERFACES) {
+#if defined(AF_INET6) && defined(SIOCGIF6CONF) && defined(SIOCGIF6FLAGS)
+ if (ret)
+ ret = find_all_addresses (context, res, flags,
+ AF_INET6, SIOCGIF6CONF, SIOCGIF6FLAGS,
+ sizeof(struct in6_ifreq));
+#endif
+#if defined(HAVE_IPV6) && defined(SIOCGIFCONF)
+ if (ret)
+ ret = find_all_addresses (context, res, flags,
+ AF_INET6, SIOCGIFCONF, SIOCGIFFLAGS,
+ sizeof(struct ifreq));
+#endif
+#if defined(AF_INET) && defined(SIOCGIFCONF) && defined(SIOCGIFFLAGS)
+ if (ret)
+ ret = find_all_addresses (context, res, flags,
+ AF_INET, SIOCGIFCONF, SIOCGIFFLAGS,
+ sizeof(struct ifreq));
+ if(ret || res->len == 0)
+ ret = gethostname_fallback (res);
+#endif
+ } else
+ ret = 0;
+
+ if(ret == 0 && (flags & EXTRA_ADDRESSES)) {
+ /* append user specified addresses */
+ krb5_addresses a;
+ ret = krb5_get_extra_addresses(context, &a);
+ if(ret) {
+ krb5_free_addresses(context, res);
+ return ret;
+ }
+ ret = krb5_append_addresses(context, res, &a);
+ if(ret) {
+ krb5_free_addresses(context, res);
+ return ret;
+ }
+ krb5_free_addresses(context, &a);
+ }
+ return ret;
+}
+
+/*
+ * Try to get all addresses, but return the one corresponding to
+ * `hostname' if we fail.
+ *
+ * Only include loopback address if there are no other.
+ */
+
+krb5_error_code
+krb5_get_all_client_addrs (krb5_context context, krb5_addresses *res)
+{
+ int flags = LOOP_IF_NONE | EXTRA_ADDRESSES;
+
+ if (context->scan_interfaces)
+ flags |= SCAN_INTERFACES;
+
+ return get_addrs_int (context, res, flags);
+}
+
+/*
+ * Try to get all local addresses that a server should listen to.
+ * If that fails, we return the address corresponding to `hostname'.
+ */
+
+krb5_error_code
+krb5_get_all_server_addrs (krb5_context context, krb5_addresses *res)
+{
+ return get_addrs_int (context, res, LOOP | SCAN_INTERFACES);
+}
diff --git a/crypto/heimdal/lib/krb5/get_cred.c b/crypto/heimdal/lib/krb5/get_cred.c
new file mode 100644
index 000000000000..61951c1a4daf
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_cred.c
@@ -0,0 +1,776 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: get_cred.c,v 1.75 1999/12/02 17:05:09 joda Exp $");
+
+/*
+ * Take the `body' and encode it into `padata' using the credentials
+ * in `creds'.
+ */
+
+static krb5_error_code
+make_pa_tgs_req(krb5_context context,
+ krb5_auth_context ac,
+ KDC_REQ_BODY *body,
+ PA_DATA *padata,
+ krb5_creds *creds)
+{
+ u_char *buf;
+ size_t buf_size;
+ size_t len;
+ krb5_data in_data;
+ krb5_error_code ret;
+
+ buf_size = 1024;
+ buf = malloc (buf_size);
+ if (buf == NULL)
+ return ENOMEM;
+
+ do {
+ ret = encode_KDC_REQ_BODY(buf + buf_size - 1, buf_size,
+ body, &len);
+ if (ret){
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ buf = tmp;
+ } else {
+ goto out;
+ }
+ }
+ } while (ret == ASN1_OVERFLOW);
+
+ in_data.length = len;
+ in_data.data = buf + buf_size - len;
+ ret = krb5_mk_req_internal(context, &ac, 0, &in_data, creds,
+ &padata->padata_value,
+ KRB5_KU_TGS_REQ_AUTH_CKSUM);
+out:
+ free (buf);
+ if(ret)
+ return ret;
+ padata->padata_type = pa_tgs_req;
+ return 0;
+}
+
+/*
+ * Set the `enc-authorization-data' in `req_body' based on `authdata'
+ */
+
+static krb5_error_code
+set_auth_data (krb5_context context,
+ KDC_REQ_BODY *req_body,
+ krb5_authdata *authdata,
+ krb5_keyblock *key)
+{
+ if(authdata->len) {
+ size_t len;
+ unsigned char *buf;
+ krb5_crypto crypto;
+ krb5_error_code ret;
+
+ len = length_AuthorizationData(authdata);
+ buf = malloc(len);
+ if (buf == NULL)
+ return ENOMEM;
+ ret = encode_AuthorizationData(buf + len - 1,
+ len, authdata, &len);
+ if (ret) {
+ free (buf);
+ return ret;
+ }
+
+ ALLOC(req_body->enc_authorization_data, 1);
+ if (req_body->enc_authorization_data == NULL) {
+ free (buf);
+ return ret;
+ }
+ ret = krb5_crypto_init(context, key, 0, &crypto);
+ if (ret) {
+ free (buf);
+ free (req_body->enc_authorization_data);
+ return ret;
+ }
+ krb5_encrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
+ /* KRB5_KU_TGS_REQ_AUTH_DAT_SESSION? */
+ buf,
+ len,
+ 0,
+ req_body->enc_authorization_data);
+ free (buf);
+ krb5_crypto_destroy(context, crypto);
+ } else {
+ req_body->enc_authorization_data = NULL;
+ }
+ return 0;
+}
+
+/*
+ * Create a tgs-req in `t' with `addresses', `flags', `second_ticket'
+ * (if not-NULL), `in_creds', `krbtgt', and returning the generated
+ * subkey in `subkey'.
+ */
+
+static krb5_error_code
+init_tgs_req (krb5_context context,
+ krb5_ccache ccache,
+ krb5_addresses *addresses,
+ krb5_kdc_flags flags,
+ Ticket *second_ticket,
+ krb5_creds *in_creds,
+ krb5_creds *krbtgt,
+ unsigned nonce,
+ krb5_keyblock **subkey,
+ TGS_REQ *t)
+{
+ krb5_error_code ret;
+
+ memset(t, 0, sizeof(*t));
+ t->pvno = 5;
+ t->msg_type = krb_tgs_req;
+ if (in_creds->session.keytype) {
+ ret = krb5_keytype_to_enctypes_default (context,
+ in_creds->session.keytype,
+ &t->req_body.etype.len,
+ &t->req_body.etype.val);
+ } else {
+ ret = krb5_init_etype(context,
+ &t->req_body.etype.len,
+ &t->req_body.etype.val,
+ NULL);
+ }
+ if (ret)
+ goto fail;
+ t->req_body.addresses = addresses;
+ t->req_body.kdc_options = flags.b;
+ ret = copy_Realm(&in_creds->server->realm, &t->req_body.realm);
+ if (ret)
+ goto fail;
+ ALLOC(t->req_body.sname, 1);
+ if (t->req_body.sname == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ ret = copy_PrincipalName(&in_creds->server->name, t->req_body.sname);
+ if (ret)
+ goto fail;
+
+ /* req_body.till should be NULL if there is no endtime specified,
+ but old MIT code (like DCE secd) doesn't like that */
+ ALLOC(t->req_body.till, 1);
+ if(t->req_body.till == NULL){
+ ret = ENOMEM;
+ goto fail;
+ }
+ *t->req_body.till = in_creds->times.endtime;
+
+ t->req_body.nonce = nonce;
+ if(second_ticket){
+ ALLOC(t->req_body.additional_tickets, 1);
+ if (t->req_body.additional_tickets == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ ALLOC_SEQ(t->req_body.additional_tickets, 1);
+ if (t->req_body.additional_tickets->val == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val);
+ if (ret)
+ goto fail;
+ }
+ ALLOC(t->padata, 1);
+ if (t->padata == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ ALLOC_SEQ(t->padata, 1);
+ if (t->padata->val == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ {
+ krb5_auth_context ac;
+ krb5_keyblock *key;
+
+ ret = krb5_auth_con_init(context, &ac);
+ if(ret)
+ goto fail;
+ ret = krb5_generate_subkey (context, &krbtgt->session, &key);
+ if (ret) {
+ krb5_auth_con_free (context, ac);
+ goto fail;
+ }
+ ret = krb5_auth_con_setlocalsubkey(context, ac, key);
+ if (ret) {
+ krb5_free_keyblock (context, key);
+ krb5_auth_con_free (context, ac);
+ goto fail;
+ }
+
+ ret = set_auth_data (context, &t->req_body, &in_creds->authdata, key);
+ if (ret) {
+ krb5_free_keyblock (context, key);
+ krb5_auth_con_free (context, ac);
+ goto fail;
+ }
+
+ ret = make_pa_tgs_req(context,
+ ac,
+ &t->req_body,
+ t->padata->val,
+ krbtgt);
+ if(ret) {
+ krb5_free_keyblock (context, key);
+ krb5_auth_con_free(context, ac);
+ goto fail;
+ }
+ *subkey = key;
+
+ krb5_auth_con_free(context, ac);
+ }
+fail:
+ if (ret)
+ free_TGS_REQ (t);
+ return ret;
+}
+
+static krb5_error_code
+get_krbtgt(krb5_context context,
+ krb5_ccache id,
+ krb5_realm realm,
+ krb5_creds **cred)
+{
+ krb5_error_code ret;
+ krb5_creds tmp_cred;
+
+ memset(&tmp_cred, 0, sizeof(tmp_cred));
+
+ ret = krb5_make_principal(context,
+ &tmp_cred.server,
+ realm,
+ KRB5_TGS_NAME,
+ realm,
+ NULL);
+ if(ret)
+ return ret;
+ ret = krb5_get_credentials(context,
+ KRB5_GC_CACHED,
+ id,
+ &tmp_cred,
+ cred);
+ krb5_free_principal(context, tmp_cred.server);
+ if(ret)
+ return ret;
+ return 0;
+}
+
+/* DCE compatible decrypt proc */
+static krb5_error_code
+decrypt_tkt_with_subkey (krb5_context context,
+ krb5_keyblock *key,
+ krb5_key_usage usage,
+ krb5_const_pointer subkey,
+ krb5_kdc_rep *dec_rep)
+{
+ krb5_error_code ret;
+ krb5_data data;
+ size_t size;
+ krb5_crypto crypto;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ usage,
+ &dec_rep->kdc_rep.enc_part,
+ &data);
+ krb5_crypto_destroy(context, crypto);
+ if(ret && subkey){
+ /* DCE compat -- try to decrypt with subkey */
+ krb5_crypto_init(context, (krb5_keyblock*)subkey, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_TGS_REP_ENC_PART_SUB_KEY,
+ &dec_rep->kdc_rep.enc_part,
+ &data);
+ krb5_crypto_destroy(context, crypto);
+ }
+ if (ret)
+ return ret;
+
+ ret = krb5_decode_EncASRepPart(context,
+ data.data,
+ data.length,
+ &dec_rep->enc_part,
+ &size);
+ if (ret)
+ ret = krb5_decode_EncTGSRepPart(context,
+ data.data,
+ data.length,
+ &dec_rep->enc_part,
+ &size);
+ krb5_data_free (&data);
+ return ret;
+}
+
+static krb5_error_code
+get_cred_kdc(krb5_context context,
+ krb5_ccache id,
+ krb5_kdc_flags flags,
+ krb5_addresses *addresses,
+ krb5_creds *in_creds,
+ krb5_creds *krbtgt,
+ krb5_creds *out_creds)
+{
+ TGS_REQ req;
+ krb5_data enc;
+ krb5_data resp;
+ krb5_kdc_rep rep;
+ KRB_ERROR error;
+ krb5_error_code ret;
+ unsigned nonce;
+ krb5_keyblock *subkey = NULL;
+ u_char *buf = NULL;
+ size_t buf_size;
+ size_t len;
+ Ticket second_ticket;
+
+ krb5_generate_random_block(&nonce, sizeof(nonce));
+ nonce &= 0xffffffff;
+
+ if(flags.b.enc_tkt_in_skey){
+ ret = decode_Ticket(in_creds->second_ticket.data,
+ in_creds->second_ticket.length,
+ &second_ticket, &len);
+ if(ret)
+ return ret;
+ }
+
+ ret = init_tgs_req (context,
+ id,
+ addresses,
+ flags,
+ flags.b.enc_tkt_in_skey ? &second_ticket : NULL,
+ in_creds,
+ krbtgt,
+ nonce,
+ &subkey,
+ &req);
+ if(flags.b.enc_tkt_in_skey)
+ free_Ticket(&second_ticket);
+ if (ret)
+ goto out;
+
+ buf_size = 1024;
+ buf = malloc (buf_size);
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ do {
+ ret = encode_TGS_REQ (buf + buf_size - 1, buf_size,
+ &req, &enc.length);
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ buf = tmp;
+ } else {
+ goto out;
+ }
+ }
+ } while (ret == ASN1_OVERFLOW);
+
+ /* don't free addresses */
+ req.req_body.addresses = NULL;
+ free_TGS_REQ(&req);
+
+ enc.data = buf + buf_size - enc.length;
+ if (ret)
+ goto out;
+
+ /*
+ * Send and receive
+ */
+
+ ret = krb5_sendto_kdc (context, &enc,
+ &krbtgt->server->name.name_string.val[1], &resp);
+ if(ret)
+ goto out;
+
+ memset(&rep, 0, sizeof(rep));
+ if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0){
+ ret = krb5_copy_principal(context,
+ in_creds->client,
+ &out_creds->client);
+ if(ret)
+ goto out;
+ ret = krb5_copy_principal(context,
+ in_creds->server,
+ &out_creds->server);
+ if(ret)
+ goto out;
+ /* this should go someplace else */
+ out_creds->times.endtime = in_creds->times.endtime;
+
+ ret = _krb5_extract_ticket(context,
+ &rep,
+ out_creds,
+ &krbtgt->session,
+ NULL,
+ KRB5_KU_TGS_REP_ENC_PART_SESSION,
+ &krbtgt->addresses,
+ nonce,
+ TRUE,
+ decrypt_tkt_with_subkey,
+ subkey);
+ krb5_free_kdc_rep(context, &rep);
+ if (ret)
+ goto out;
+ }else if(krb5_rd_error(context, &resp, &error) == 0){
+ ret = error.error_code;
+ free_KRB_ERROR(&error);
+ }else if(resp.data && ((char*)resp.data)[0] == 4)
+ ret = KRB5KRB_AP_ERR_V4_REPLY;
+ else
+ ret = KRB5KRB_AP_ERR_MSG_TYPE;
+ krb5_data_free(&resp);
+out:
+ if(subkey){
+ krb5_free_keyblock_contents(context, subkey);
+ free(subkey);
+ }
+ if (buf)
+ free (buf);
+ return ret;
+
+}
+
+/* same as above, just get local addresses first */
+
+static krb5_error_code
+get_cred_kdc_la(krb5_context context, krb5_ccache id, krb5_kdc_flags flags,
+ krb5_creds *in_creds, krb5_creds *krbtgt,
+ krb5_creds *out_creds)
+{
+ krb5_error_code ret;
+ krb5_addresses addresses;
+
+ krb5_get_all_client_addrs(context, &addresses);
+ ret = get_cred_kdc(context, id, flags, &addresses,
+ in_creds, krbtgt, out_creds);
+ krb5_free_addresses(context, &addresses);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_kdc_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_kdc_flags flags,
+ krb5_addresses *addresses,
+ Ticket *second_ticket,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds
+ )
+{
+ krb5_error_code ret;
+ krb5_creds *krbtgt;
+ *out_creds = calloc(1, sizeof(**out_creds));
+ if(*out_creds == NULL)
+ return ENOMEM;
+ ret = get_krbtgt (context,
+ id,
+ in_creds->server->realm,
+ &krbtgt);
+ if(ret) {
+ free(*out_creds);
+ return ret;
+ }
+ ret = get_cred_kdc(context, id, flags, addresses,
+ in_creds, krbtgt, *out_creds);
+ krb5_free_creds (context, krbtgt);
+ if(ret)
+ free(*out_creds);
+ return ret;
+}
+
+
+static krb5_error_code
+find_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_principal server,
+ krb5_creds **tgts,
+ krb5_creds *out_creds)
+{
+ krb5_error_code ret;
+ krb5_creds mcreds;
+ mcreds.server = server;
+ ret = krb5_cc_retrieve_cred(context, id, KRB5_TC_DONT_MATCH_REALM,
+ &mcreds, out_creds);
+ if(ret == 0)
+ return 0;
+ while(tgts && *tgts){
+ if(krb5_compare_creds(context, KRB5_TC_DONT_MATCH_REALM,
+ &mcreds, *tgts)){
+ ret = krb5_copy_creds_contents(context, *tgts, out_creds);
+ return ret;
+ }
+ tgts++;
+ }
+ return KRB5_CC_NOTFOUND;
+}
+
+static krb5_error_code
+add_cred(krb5_context context, krb5_creds ***tgts, krb5_creds *tkt)
+{
+ int i;
+ krb5_error_code ret;
+ krb5_creds **tmp = *tgts;
+ for(i = 0; tmp && tmp[i]; i++); /* XXX */
+ tmp = realloc(tmp, (i+2)*sizeof(*tmp));
+ if(tmp == NULL)
+ return ENOMEM;
+ *tgts = tmp;
+ ret = krb5_copy_creds(context, tkt, &tmp[i]);
+ tmp[i+1] = NULL;
+ return ret;
+}
+
+/*
+get_cred(server)
+ creds = cc_get_cred(server)
+ if(creds) return creds
+ tgt = cc_get_cred(krbtgt/server_realm@any_realm)
+ if(tgt)
+ return get_cred_tgt(server, tgt)
+ if(client_realm == server_realm)
+ return NULL
+ tgt = get_cred(krbtgt/server_realm@client_realm)
+ while(tgt_inst != server_realm)
+ tgt = get_cred(krbtgt/server_realm@tgt_inst)
+ return get_cred_tgt(server, tgt)
+ */
+
+static krb5_error_code
+get_cred_from_kdc_flags(krb5_context context,
+ krb5_kdc_flags flags,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds,
+ krb5_creds ***ret_tgts)
+{
+ krb5_error_code ret;
+ krb5_creds *tgt, tmp_creds;
+ krb5_realm client_realm, server_realm;
+
+ *out_creds = NULL;
+
+ client_realm = *krb5_princ_realm(context, in_creds->client);
+ server_realm = *krb5_princ_realm(context, in_creds->server);
+ memset(&tmp_creds, 0, sizeof(tmp_creds));
+ ret = krb5_copy_principal(context, in_creds->client, &tmp_creds.client);
+ if(ret)
+ return ret;
+ ret = krb5_make_principal(context,
+ &tmp_creds.server,
+ client_realm,
+ KRB5_TGS_NAME,
+ server_realm,
+ NULL);
+ if(ret){
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ {
+ krb5_creds tgts;
+ /* XXX try krb5_cc_retrieve_cred first? */
+ ret = find_cred(context, ccache, tmp_creds.server,
+ *ret_tgts, &tgts);
+ if(ret == 0){
+ *out_creds = calloc(1, sizeof(**out_creds));
+ if(*out_creds == NULL)
+ ret = ENOMEM;
+ else {
+ ret = get_cred_kdc_la(context, ccache, flags,
+ in_creds, &tgts, *out_creds);
+ if (ret)
+ free (*out_creds);
+ }
+ krb5_free_creds_contents(context, &tgts);
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ }
+ if(krb5_realm_compare(context, in_creds->client, in_creds->server))
+ return KRB5_CC_NOTFOUND;
+ /* XXX this can loop forever */
+ while(1){
+ general_string tgt_inst;
+ krb5_kdc_flags f;
+ f.i = 0;
+ ret = get_cred_from_kdc_flags(context, flags, ccache, &tmp_creds,
+ &tgt, ret_tgts);
+ if(ret) {
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ ret = add_cred(context, ret_tgts, tgt);
+ if(ret) {
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ tgt_inst = tgt->server->name.name_string.val[1];
+ if(strcmp(tgt_inst, server_realm) == 0)
+ break;
+ krb5_free_principal(context, tmp_creds.server);
+ ret = krb5_make_principal(context, &tmp_creds.server,
+ tgt_inst, KRB5_TGS_NAME, server_realm, NULL);
+ if(ret) {
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ ret = krb5_free_creds(context, tgt);
+ if(ret) {
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ }
+
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ *out_creds = calloc(1, sizeof(**out_creds));
+ if(*out_creds == NULL)
+ ret = ENOMEM;
+ else {
+ ret = get_cred_kdc_la(context, ccache, flags,
+ in_creds, tgt, *out_creds);
+ if (ret)
+ free (*out_creds);
+ }
+ krb5_free_creds(context, tgt);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_cred_from_kdc(krb5_context context,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds,
+ krb5_creds ***ret_tgts)
+{
+ krb5_kdc_flags f;
+ f.i = 0;
+ return get_cred_from_kdc_flags(context, f, ccache,
+ in_creds, out_creds, ret_tgts);
+}
+
+
+krb5_error_code
+krb5_get_credentials_with_flags(krb5_context context,
+ krb5_flags options,
+ krb5_kdc_flags flags,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds)
+{
+ krb5_error_code ret;
+ krb5_creds **tgts;
+ int i;
+
+ *out_creds = calloc(1, sizeof(**out_creds));
+ if (*out_creds == NULL)
+ return ENOMEM;
+
+ ret = krb5_cc_retrieve_cred(context,
+ ccache,
+ in_creds->session.keytype ?
+ KRB5_TC_MATCH_KEYTYPE : 0,
+ in_creds, *out_creds);
+ if(ret == 0)
+ return 0;
+ free(*out_creds);
+ if(ret != KRB5_CC_END)
+ return ret;
+ if(options & KRB5_GC_CACHED)
+ return KRB5_CC_NOTFOUND;
+ if(options & KRB5_GC_USER_USER)
+ flags.b.enc_tkt_in_skey = 1;
+ tgts = NULL;
+ ret = get_cred_from_kdc_flags(context, flags, ccache,
+ in_creds, out_creds, &tgts);
+ for(i = 0; tgts && tgts[i]; i++){
+ krb5_cc_store_cred(context, ccache, tgts[i]);
+ krb5_free_creds(context, tgts[i]);
+ }
+ free(tgts);
+ if(ret == 0 && flags.b.enc_tkt_in_skey == 0)
+ krb5_cc_store_cred(context, ccache, *out_creds);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_credentials(krb5_context context,
+ krb5_flags options,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds)
+{
+ krb5_kdc_flags flags;
+ flags.i = 0;
+ return krb5_get_credentials_with_flags(context, options, flags,
+ ccache, in_creds, out_creds);
+}
diff --git a/crypto/heimdal/lib/krb5/get_default_principal.c b/crypto/heimdal/lib/krb5/get_default_principal.c
new file mode 100644
index 000000000000..84d7a5e06579
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_default_principal.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_default_principal.c,v 1.5 1999/12/02 17:05:09 joda Exp $");
+
+/*
+ * Try to find out what's a reasonable default principal.
+ */
+
+krb5_error_code
+krb5_get_default_principal (krb5_context context,
+ krb5_principal *princ)
+{
+ krb5_error_code ret;
+ krb5_ccache id;
+ const char *user;
+
+ ret = krb5_cc_default (context, &id);
+ if (ret == 0) {
+ ret = krb5_cc_get_principal (context, id, princ);
+ krb5_cc_close (context, id);
+ if (ret == 0)
+ return 0;
+ }
+
+ user = get_default_username ();
+ if (user == NULL)
+ return ENOTTY;
+ if (getuid () == 0) {
+ ret = krb5_make_principal(context, princ, NULL, user, "root", NULL);
+ } else {
+ ret = krb5_make_principal(context, princ, NULL, user, NULL);
+ }
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/get_default_realm.c b/crypto/heimdal/lib/krb5/get_default_realm.c
new file mode 100644
index 000000000000..3f9b9019a352
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_default_realm.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_default_realm.c,v 1.8 1999/12/02 17:05:09 joda Exp $");
+
+/*
+ * Return a NULL-terminated list of default realms in `realms'.
+ * Free this memory with krb5_free_host_realm.
+ */
+
+krb5_error_code
+krb5_get_default_realms (krb5_context context,
+ krb5_realm **realms)
+{
+ if (context->default_realms == NULL) {
+ krb5_error_code ret = krb5_set_default_realm (context, NULL);
+ if (ret)
+ return KRB5_CONFIG_NODEFREALM;
+ }
+
+ return krb5_copy_host_realm (context,
+ context->default_realms,
+ realms);
+}
+
+/*
+ * Return the first default realm. For compatability.
+ */
+
+krb5_error_code
+krb5_get_default_realm(krb5_context context,
+ krb5_realm *realm)
+{
+ char *res;
+
+ if (context->default_realms == NULL
+ || context->default_realms[0] == NULL) {
+ krb5_error_code ret = krb5_set_default_realm (context, NULL);
+ if (ret)
+ return KRB5_CONFIG_NODEFREALM;
+ }
+
+ res = strdup (context->default_realms[0]);
+ if (res == NULL)
+ return ENOMEM;
+ *realm = res;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/get_for_creds.c b/crypto/heimdal/lib/krb5/get_for_creds.c
new file mode 100644
index 000000000000..977515facd26
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_for_creds.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: get_for_creds.c,v 1.21 1999/12/20 00:57:37 assar Exp $");
+
+static krb5_error_code
+add_addrs(krb5_context context,
+ krb5_addresses *addr,
+ struct addrinfo *ai)
+{
+ krb5_error_code ret;
+ unsigned n, i;
+ void *tmp;
+ struct addrinfo *a;
+
+ n = 0;
+ for (a = ai; a != NULL; a = a->ai_next)
+ ++n;
+
+ i = addr->len;
+ addr->len += n;
+ tmp = realloc(addr->val, addr->len * sizeof(*addr->val));
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ addr->val = tmp;
+ for (a = ai; a != NULL; a = a->ai_next) {
+ ret = krb5_sockaddr2address (a->ai_addr, &addr->val[i++]);
+ if (ret)
+ goto fail;
+ }
+ return 0;
+fail:
+ krb5_free_addresses (context, addr);
+ return ret;
+}
+
+/*
+ *
+ */
+
+krb5_error_code
+krb5_fwd_tgt_creds (krb5_context context,
+ krb5_auth_context auth_context,
+ const char *hostname,
+ krb5_principal client,
+ krb5_principal server,
+ krb5_ccache ccache,
+ int forwardable,
+ krb5_data *out_data)
+{
+ krb5_flags flags = 0;
+ krb5_creds creds;
+ krb5_error_code ret;
+
+ flags |= KDC_OPT_FORWARDED;
+
+ if (forwardable)
+ flags |= KDC_OPT_FORWARDABLE;
+
+
+ memset (&creds, 0, sizeof(creds));
+ creds.client = client;
+ creds.server = server;
+
+ ret = krb5_get_forwarded_creds (context,
+ auth_context,
+ ccache,
+ flags,
+ hostname,
+ &creds,
+ out_data);
+ return ret;
+}
+
+/*
+ *
+ */
+
+krb5_error_code
+krb5_get_forwarded_creds (krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_ccache ccache,
+ krb5_flags flags,
+ const char *hostname,
+ krb5_creds *in_creds,
+ krb5_data *out_data)
+{
+ krb5_error_code ret;
+ krb5_creds *out_creds;
+ krb5_addresses addrs;
+ KRB_CRED cred;
+ KrbCredInfo *krb_cred_info;
+ EncKrbCredPart enc_krb_cred_part;
+ size_t len;
+ u_char buf[1024];
+ int32_t sec, usec;
+ krb5_kdc_flags kdc_flags;
+ krb5_crypto crypto;
+ struct addrinfo *ai;
+
+ addrs.len = 0;
+ addrs.val = NULL;
+
+ ret = getaddrinfo (hostname, NULL, NULL, &ai);
+ if (ret)
+ return ret;
+
+ ret = add_addrs (context, &addrs, ai);
+ freeaddrinfo (ai);
+ if (ret)
+ return ret;
+
+ kdc_flags.i = flags;
+
+ ret = krb5_get_kdc_cred (context,
+ ccache,
+ kdc_flags,
+ &addrs,
+ NULL,
+ in_creds,
+ &out_creds);
+ krb5_free_addresses (context, &addrs);
+ if (ret) {
+ return ret;
+ }
+
+ memset (&cred, 0, sizeof(cred));
+ cred.pvno = 5;
+ cred.msg_type = krb_cred;
+ ALLOC_SEQ(&cred.tickets, 1);
+ if (cred.tickets.val == NULL) {
+ ret = ENOMEM;
+ goto out2;
+ }
+ ret = decode_Ticket(out_creds->ticket.data,
+ out_creds->ticket.length,
+ cred.tickets.val, &len);
+ if (ret)
+ goto out3;
+
+ memset (&enc_krb_cred_part, 0, sizeof(enc_krb_cred_part));
+ ALLOC_SEQ(&enc_krb_cred_part.ticket_info, 1);
+ if (enc_krb_cred_part.ticket_info.val == NULL) {
+ ret = ENOMEM;
+ goto out4;
+ }
+
+ krb5_us_timeofday (context, &sec, &usec);
+
+ ALLOC(enc_krb_cred_part.timestamp, 1);
+ if (enc_krb_cred_part.timestamp == NULL) {
+ ret = ENOMEM;
+ goto out4;
+ }
+ *enc_krb_cred_part.timestamp = sec;
+ ALLOC(enc_krb_cred_part.usec, 1);
+ if (enc_krb_cred_part.usec == NULL) {
+ ret = ENOMEM;
+ goto out4;
+ }
+ *enc_krb_cred_part.usec = usec;
+
+ ret = krb5_make_addrport (&enc_krb_cred_part.s_address,
+ auth_context->local_address,
+ auth_context->local_port);
+ if (ret)
+ goto out4;
+
+ ALLOC(enc_krb_cred_part.r_address, 1);
+ if (enc_krb_cred_part.r_address == NULL) {
+ ret = ENOMEM;
+ goto out4;
+ }
+
+ ret = krb5_copy_address (context, auth_context->remote_address,
+ enc_krb_cred_part.r_address);
+ if (ret)
+ goto out4;
+
+ /* fill ticket_info.val[0] */
+
+ enc_krb_cred_part.ticket_info.len = 1;
+
+ krb_cred_info = enc_krb_cred_part.ticket_info.val;
+
+ copy_EncryptionKey (&out_creds->session, &krb_cred_info->key);
+ ALLOC(krb_cred_info->prealm, 1);
+ copy_Realm (&out_creds->client->realm, krb_cred_info->prealm);
+ ALLOC(krb_cred_info->pname, 1);
+ copy_PrincipalName(&out_creds->client->name, krb_cred_info->pname);
+ ALLOC(krb_cred_info->flags, 1);
+ *krb_cred_info->flags = out_creds->flags.b;
+ ALLOC(krb_cred_info->authtime, 1);
+ *krb_cred_info->authtime = out_creds->times.authtime;
+ ALLOC(krb_cred_info->starttime, 1);
+ *krb_cred_info->starttime = out_creds->times.starttime;
+ ALLOC(krb_cred_info->endtime, 1);
+ *krb_cred_info->endtime = out_creds->times.endtime;
+ ALLOC(krb_cred_info->renew_till, 1);
+ *krb_cred_info->renew_till = out_creds->times.renew_till;
+ ALLOC(krb_cred_info->srealm, 1);
+ copy_Realm (&out_creds->server->realm, krb_cred_info->srealm);
+ ALLOC(krb_cred_info->sname, 1);
+ copy_PrincipalName (&out_creds->server->name, krb_cred_info->sname);
+ ALLOC(krb_cred_info->caddr, 1);
+ copy_HostAddresses (&out_creds->addresses, krb_cred_info->caddr);
+
+ krb5_free_creds (context, out_creds);
+
+ /* encode EncKrbCredPart */
+
+ ret = krb5_encode_EncKrbCredPart (context,
+ buf + sizeof(buf) - 1, sizeof(buf),
+ &enc_krb_cred_part, &len);
+ free_EncKrbCredPart (&enc_krb_cred_part);
+ if (ret) {
+ free_KRB_CRED(&cred);
+ return ret;
+ }
+
+ krb5_crypto_init(context, auth_context->local_subkey, 0, &crypto);
+ ret = krb5_encrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_KRB_CRED,
+ buf + sizeof(buf) - len,
+ len,
+ 0,
+ &cred.enc_part);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ free_KRB_CRED(&cred);
+ return ret;
+ }
+
+ ret = encode_KRB_CRED (buf + sizeof(buf) - 1, sizeof(buf),
+ &cred, &len);
+ free_KRB_CRED (&cred);
+ if (ret)
+ return ret;
+ out_data->length = len;
+ out_data->data = malloc(len);
+ if (out_data->data == NULL)
+ return ENOMEM;
+ memcpy (out_data->data, buf + sizeof(buf) - len, len);
+ return 0;
+out4:
+ free_EncKrbCredPart(&enc_krb_cred_part);
+out3:
+ free_KRB_CRED(&cred);
+out2:
+ krb5_free_creds (context, out_creds);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/get_host_realm.c b/crypto/heimdal/lib/krb5/get_host_realm.c
new file mode 100644
index 000000000000..e8522cbc48d9
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_host_realm.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+#include <resolve.h>
+
+RCSID("$Id: get_host_realm.c,v 1.25 1999/12/11 23:14:07 assar Exp $");
+
+/* To automagically find the correct realm of a host (without
+ * [domain_realm] in krb5.conf) add a text record for your domain with
+ * the name of your realm, like this:
+ *
+ * krb5-realm IN TXT FOO.SE
+ *
+ * The search is recursive, so you can add entries for specific
+ * hosts. To find the realm of host a.b.c, it first tries
+ * krb5-realm.a.b.c, then krb5-realm.b.c and so on.
+ *
+ * Also supported is _kerberos (following draft-ietf-cat-krb-dns-locate-01.txt)
+ *
+ */
+
+static int
+copy_txt_to_realms (struct resource_record *head,
+ krb5_realm **realms)
+{
+ struct resource_record *rr;
+ int n, i;
+
+ for(n = 0, rr = head; rr; rr = rr->next)
+ if (rr->type == T_TXT)
+ ++n;
+
+ if (n == 0)
+ return -1;
+
+ *realms = malloc ((n + 1) * sizeof(krb5_realm));
+ if (*realms == NULL)
+ return -1;
+
+ for (i = 0; i < n + 1; ++i)
+ (*realms)[i] = NULL;
+
+ for (i = 0, rr = head; rr; rr = rr->next) {
+ if (rr->type == T_TXT) {
+ char *tmp;
+
+ tmp = strdup(rr->u.txt);
+ if (tmp == NULL) {
+ for (i = 0; i < n; ++i)
+ free ((*realms)[i]);
+ free (*realms);
+ return -1;
+ }
+ (*realms)[i] = tmp;
+ ++i;
+ }
+ }
+ return 0;
+}
+
+static int
+dns_find_realm(krb5_context context,
+ const char *domain,
+ const char *dom_string,
+ krb5_realm **realms)
+{
+ char dom[MAXHOSTNAMELEN];
+ struct dns_reply *r;
+ int ret;
+
+ if(*domain == '.')
+ domain++;
+ snprintf(dom, sizeof(dom), "%s.%s.", dom_string, domain);
+ r = dns_lookup(dom, "TXT");
+ if(r == NULL)
+ return -1;
+
+ ret = copy_txt_to_realms (r->head, realms);
+ dns_free_data(r);
+ return ret;
+}
+
+/*
+ * Try to figure out what realms host in `domain' belong to from the
+ * configuration file.
+ */
+
+static int
+config_find_realm(krb5_context context,
+ const char *domain,
+ krb5_realm **realms)
+{
+ char **tmp = krb5_config_get_strings (context, NULL,
+ "domain_realm",
+ domain,
+ NULL);
+
+ if (tmp == NULL)
+ return -1;
+ *realms = tmp;
+ return 0;
+}
+
+/*
+ * This function assumes that `host' is a FQDN (and doesn't handle the
+ * special case of host == NULL either).
+ * Try to find mapping in the config file or DNS and it that fails,
+ * fall back to guessing
+ */
+
+krb5_error_code
+krb5_get_host_realm_int (krb5_context context,
+ const char *host,
+ krb5_realm **realms)
+{
+ const char *p;
+
+ for (p = host; p != NULL; p = strchr (p + 1, '.')) {
+ if(config_find_realm(context, p, realms) == 0)
+ return 0;
+ else if(dns_find_realm(context, p, "krb5-realm", realms) == 0)
+ return 0;
+ else if(dns_find_realm(context, p, "_kerberos", realms) == 0)
+ return 0;
+ }
+ p = strchr(host, '.');
+ if(p != NULL) {
+ p++;
+ *realms = malloc(2 * sizeof(krb5_realm));
+ if (*realms == NULL)
+ return ENOMEM;
+
+ (*realms)[0] = strdup(p);
+ if((*realms)[0] == NULL) {
+ free(*realms);
+ return ENOMEM;
+ }
+ strupr((*realms)[0]);
+ (*realms)[1] = NULL;
+ return 0;
+ }
+ return KRB5_ERR_HOST_REALM_UNKNOWN;
+}
+
+/*
+ * Return the realm(s) of `host' as a NULL-terminated list in `realms'.
+ */
+
+krb5_error_code
+krb5_get_host_realm(krb5_context context,
+ const char *host,
+ krb5_realm **realms)
+{
+ char hostname[MAXHOSTNAMELEN];
+
+ if (host == NULL) {
+ if (gethostname (hostname, sizeof(hostname)))
+ return errno;
+ host = hostname;
+ }
+
+ return krb5_get_host_realm_int (context, host, realms);
+}
diff --git a/crypto/heimdal/lib/krb5/get_in_tkt.c b/crypto/heimdal/lib/krb5/get_in_tkt.c
new file mode 100644
index 000000000000..f65af470ba12
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_in_tkt.c
@@ -0,0 +1,794 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_in_tkt.c,v 1.93 2000/01/06 20:36:28 assar Exp $");
+
+krb5_error_code
+krb5_init_etype (krb5_context context,
+ unsigned *len,
+ int **val,
+ const krb5_enctype *etypes)
+{
+ int i;
+ krb5_error_code ret;
+ krb5_enctype *tmp;
+
+ ret = 0;
+ if (etypes)
+ tmp = (krb5_enctype*)etypes;
+ else {
+ ret = krb5_get_default_in_tkt_etypes(context,
+ &tmp);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; tmp[i]; ++i)
+ ;
+ *len = i;
+ *val = malloc(i * sizeof(int));
+ if (i != 0 && *val == NULL) {
+ ret = ENOMEM;
+ goto cleanup;
+ }
+ memmove (*val,
+ tmp,
+ i * sizeof(*tmp));
+cleanup:
+ if (etypes == NULL)
+ free (tmp);
+ return ret;
+}
+
+
+static krb5_error_code
+decrypt_tkt (krb5_context context,
+ krb5_keyblock *key,
+ krb5_key_usage usage,
+ krb5_const_pointer decrypt_arg,
+ krb5_kdc_rep *dec_rep)
+{
+ krb5_error_code ret;
+ krb5_data data;
+ size_t size;
+ krb5_crypto crypto;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ usage,
+ &dec_rep->kdc_rep.enc_part,
+ &data);
+ krb5_crypto_destroy(context, crypto);
+
+ if (ret)
+ return ret;
+
+ ret = krb5_decode_EncASRepPart(context,
+ data.data,
+ data.length,
+ &dec_rep->enc_part,
+ &size);
+ if (ret)
+ ret = krb5_decode_EncTGSRepPart(context,
+ data.data,
+ data.length,
+ &dec_rep->enc_part,
+ &size);
+ krb5_data_free (&data);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+int
+_krb5_extract_ticket(krb5_context context,
+ krb5_kdc_rep *rep,
+ krb5_creds *creds,
+ krb5_keyblock *key,
+ krb5_const_pointer keyseed,
+ krb5_key_usage key_usage,
+ krb5_addresses *addrs,
+ unsigned nonce,
+ krb5_boolean allow_server_mismatch,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg)
+{
+ krb5_error_code ret;
+ krb5_principal tmp_principal;
+ int tmp;
+ time_t tmp_time;
+ int32_t sec_now;
+
+ /* compare client */
+
+ ret = principalname2krb5_principal (&tmp_principal,
+ rep->kdc_rep.cname,
+ rep->kdc_rep.crealm);
+ if (ret)
+ goto out;
+ tmp = krb5_principal_compare (context, tmp_principal, creds->client);
+ krb5_free_principal (context, tmp_principal);
+ if (!tmp) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ /* extract ticket */
+ {
+ unsigned char *buf;
+ size_t len;
+ len = length_Ticket(&rep->kdc_rep.ticket);
+ buf = malloc(len);
+ if(buf == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ encode_Ticket(buf + len - 1, len, &rep->kdc_rep.ticket, &len);
+ creds->ticket.data = buf;
+ creds->ticket.length = len;
+ creds->second_ticket.length = 0;
+ creds->second_ticket.data = NULL;
+ }
+
+ /* compare server */
+
+ ret = principalname2krb5_principal (&tmp_principal,
+ rep->kdc_rep.ticket.sname,
+ rep->kdc_rep.ticket.realm);
+ if (ret)
+ goto out;
+ if(allow_server_mismatch){
+ krb5_free_principal(context, creds->server);
+ creds->server = tmp_principal;
+ tmp_principal = NULL;
+ }else{
+ tmp = krb5_principal_compare (context, tmp_principal, creds->server);
+ krb5_free_principal (context, tmp_principal);
+ if (!tmp) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+ }
+
+ /* decrypt */
+
+ if (decrypt_proc == NULL)
+ decrypt_proc = decrypt_tkt;
+
+ ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
+ if (ret)
+ goto out;
+
+#if 0
+ /* XXX should this decode be here, or in the decrypt_proc? */
+ ret = krb5_decode_keyblock(context, &rep->enc_part.key, 1);
+ if(ret)
+ goto out;
+#endif
+
+ /* compare nonces */
+
+ if (nonce != rep->enc_part.nonce) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ /* set kdc-offset */
+
+ krb5_timeofday (context, &sec_now);
+ if (context->kdc_sec_offset == 0
+ && krb5_config_get_bool (context, NULL,
+ "libdefaults",
+ "kdc_timesync",
+ NULL)) {
+ context->kdc_sec_offset = rep->enc_part.authtime - sec_now;
+ krb5_timeofday (context, &sec_now);
+ }
+
+ /* check all times */
+
+ if (rep->enc_part.starttime) {
+ tmp_time = *rep->enc_part.starttime;
+ } else
+ tmp_time = rep->enc_part.authtime;
+
+ if (creds->times.starttime == 0
+ && abs(tmp_time - sec_now) > context->max_skew) {
+ ret = KRB5KRB_AP_ERR_SKEW;
+ goto out;
+ }
+
+ if (creds->times.starttime != 0
+ && tmp_time != creds->times.starttime) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ creds->times.starttime = tmp_time;
+
+ if (rep->enc_part.renew_till) {
+ tmp_time = *rep->enc_part.renew_till;
+ } else
+ tmp_time = 0;
+
+ if (creds->times.renew_till != 0
+ && tmp_time > creds->times.renew_till) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ creds->times.renew_till = tmp_time;
+
+ creds->times.authtime = rep->enc_part.authtime;
+
+ if (creds->times.endtime != 0
+ && rep->enc_part.endtime > creds->times.endtime) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ creds->times.endtime = rep->enc_part.endtime;
+
+ if(rep->enc_part.caddr)
+ krb5_copy_addresses (context, rep->enc_part.caddr, &creds->addresses);
+ else if(addrs)
+ krb5_copy_addresses (context, addrs, &creds->addresses);
+ else {
+ creds->addresses.len = 0;
+ creds->addresses.val = NULL;
+ }
+ creds->flags.b = rep->enc_part.flags;
+
+ creds->authdata.len = 0;
+ creds->authdata.val = NULL;
+ creds->session.keyvalue.length = 0;
+ creds->session.keyvalue.data = NULL;
+ creds->session.keytype = rep->enc_part.key.keytype;
+ ret = krb5_data_copy (&creds->session.keyvalue,
+ rep->enc_part.key.keyvalue.data,
+ rep->enc_part.key.keyvalue.length);
+
+out:
+ memset (rep->enc_part.key.keyvalue.data, 0,
+ rep->enc_part.key.keyvalue.length);
+ return ret;
+}
+
+
+static krb5_error_code
+make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
+ krb5_enctype etype, krb5_keyblock *key)
+{
+ PA_ENC_TS_ENC p;
+ u_char buf[1024];
+ size_t len;
+ EncryptedData encdata;
+ krb5_error_code ret;
+ int32_t sec, usec;
+ int usec2;
+ krb5_crypto crypto;
+
+ krb5_us_timeofday (context, &sec, &usec);
+ p.patimestamp = sec;
+ usec2 = usec;
+ p.pausec = &usec2;
+
+ ret = encode_PA_ENC_TS_ENC(buf + sizeof(buf) - 1,
+ sizeof(buf),
+ &p,
+ &len);
+ if (ret)
+ return ret;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_encrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_PA_ENC_TIMESTAMP,
+ buf + sizeof(buf) - len,
+ len,
+ 0,
+ &encdata);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ return ret;
+
+ ret = encode_EncryptedData(buf + sizeof(buf) - 1,
+ sizeof(buf),
+ &encdata,
+ &len);
+ free_EncryptedData(&encdata);
+ if (ret)
+ return ret;
+ pa->padata_type = pa_enc_timestamp;
+ pa->padata_value.length = 0;
+ krb5_data_copy(&pa->padata_value,
+ buf + sizeof(buf) - len,
+ len);
+ return 0;
+}
+
+static krb5_error_code
+add_padata(krb5_context context,
+ METHOD_DATA *md,
+ krb5_principal client,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ int *enctypes,
+ unsigned netypes,
+ krb5_salt *salt)
+{
+ krb5_error_code ret;
+ PA_DATA *pa2;
+ krb5_salt salt2;
+ int *ep;
+ int i;
+
+ if(salt == NULL) {
+ /* default to standard salt */
+ ret = krb5_get_pw_salt (context, client, &salt2);
+ salt = &salt2;
+ }
+ if (!enctypes) {
+ enctypes = (int *)context->etypes; /* XXX */
+ netypes = 0;
+ for (ep = enctypes; *ep != ETYPE_NULL; ep++)
+ netypes++;
+ }
+ pa2 = realloc (md->val, (md->len + netypes) * sizeof(*md->val));
+ if (pa2 == NULL)
+ return ENOMEM;
+ md->val = pa2;
+
+ for (i = 0; i < netypes; ++i) {
+ krb5_keyblock *key;
+
+ ret = (*key_proc)(context, enctypes[i], *salt, keyseed, &key);
+ if (ret)
+ continue;
+ ret = make_pa_enc_timestamp (context, &md->val[md->len],
+ enctypes[i], key);
+ krb5_free_keyblock (context, key);
+ if (ret)
+ return ret;
+ ++md->len;
+ }
+ if(salt == &salt2)
+ krb5_free_salt(context, salt2);
+ return 0;
+}
+
+static krb5_error_code
+init_as_req (krb5_context context,
+ krb5_kdc_flags opts,
+ krb5_creds *creds,
+ const krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *ptypes,
+ const krb5_preauthdata *preauth,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ unsigned nonce,
+ AS_REQ *a)
+{
+ krb5_error_code ret;
+ krb5_salt salt;
+
+ memset(a, 0, sizeof(*a));
+
+ a->pvno = 5;
+ a->msg_type = krb_as_req;
+ a->req_body.kdc_options = opts.b;
+ a->req_body.cname = malloc(sizeof(*a->req_body.cname));
+ if (a->req_body.cname == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ a->req_body.sname = malloc(sizeof(*a->req_body.sname));
+ if (a->req_body.sname == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ ret = krb5_principal2principalname (a->req_body.cname, creds->client);
+ if (ret)
+ goto fail;
+ ret = krb5_principal2principalname (a->req_body.sname, creds->server);
+ if (ret)
+ goto fail;
+ ret = copy_Realm(&creds->client->realm, &a->req_body.realm);
+ if (ret)
+ goto fail;
+
+ if(creds->times.starttime) {
+ a->req_body.from = malloc(sizeof(*a->req_body.from));
+ if (a->req_body.from == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ *a->req_body.from = creds->times.starttime;
+ }
+ if(creds->times.endtime){
+ ALLOC(a->req_body.till, 1);
+ *a->req_body.till = creds->times.endtime;
+ }
+ if(creds->times.renew_till){
+ a->req_body.rtime = malloc(sizeof(*a->req_body.rtime));
+ if (a->req_body.rtime == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ *a->req_body.rtime = creds->times.renew_till;
+ }
+ a->req_body.nonce = nonce;
+ ret = krb5_init_etype (context,
+ &a->req_body.etype.len,
+ &a->req_body.etype.val,
+ etypes);
+ if (ret)
+ goto fail;
+
+ /*
+ * This means no addresses
+ */
+
+ if (addrs && addrs->len == 0) {
+ a->req_body.addresses = NULL;
+ } else {
+ a->req_body.addresses = malloc(sizeof(*a->req_body.addresses));
+ if (a->req_body.addresses == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ if (addrs)
+ ret = krb5_copy_addresses(context, addrs, a->req_body.addresses);
+ else
+ ret = krb5_get_all_client_addrs (context, a->req_body.addresses);
+ if (ret)
+ return ret;
+ }
+
+ a->req_body.enc_authorization_data = NULL;
+ a->req_body.additional_tickets = NULL;
+
+ if(preauth != NULL) {
+ int i;
+ ALLOC(a->padata, 1);
+ if(a->padata == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ for(i = 0; i < preauth->len; i++) {
+ if(preauth->val[i].type == KRB5_PADATA_ENC_TIMESTAMP){
+ int j;
+ PA_DATA *tmp = realloc(a->padata->val,
+ (a->padata->len +
+ preauth->val[i].info.len) *
+ sizeof(*a->padata->val));
+ if(tmp == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ a->padata->val = tmp;
+ for(j = 0; j < preauth->val[i].info.len; j++) {
+ krb5_salt *sp = &salt;
+ if(preauth->val[i].info.val[j].salttype)
+ salt.salttype = *preauth->val[i].info.val[j].salttype;
+ else
+ salt.salttype = KRB5_PW_SALT;
+ if(preauth->val[i].info.val[j].salt)
+ salt.saltvalue = *preauth->val[i].info.val[j].salt;
+ else
+ if(salt.salttype == KRB5_PW_SALT)
+ sp = NULL;
+ else
+ krb5_data_zero(&salt.saltvalue);
+ add_padata(context, a->padata, creds->client,
+ key_proc, keyseed,
+ &preauth->val[i].info.val[j].etype, 1,
+ sp);
+ }
+ }
+ }
+ } else
+ /* not sure this is the way to use `ptypes' */
+ if (ptypes == NULL || *ptypes == KRB5_PADATA_NONE)
+ a->padata = NULL;
+ else if (*ptypes == KRB5_PADATA_ENC_TIMESTAMP) {
+ ALLOC(a->padata, 1);
+ if (a->padata == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ a->padata->len = 0;
+ a->padata->val = NULL;
+
+ /* make a v5 salted pa-data */
+ add_padata(context, a->padata, creds->client,
+ key_proc, keyseed, a->req_body.etype.val,
+ a->req_body.etype.len, NULL);
+
+ /* make a v4 salted pa-data */
+ salt.salttype = KRB5_PW_SALT;
+ krb5_data_zero(&salt.saltvalue);
+ add_padata(context, a->padata, creds->client,
+ key_proc, keyseed, a->req_body.etype.val,
+ a->req_body.etype.len, &salt);
+ } else {
+ ret = KRB5_PREAUTH_BAD_TYPE;
+ goto fail;
+ }
+ return 0;
+fail:
+ free_AS_REQ(a);
+ return ret;
+}
+
+static int
+set_ptypes(krb5_context context,
+ KRB_ERROR *error,
+ krb5_preauthtype **ptypes,
+ krb5_preauthdata **preauth)
+{
+ static krb5_preauthdata preauth2;
+ static krb5_preauthtype ptypes2[] = { KRB5_PADATA_ENC_TIMESTAMP, KRB5_PADATA_NONE };
+
+ if(error->e_data) {
+ METHOD_DATA md;
+ int i;
+ decode_METHOD_DATA(error->e_data->data,
+ error->e_data->length,
+ &md,
+ NULL);
+ for(i = 0; i < md.len; i++){
+ switch(md.val[i].padata_type){
+ case pa_enc_timestamp:
+ *ptypes = ptypes2;
+ break;
+ case pa_etype_info:
+ *preauth = &preauth2;
+ ALLOC_SEQ(*preauth, 1);
+ (*preauth)->val[0].type = KRB5_PADATA_ENC_TIMESTAMP;
+ krb5_decode_ETYPE_INFO(context,
+ md.val[i].padata_value.data,
+ md.val[i].padata_value.length,
+ &(*preauth)->val[0].info,
+ NULL);
+ break;
+ }
+ }
+ free_METHOD_DATA(&md);
+ } else {
+ *ptypes = ptypes2;
+ }
+ return(1);
+}
+
+krb5_error_code
+krb5_get_in_cred(krb5_context context,
+ krb5_flags options,
+ const krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *ptypes,
+ const krb5_preauthdata *preauth,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply)
+{
+ krb5_error_code ret;
+ AS_REQ a;
+ krb5_kdc_rep rep;
+ krb5_data req, resp;
+ char buf[BUFSIZ];
+ krb5_salt salt;
+ krb5_keyblock *key;
+ size_t size;
+ krb5_kdc_flags opts;
+ PA_DATA *pa;
+ krb5_enctype etype;
+ krb5_preauthdata *my_preauth = NULL;
+ unsigned nonce;
+ int done;
+
+ opts.i = options;
+
+ krb5_generate_random_block (&nonce, sizeof(nonce));
+ nonce &= 0xffffffff;
+
+ do {
+ done = 1;
+ ret = init_as_req (context,
+ opts,
+ creds,
+ addrs,
+ etypes,
+ ptypes,
+ preauth,
+ key_proc,
+ keyseed,
+ nonce,
+ &a);
+ if (my_preauth) {
+ free_ETYPE_INFO(&my_preauth->val[0].info);
+ free (my_preauth->val);
+ }
+ if (ret)
+ return ret;
+
+ ret = encode_AS_REQ ((unsigned char*)buf + sizeof(buf) - 1,
+ sizeof(buf),
+ &a,
+ &req.length);
+ free_AS_REQ(&a);
+ if (ret)
+ return ret;
+
+ req.data = buf + sizeof(buf) - req.length;
+
+ ret = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
+ if (ret)
+ return ret;
+
+ memset (&rep, 0, sizeof(rep));
+ ret = decode_AS_REP(resp.data, resp.length, &rep.kdc_rep, &size);
+ if(ret) {
+ /* let's try to parse it as a KRB-ERROR */
+ KRB_ERROR error;
+ int ret2;
+
+ ret2 = krb5_rd_error(context, &resp, &error);
+ if(ret2 && resp.data && ((char*)resp.data)[0] == 4)
+ ret = KRB5KRB_AP_ERR_V4_REPLY;
+ krb5_data_free(&resp);
+ if (ret2 == 0) {
+ ret = error.error_code;
+ /* if no preauth was set and KDC requires it, give it
+ one more try */
+ if (!ptypes && !preauth
+ && ret == KRB5KDC_ERR_PREAUTH_REQUIRED
+#if 0
+ || ret == KRB5KDC_ERR_BADOPTION
+#endif
+ && set_ptypes(context, &error, &ptypes, &my_preauth)) {
+ done = 0;
+ preauth = my_preauth;
+ free_KRB_ERROR(&error);
+ continue;
+ }
+ if(ret_as_reply)
+ ret_as_reply->error = error;
+ else
+ free_KRB_ERROR (&error);
+ return ret;
+ }
+ return ret;
+ }
+ krb5_data_free(&resp);
+ } while(!done);
+
+ pa = NULL;
+ etype = rep.kdc_rep.enc_part.etype;
+ if(rep.kdc_rep.padata){
+ int index = 0;
+ pa = krb5_find_padata(rep.kdc_rep.padata->val, rep.kdc_rep.padata->len,
+ pa_pw_salt, &index);
+ if(pa == NULL) {
+ index = 0;
+ pa = krb5_find_padata(rep.kdc_rep.padata->val,
+ rep.kdc_rep.padata->len,
+ pa_afs3_salt, &index);
+ }
+ }
+ if(pa) {
+ salt.salttype = pa->padata_type;
+ salt.saltvalue = pa->padata_value;
+
+ ret = (*key_proc)(context, etype, salt, keyseed, &key);
+ } else {
+ /* make a v5 salted pa-data */
+ ret = krb5_get_pw_salt (context, creds->client, &salt);
+
+ if (ret)
+ goto out;
+ ret = (*key_proc)(context, etype, salt, keyseed, &key);
+ krb5_free_salt(context, salt);
+ }
+ if (ret)
+ goto out;
+
+ ret = _krb5_extract_ticket(context,
+ &rep,
+ creds,
+ key,
+ keyseed,
+ KRB5_KU_AS_REP_ENC_PART,
+ NULL,
+ nonce,
+ FALSE,
+ decrypt_proc,
+ decryptarg);
+ memset (key->keyvalue.data, 0, key->keyvalue.length);
+ krb5_free_keyblock_contents (context, key);
+ free (key);
+
+out:
+ if (ret == 0 && ret_as_reply)
+ *ret_as_reply = rep;
+ else
+ krb5_free_kdc_rep (context, &rep);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_in_tkt(krb5_context context,
+ krb5_flags options,
+ const krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *ptypes,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg,
+ krb5_creds *creds,
+ krb5_ccache ccache,
+ krb5_kdc_rep *ret_as_reply)
+{
+ krb5_error_code ret;
+ krb5_kdc_flags opts;
+ opts.i = 0;
+ opts.b = int2KDCOptions(options);
+
+ ret = krb5_get_in_cred (context,
+ opts.i,
+ addrs,
+ etypes,
+ ptypes,
+ NULL,
+ key_proc,
+ keyseed,
+ decrypt_proc,
+ decryptarg,
+ creds,
+ ret_as_reply);
+ if(ret)
+ return ret;
+ ret = krb5_cc_store_cred (context, ccache, creds);
+ krb5_free_creds_contents (context, creds);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/get_in_tkt_pw.c b/crypto/heimdal/lib/krb5/get_in_tkt_pw.c
new file mode 100644
index 000000000000..4fb8800bfdcc
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_in_tkt_pw.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_in_tkt_pw.c,v 1.15 1999/12/02 17:05:10 joda Exp $");
+
+krb5_error_code
+krb5_password_key_proc (krb5_context context,
+ krb5_enctype type,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key)
+{
+ krb5_error_code ret;
+ const char *password = (const char *)keyseed;
+ char buf[BUFSIZ];
+
+ *key = malloc (sizeof (**key));
+ if (*key == NULL)
+ return ENOMEM;
+ if (password == NULL) {
+ if(des_read_pw_string (buf, sizeof(buf), "Password: ", 0)) {
+ free (*key);
+ return KRB5_LIBOS_PWDINTR;
+ }
+ password = buf;
+ }
+ ret = krb5_string_to_key_salt (context, type, password, salt, *key);
+ memset (buf, 0, sizeof(buf));
+ return ret;
+}
+
+krb5_error_code
+krb5_get_in_tkt_with_password (krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ const char *password,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply)
+{
+ return krb5_get_in_tkt (context,
+ options,
+ addrs,
+ etypes,
+ pre_auth_types,
+ krb5_password_key_proc,
+ password,
+ NULL,
+ NULL,
+ creds,
+ ccache,
+ ret_as_reply);
+}
diff --git a/crypto/heimdal/lib/krb5/get_in_tkt_with_keytab.c b/crypto/heimdal/lib/krb5/get_in_tkt_with_keytab.c
new file mode 100644
index 000000000000..d78ef354e3fd
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_in_tkt_with_keytab.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_in_tkt_with_keytab.c,v 1.5 1999/12/02 17:05:10 joda Exp $");
+
+krb5_error_code
+krb5_keytab_key_proc (krb5_context context,
+ krb5_enctype enctype,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key)
+{
+ krb5_keytab_key_proc_args *args = (krb5_keytab_key_proc_args *)keyseed;
+ krb5_keytab keytab = args->keytab;
+ krb5_principal principal = args->principal;
+ krb5_error_code ret;
+ krb5_keytab real_keytab;
+ krb5_keytab_entry entry;
+
+ if(keytab == NULL)
+ krb5_kt_default(context, &real_keytab);
+ else
+ real_keytab = keytab;
+
+ ret = krb5_kt_get_entry (context, real_keytab, principal,
+ 0, enctype, &entry);
+
+ if (keytab == NULL)
+ krb5_kt_close (context, real_keytab);
+
+ if (ret)
+ return ret;
+
+ ret = krb5_copy_keyblock (context, &entry.keyblock, key);
+ krb5_kt_free_entry(context, &entry);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_in_tkt_with_keytab (krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ krb5_keytab keytab,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply)
+{
+ krb5_keytab_key_proc_args *a;
+
+ a = malloc(sizeof(*a));
+ if (a == NULL)
+ return ENOMEM;
+
+ a->principal = creds->client;
+ a->keytab = keytab;
+
+ return krb5_get_in_tkt (context,
+ options,
+ addrs,
+ etypes,
+ pre_auth_types,
+ krb5_keytab_key_proc,
+ a,
+ NULL,
+ NULL,
+ creds,
+ ccache,
+ ret_as_reply);
+}
diff --git a/crypto/heimdal/lib/krb5/get_in_tkt_with_skey.c b/crypto/heimdal/lib/krb5/get_in_tkt_with_skey.c
new file mode 100644
index 000000000000..773d36175812
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_in_tkt_with_skey.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_in_tkt_with_skey.c,v 1.3 1999/12/02 17:05:10 joda Exp $");
+
+static krb5_error_code
+krb5_skey_key_proc (krb5_context context,
+ krb5_enctype type,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key)
+{
+ return krb5_copy_keyblock (context, keyseed, key);
+}
+
+krb5_error_code
+krb5_get_in_tkt_with_skey (krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ const krb5_keyblock *key,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply)
+{
+ if(key == NULL)
+ return krb5_get_in_tkt_with_keytab (context,
+ options,
+ addrs,
+ etypes,
+ pre_auth_types,
+ NULL,
+ ccache,
+ creds,
+ ret_as_reply);
+ else
+ return krb5_get_in_tkt (context,
+ options,
+ addrs,
+ etypes,
+ pre_auth_types,
+ krb5_skey_key_proc,
+ key,
+ NULL,
+ NULL,
+ creds,
+ ccache,
+ ret_as_reply);
+}
diff --git a/crypto/heimdal/lib/krb5/get_port.c b/crypto/heimdal/lib/krb5/get_port.c
new file mode 100644
index 000000000000..17bb45f67d43
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_port.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: get_port.c,v 1.7 1999/12/02 17:05:10 joda Exp $");
+
+int
+krb5_getportbyname (krb5_context context,
+ const char *service,
+ const char *proto,
+ int default_port)
+{
+ struct servent *sp;
+
+ if ((sp = roken_getservbyname (service, proto)) == NULL) {
+ krb5_warnx(context, "%s/%s unknown service, using default port %d",
+ service, proto, default_port);
+ return htons(default_port);
+ } else
+ return sp->s_port;
+}
diff --git a/crypto/heimdal/lib/krb5/heim_err.et b/crypto/heimdal/lib/krb5/heim_err.et
new file mode 100644
index 000000000000..5ec35434f396
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/heim_err.et
@@ -0,0 +1,18 @@
+#
+# Error messages for the krb5 library
+#
+# This might look like a com_err file, but is not
+#
+id "$Id: heim_err.et,v 1.7 1999/08/25 20:49:17 joda Exp $"
+
+error_table heim
+
+prefix HEIM_ERR
+
+error_code LOG_PARSE, "Error parsing log destination"
+error_code V4_PRINC_NO_CONV, "Failed to convert v4 principal"
+error_code SALTTYPE_NOSUPP, "Salt type is not supported by enctype"
+error_code NOHOST, "Host not found"
+error_code OPNOTSUPP, "Operation not supported"
+
+end
diff --git a/crypto/heimdal/lib/krb5/init_creds.c b/crypto/heimdal/lib/krb5/init_creds.c
new file mode 100644
index 000000000000..404fa5a2acb4
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/init_creds.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: init_creds.c,v 1.2 1999/12/02 17:05:10 joda Exp $");
+
+void
+krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
+{
+ memset (opt, 0, sizeof(*opt));
+ opt->flags = 0;
+}
+
+void
+krb5_get_init_creds_opt_set_tkt_life(krb5_get_init_creds_opt *opt,
+ krb5_deltat tkt_life)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_TKT_LIFE;
+ opt->tkt_life = tkt_life;
+}
+
+void
+krb5_get_init_creds_opt_set_renew_life(krb5_get_init_creds_opt *opt,
+ krb5_deltat renew_life)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE;
+ opt->renew_life = renew_life;
+}
+
+void
+krb5_get_init_creds_opt_set_forwardable(krb5_get_init_creds_opt *opt,
+ int forwardable)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_FORWARDABLE;
+ opt->forwardable = forwardable;
+}
+
+void
+krb5_get_init_creds_opt_set_proxiable(krb5_get_init_creds_opt *opt,
+ int proxiable)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_PROXIABLE;
+ opt->proxiable = proxiable;
+}
+
+void
+krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt *opt,
+ krb5_enctype *etype_list,
+ int etype_list_length)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST;
+ opt->etype_list = etype_list;
+ opt->etype_list_length = etype_list_length;
+}
+
+void
+krb5_get_init_creds_opt_set_address_list(krb5_get_init_creds_opt *opt,
+ krb5_addresses *addresses)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST;
+ opt->address_list = addresses;
+}
+
+void
+krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt,
+ krb5_preauthtype *preauth_list,
+ int preauth_list_length)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST;
+ opt->preauth_list_length = preauth_list_length;
+ opt->preauth_list = preauth_list;
+}
+
+void
+krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt,
+ krb5_data *salt)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_SALT;
+ opt->salt = salt;
+}
diff --git a/crypto/heimdal/lib/krb5/init_creds_pw.c b/crypto/heimdal/lib/krb5/init_creds_pw.c
new file mode 100644
index 000000000000..84b295f4751c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/init_creds_pw.c
@@ -0,0 +1,547 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: init_creds_pw.c,v 1.36 1999/12/02 17:05:10 joda Exp $");
+
+static int
+get_config_time (krb5_context context,
+ char *realm,
+ char *name,
+ int def)
+{
+ int ret;
+
+ ret = krb5_config_get_time (context, NULL,
+ "realms",
+ realm,
+ name,
+ NULL);
+ if (ret >= 0)
+ return ret;
+ ret = krb5_config_get_time (context, NULL,
+ "libdefaults",
+ name,
+ NULL);
+ if (ret >= 0)
+ return ret;
+ return def;
+}
+
+static krb5_boolean
+get_config_bool (krb5_context context,
+ char *realm,
+ char *name)
+{
+ return krb5_config_get_bool (context,
+ NULL,
+ "realms",
+ realm,
+ name,
+ NULL)
+ || krb5_config_get_bool (context,
+ NULL,
+ "libdefaults",
+ name,
+ NULL);
+}
+
+static krb5_error_code
+init_cred (krb5_context context,
+ krb5_creds *cred,
+ krb5_principal client,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options)
+{
+ krb5_error_code ret;
+ krb5_realm *client_realm;
+ int tmp;
+ int32_t now;
+
+ krb5_timeofday (context, &now);
+
+ memset (cred, 0, sizeof(*cred));
+
+ if (client)
+ krb5_copy_principal(context, client, &cred->client);
+ else {
+ ret = krb5_get_default_principal (context,
+ &cred->client);
+ if (ret)
+ goto out;
+ }
+
+ client_realm = krb5_princ_realm (context, cred->client);
+
+ if (start_time)
+ cred->times.starttime = now + start_time;
+
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE)
+ tmp = options->tkt_life;
+ else
+ tmp = get_config_time (context,
+ *client_realm,
+ "ticket_lifetime",
+ 10 * 60 * 60);
+ cred->times.endtime = now + tmp;
+
+ tmp = 0;
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE)
+ tmp = options->renew_life;
+ else
+ tmp = get_config_time (context,
+ *client_realm,
+ "renew_lifetime",
+ 0);
+ if (tmp)
+ cred->times.renew_till = now + tmp;
+
+ if (in_tkt_service) {
+ krb5_realm server_realm;
+
+ ret = krb5_parse_name (context, in_tkt_service, &cred->server);
+ if (ret)
+ goto out;
+ server_realm = strdup (*client_realm);
+ free (cred->server->realm);
+ krb5_princ_set_realm (context, cred->server, &server_realm);
+ } else {
+ ret = krb5_make_principal(context, &cred->server,
+ *client_realm, KRB5_TGS_NAME, *client_realm,
+ NULL);
+ if (ret)
+ goto out;
+ }
+ return 0;
+
+out:
+ krb5_free_creds_contents (context, cred);
+ return ret;
+}
+
+/*
+ * Parse the last_req data and show it to the user if it's interesting
+ */
+
+static void
+print_expire (krb5_context context,
+ krb5_realm *realm,
+ krb5_kdc_rep *rep,
+ krb5_prompter_fct prompter,
+ krb5_data *data)
+{
+ int i;
+ LastReq *lr = &rep->enc_part.last_req;
+ int32_t sec;
+ time_t t;
+
+ krb5_timeofday (context, &sec);
+
+ t = sec + get_config_time (context,
+ *realm,
+ "warn_pwexpire",
+ 7 * 24 * 60 * 60);
+
+ for (i = 0; i < lr->len; ++i) {
+ if (lr->val[i].lr_type == 6
+ && lr->val[i].lr_value <= t) {
+ char *p;
+
+ asprintf (&p, "Your password will expire at %s",
+ ctime(&lr->val[i].lr_value));
+ (*prompter) (context, data, p, 0, NULL);
+ free (p);
+ return;
+ }
+ }
+
+ if (rep->enc_part.key_expiration
+ && *rep->enc_part.key_expiration <= t) {
+ char *p;
+
+ asprintf (&p, "Your password/account will expire at %s",
+ ctime(rep->enc_part.key_expiration));
+ (*prompter) (context, data, p, 0, NULL);
+ free (p);
+ }
+}
+
+static krb5_error_code
+get_init_creds_common(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options,
+ krb5_addresses **addrs,
+ krb5_enctype **etypes,
+ krb5_creds *cred,
+ krb5_preauthtype **pre_auth_types,
+ krb5_kdc_flags *flags)
+{
+ krb5_error_code ret;
+ krb5_realm *client_realm;
+
+ ret = init_cred (context, cred, client, start_time,
+ in_tkt_service, options);
+ if (ret)
+ return ret;
+
+ client_realm = krb5_princ_realm (context, cred->client);
+
+ flags->i = 0;
+
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE)
+ flags->b.forwardable = options->forwardable;
+ else
+ flags->b.forwardable = get_config_bool (context,
+ *client_realm,
+ "forwardable");
+
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE)
+ flags->b.proxiable = options->proxiable;
+ else
+ flags->b.proxiable = get_config_bool (context,
+ *client_realm,
+ "proxiable");
+
+ if (start_time)
+ flags->b.postdated = 1;
+ if (cred->times.renew_till)
+ flags->b.renewable = 1;
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST)
+ *addrs = options->address_list;
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) {
+ *etypes = malloc((options->etype_list_length + 1)
+ * sizeof(krb5_enctype));
+ if (*etypes == NULL)
+ return ENOMEM;
+ memcpy (*etypes, options->etype_list,
+ options->etype_list_length * sizeof(krb5_enctype));
+ (*etypes)[options->etype_list_length] = ETYPE_NULL;
+ }
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST) {
+ *pre_auth_types = malloc((options->preauth_list_length + 1)
+ * sizeof(krb5_preauthtype));
+ if (*pre_auth_types == NULL)
+ return ENOMEM;
+ memcpy (*pre_auth_types, options->preauth_list,
+ options->preauth_list_length * sizeof(krb5_preauthtype));
+ (*pre_auth_types)[options->preauth_list_length] = KRB5_PADATA_NONE;
+ }
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_SALT)
+ ; /* XXX */
+ return 0;
+}
+
+static krb5_error_code
+change_password (krb5_context context,
+ krb5_principal client,
+ const char *password,
+ char *newpw,
+ size_t newpw_sz,
+ krb5_prompter_fct prompter,
+ void *data,
+ krb5_get_init_creds_opt *old_options)
+{
+ krb5_prompt prompt;
+ krb5_error_code ret;
+ krb5_creds cpw_cred;
+ char buf1[BUFSIZ], buf2[BUFSIZ];
+ krb5_data password_data;
+ int result_code;
+ krb5_data result_code_string;
+ krb5_data result_string;
+ char *p;
+ krb5_get_init_creds_opt options;
+
+ memset (&cpw_cred, 0, sizeof(cpw_cred));
+
+ krb5_get_init_creds_opt_init (&options);
+ krb5_get_init_creds_opt_set_tkt_life (&options, 60);
+ krb5_get_init_creds_opt_set_preauth_list (&options,
+ old_options->preauth_list,
+ old_options->preauth_list_length);
+
+ krb5_data_zero (&result_code_string);
+ krb5_data_zero (&result_string);
+
+ ret = krb5_get_init_creds_password (context,
+ &cpw_cred,
+ client,
+ password,
+ prompter,
+ data,
+ 0,
+ "kadmin/changepw",
+ &options);
+ if (ret)
+ goto out;
+
+ for(;;) {
+ password_data.data = buf1;
+ password_data.length = sizeof(buf1);
+
+ prompt.hidden = 1;
+ prompt.prompt = "New password: ";
+ prompt.reply = &password_data;
+
+ ret = (*prompter) (context, data, "Changing password", 1, &prompt);
+ if (ret)
+ goto out;
+
+ password_data.data = buf2;
+ password_data.length = sizeof(buf2);
+
+ prompt.hidden = 1;
+ prompt.prompt = "Repeat new password: ";
+ prompt.reply = &password_data;
+
+ ret = (*prompter) (context, data, "Changing password", 1, &prompt);
+ if (ret)
+ goto out;
+
+ if (strcmp (buf1, buf2) == 0)
+ break;
+ }
+
+ ret = krb5_change_password (context,
+ &cpw_cred,
+ buf1,
+ &result_code,
+ &result_code_string,
+ &result_string);
+ if (ret)
+ goto out;
+ asprintf (&p, "%s: %.*s\n",
+ result_code ? "Error" : "Success",
+ (int)result_string.length,
+ (char*)result_string.data);
+
+ ret = (*prompter) (context, data, p, 0, NULL);
+ free (p);
+ if (result_code == 0) {
+ strncpy (newpw, buf1, newpw_sz);
+ ret = 0;
+ } else
+ ret = ENOTTY;
+
+out:
+ memset (buf1, 0, sizeof(buf1));
+ memset (buf2, 0, sizeof(buf2));
+ krb5_data_free (&result_string);
+ krb5_data_free (&result_code_string);
+ krb5_free_creds_contents (context, &cpw_cred);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_init_creds_password(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ const char *password,
+ krb5_prompter_fct prompter,
+ void *data,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options)
+{
+ krb5_error_code ret;
+ krb5_kdc_flags flags;
+ krb5_addresses *addrs = NULL;
+ krb5_enctype *etypes = NULL;
+ krb5_preauthtype *pre_auth_types = NULL;
+ krb5_creds this_cred;
+ krb5_kdc_rep kdc_reply;
+ char buf[BUFSIZ];
+ krb5_data password_data;
+ int done;
+
+ ret = get_init_creds_common(context, creds, client, start_time,
+ in_tkt_service, options,
+ &addrs, &etypes, &this_cred, &pre_auth_types,
+ &flags);
+ if(ret)
+ goto out;
+
+ if (password == NULL) {
+ krb5_prompt prompt;
+ char *p;
+
+ krb5_unparse_name (context, this_cred.client, &p);
+ asprintf (&prompt.prompt, "%s's Password: ", p);
+ free (p);
+ password_data.data = buf;
+ password_data.length = sizeof(buf);
+ prompt.hidden = 1;
+ prompt.reply = &password_data;
+
+ ret = (*prompter) (context, data, NULL, 1, &prompt);
+ free (prompt.prompt);
+ if (ret) {
+ memset (buf, 0, sizeof(buf));
+ ret = KRB5_LIBOS_PWDINTR;
+ goto out;
+ }
+ password = password_data.data;
+ }
+
+ done = 0;
+ while(!done) {
+ memset(&kdc_reply, 0, sizeof(kdc_reply));
+ ret = krb5_get_in_cred (context,
+ flags.i,
+ addrs,
+ etypes,
+ pre_auth_types,
+ NULL,
+ krb5_password_key_proc,
+ password,
+ NULL,
+ NULL,
+ &this_cred,
+ &kdc_reply);
+ switch (ret) {
+ case 0 :
+ done = 1;
+ break;
+ case KRB5KDC_ERR_KEY_EXPIRED :
+ ret = change_password (context,
+ client,
+ password,
+ buf,
+ sizeof(buf),
+ prompter,
+ data,
+ options);
+ if (ret)
+ goto out;
+ password = buf;
+ break;
+ default:
+ goto out;
+ }
+ }
+
+ if (prompter)
+ print_expire (context,
+ krb5_princ_realm (context, this_cred.client),
+ &kdc_reply,
+ prompter,
+ data);
+out:
+ memset (buf, 0, sizeof(buf));
+ if (ret == 0)
+ krb5_free_kdc_rep (context, &kdc_reply);
+
+ free (pre_auth_types);
+ free (etypes);
+ if (ret == 0 && creds)
+ *creds = this_cred;
+ else
+ krb5_free_creds_contents (context, &this_cred);
+ return ret;
+}
+
+krb5_error_code
+krb5_keyblock_key_proc (krb5_context context,
+ krb5_keytype type,
+ krb5_data *salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key)
+{
+ return krb5_copy_keyblock (context, keyseed, key);
+}
+
+krb5_error_code
+krb5_get_init_creds_keytab(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_keytab keytab,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options)
+{
+ krb5_error_code ret;
+ krb5_kdc_flags flags;
+ krb5_addresses *addrs = NULL;
+ krb5_enctype *etypes = NULL;
+ krb5_preauthtype *pre_auth_types = NULL;
+ krb5_creds this_cred;
+ krb5_keytab_key_proc_args *a;
+
+ ret = get_init_creds_common(context, creds, client, start_time,
+ in_tkt_service, options,
+ &addrs, &etypes, &this_cred, &pre_auth_types,
+ &flags);
+ if(ret)
+ goto out;
+
+ a = malloc (sizeof(*a));
+ if (a == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ a->principal = this_cred.client;
+ a->keytab = keytab;
+
+ ret = krb5_get_in_cred (context,
+ flags.i,
+ addrs,
+ etypes,
+ pre_auth_types,
+ NULL,
+ krb5_keytab_key_proc,
+ a,
+ NULL,
+ NULL,
+ &this_cred,
+ NULL);
+ if (ret)
+ goto out;
+ free (pre_auth_types);
+ free (etypes);
+ if (creds)
+ *creds = this_cred;
+ else
+ krb5_free_creds_contents (context, &this_cred);
+ return 0;
+
+out:
+ free (pre_auth_types);
+ free (etypes);
+ krb5_free_creds_contents (context, &this_cred);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/keyblock.c b/crypto/heimdal/lib/krb5/keyblock.c
new file mode 100644
index 000000000000..89732a0d4afa
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keyblock.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+void
+krb5_free_keyblock_contents(krb5_context context,
+ krb5_keyblock *keyblock)
+{
+ if(keyblock) {
+ if (keyblock->keyvalue.data != NULL)
+ memset(keyblock->keyvalue.data, 0, keyblock->keyvalue.length);
+ krb5_data_free (&keyblock->keyvalue);
+ }
+}
+
+void
+krb5_free_keyblock(krb5_context context,
+ krb5_keyblock *keyblock)
+{
+ if(keyblock){
+ krb5_free_keyblock_contents(context, keyblock);
+ free(keyblock);
+ }
+}
+
+krb5_error_code
+krb5_copy_keyblock_contents (krb5_context context,
+ const krb5_keyblock *inblock,
+ krb5_keyblock *to)
+{
+ return copy_EncryptionKey(inblock, to);
+}
+
+krb5_error_code
+krb5_copy_keyblock (krb5_context context,
+ const krb5_keyblock *inblock,
+ krb5_keyblock **to)
+{
+ krb5_keyblock *k;
+
+ k = malloc (sizeof(*k));
+ if (k == NULL)
+ return ENOMEM;
+ *to = k;
+ return krb5_copy_keyblock_contents (context, inblock, k);
+}
diff --git a/crypto/heimdal/lib/krb5/keytab.c b/crypto/heimdal/lib/krb5/keytab.c
new file mode 100644
index 000000000000..af853a41f9f2
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keytab.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: keytab.c,v 1.45 2000/01/02 00:31:20 assar Exp $");
+
+/*
+ * Register a new keytab in `ops'
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_register(krb5_context context,
+ const krb5_kt_ops *ops)
+{
+ struct krb5_keytab_data *tmp;
+
+ tmp = realloc(context->kt_types,
+ (context->num_kt_types + 1) * sizeof(*context->kt_types));
+ if(tmp == NULL)
+ return ENOMEM;
+ memcpy(&tmp[context->num_kt_types], ops,
+ sizeof(tmp[context->num_kt_types]));
+ context->kt_types = tmp;
+ context->num_kt_types++;
+ return 0;
+}
+
+/*
+ * Resolve the keytab name (of the form `type:residual') in `name'
+ * into a keytab in `id'.
+ * Return 0 or an error
+ */
+
+krb5_error_code
+krb5_kt_resolve(krb5_context context,
+ const char *name,
+ krb5_keytab *id)
+{
+ krb5_keytab k;
+ int i;
+ const char *type, *residual;
+ size_t type_len;
+ krb5_error_code ret;
+
+ residual = strchr(name, ':');
+ if(residual == NULL) {
+ type = "FILE";
+ type_len = strlen(type);
+ residual = name;
+ } else {
+ type = name;
+ type_len = residual - name;
+ residual++;
+ }
+
+ for(i = 0; i < context->num_kt_types; i++) {
+ if(strncmp(type, context->kt_types[i].prefix, type_len) == 0)
+ break;
+ }
+ if(i == context->num_kt_types)
+ return KRB5_KT_UNKNOWN_TYPE;
+
+ k = malloc (sizeof(*k));
+ if (k == NULL)
+ return ENOMEM;
+ memcpy(k, &context->kt_types[i], sizeof(*k));
+ k->data = NULL;
+ ret = (*k->resolve)(context, residual, k);
+ if(ret) {
+ free(k);
+ k = NULL;
+ }
+ *id = k;
+ return ret;
+}
+
+/*
+ * copy the name of the default keytab into `name'.
+ * Return 0 or KRB5_CONFIG_NOTENUFSPACE if `namesize' is too short.
+ */
+
+krb5_error_code
+krb5_kt_default_name(krb5_context context, char *name, size_t namesize)
+{
+ strncpy(name, context->default_keytab, namesize);
+ if(strlen(context->default_keytab) >= namesize)
+ return KRB5_CONFIG_NOTENUFSPACE;
+ return 0;
+}
+
+/*
+ * Set `id' to the default keytab.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_default(krb5_context context, krb5_keytab *id)
+{
+ return krb5_kt_resolve (context, context->default_keytab, id);
+}
+
+/*
+ * Read the key identified by `(principal, vno, enctype)' from the
+ * keytab in `keyprocarg' (the default if == NULL) into `*key'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_read_service_key(krb5_context context,
+ krb5_pointer keyprocarg,
+ krb5_principal principal,
+ krb5_kvno vno,
+ krb5_enctype enctype,
+ krb5_keyblock **key)
+{
+ krb5_keytab keytab;
+ krb5_keytab_entry entry;
+ krb5_error_code ret;
+
+ if (keyprocarg)
+ ret = krb5_kt_resolve (context, keyprocarg, &keytab);
+ else
+ ret = krb5_kt_default (context, &keytab);
+
+ if (ret)
+ return ret;
+
+ ret = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry);
+ krb5_kt_close (context, keytab);
+ if (ret)
+ return ret;
+ ret = krb5_copy_keyblock (context, &entry.keyblock, key);
+ krb5_kt_free_entry(context, &entry);
+ return ret;
+}
+
+/*
+ * Retrieve the name of the keytab `keytab' into `name', `namesize'
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_get_name(krb5_context context,
+ krb5_keytab keytab,
+ char *name,
+ size_t namesize)
+{
+ return (*keytab->get_name)(context, keytab, name, namesize);
+}
+
+/*
+ * Finish using the keytab in `id'. All resources will be released.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_close(krb5_context context,
+ krb5_keytab id)
+{
+ krb5_error_code ret;
+
+ ret = (*id->close)(context, id);
+ if(ret == 0)
+ free(id);
+ return ret;
+}
+
+/*
+ * Compare `entry' against `principal, vno, enctype'.
+ * Any of `principal, vno, enctype' might be 0 which acts as a wildcard.
+ * Return TRUE if they compare the same, FALSE otherwise.
+ */
+
+krb5_boolean
+krb5_kt_compare(krb5_context context,
+ krb5_keytab_entry *entry,
+ krb5_const_principal principal,
+ krb5_kvno vno,
+ krb5_enctype enctype)
+{
+ if(principal != NULL &&
+ !krb5_principal_compare(context, entry->principal, principal))
+ return FALSE;
+ if(vno && vno != entry->vno)
+ return FALSE;
+ if(enctype && enctype != entry->keyblock.keytype)
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * Retrieve the keytab entry for `principal, kvno, enctype' into `entry'
+ * from the keytab `id'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_get_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_const_principal principal,
+ krb5_kvno kvno,
+ krb5_enctype enctype,
+ krb5_keytab_entry *entry)
+{
+ krb5_keytab_entry tmp;
+ krb5_error_code ret;
+ krb5_kt_cursor cursor;
+
+ if(id->get)
+ return (*id->get)(context, id, principal, kvno, enctype, entry);
+
+ ret = krb5_kt_start_seq_get (context, id, &cursor);
+ if (ret)
+ return KRB5_KT_NOTFOUND; /* XXX i.e. file not found */
+
+ entry->vno = 0;
+ while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) {
+ if (krb5_kt_compare(context, &tmp, principal, 0, enctype)) {
+ if (kvno == tmp.vno) {
+ krb5_kt_copy_entry_contents (context, &tmp, entry);
+ krb5_kt_free_entry (context, &tmp);
+ krb5_kt_end_seq_get(context, id, &cursor);
+ return 0;
+ } else if (kvno == 0 && tmp.vno > entry->vno) {
+ if (entry->vno)
+ krb5_kt_free_entry (context, entry);
+ krb5_kt_copy_entry_contents (context, &tmp, entry);
+ }
+ }
+ krb5_kt_free_entry(context, &tmp);
+ }
+ krb5_kt_end_seq_get (context, id, &cursor);
+ if (entry->vno)
+ return 0;
+ else
+ return KRB5_KT_NOTFOUND;
+}
+
+/*
+ * Copy the contents of `in' into `out'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_copy_entry_contents(krb5_context context,
+ const krb5_keytab_entry *in,
+ krb5_keytab_entry *out)
+{
+ krb5_error_code ret;
+
+ memset(out, 0, sizeof(*out));
+ out->vno = in->vno;
+
+ ret = krb5_copy_principal (context, in->principal, &out->principal);
+ if (ret)
+ goto fail;
+ ret = krb5_copy_keyblock_contents (context,
+ &in->keyblock,
+ &out->keyblock);
+ if (ret)
+ goto fail;
+ out->timestamp = in->timestamp;
+ return 0;
+fail:
+ krb5_kt_free_entry (context, out);
+ return ret;
+}
+
+/*
+ * Free the contents of `entry'.
+ */
+
+krb5_error_code
+krb5_kt_free_entry(krb5_context context,
+ krb5_keytab_entry *entry)
+{
+ krb5_free_principal (context, entry->principal);
+ krb5_free_keyblock_contents (context, &entry->keyblock);
+ return 0;
+}
+
+#if 0
+static int
+xxxlock(int fd, int write)
+{
+ if(flock(fd, (write ? LOCK_EX : LOCK_SH) | LOCK_NB) < 0) {
+ sleep(1);
+ if(flock(fd, (write ? LOCK_EX : LOCK_SH) | LOCK_NB) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static void
+xxxunlock(int fd)
+{
+ flock(fd, LOCK_UN);
+}
+#endif
+
+/*
+ * Set `cursor' to point at the beginning of `id'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_start_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ if(id->start_seq_get == NULL)
+ return HEIM_ERR_OPNOTSUPP;
+ return (*id->start_seq_get)(context, id, cursor);
+}
+
+/*
+ * Get the next entry from `id' pointed to by `cursor' and advance the
+ * `cursor'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_next_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor)
+{
+ if(id->next_entry == NULL)
+ return HEIM_ERR_OPNOTSUPP;
+ return (*id->next_entry)(context, id, entry, cursor);
+}
+
+/*
+ * Release all resources associated with `cursor'.
+ */
+
+krb5_error_code
+krb5_kt_end_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ if(id->end_seq_get == NULL)
+ return HEIM_ERR_OPNOTSUPP;
+ return (*id->end_seq_get)(context, id, cursor);
+}
+
+/*
+ * Add the entry in `entry' to the keytab `id'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_add_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ if(id->add == NULL)
+ return KRB5_KT_NOWRITE;
+ return (*id->add)(context, id,entry);
+}
+
+/*
+ * Remove the entry `entry' from the keytab `id'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_remove_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ if(id->remove == NULL)
+ return KRB5_KT_NOWRITE;
+ return (*id->remove)(context, id, entry);
+}
diff --git a/crypto/heimdal/lib/krb5/keytab_file.c b/crypto/heimdal/lib/krb5/keytab_file.c
new file mode 100644
index 000000000000..c6c35e5b4f84
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keytab_file.c
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: keytab_file.c,v 1.6 2000/01/02 00:20:22 assar Exp $");
+
+#define KRB5_KT_VNO_1 1
+#define KRB5_KT_VNO_2 2
+#define KRB5_KT_VNO KRB5_KT_VNO_2
+
+/* file operations -------------------------------------------- */
+
+struct fkt_data {
+ char *filename;
+};
+
+static krb5_error_code
+krb5_kt_ret_data(krb5_storage *sp,
+ krb5_data *data)
+{
+ int ret;
+ int16_t size;
+ ret = krb5_ret_int16(sp, &size);
+ if(ret)
+ return ret;
+ data->length = size;
+ data->data = malloc(size);
+ if (data->data == NULL)
+ return ENOMEM;
+ ret = sp->fetch(sp, data->data, size);
+ if(ret != size)
+ return (ret < 0)? errno : KRB5_KT_END;
+ return 0;
+}
+
+static krb5_error_code
+krb5_kt_ret_string(krb5_storage *sp,
+ general_string *data)
+{
+ int ret;
+ int16_t size;
+ ret = krb5_ret_int16(sp, &size);
+ if(ret)
+ return ret;
+ *data = malloc(size + 1);
+ if (*data == NULL)
+ return ENOMEM;
+ ret = sp->fetch(sp, *data, size);
+ (*data)[size] = '\0';
+ if(ret != size)
+ return (ret < 0)? errno : KRB5_KT_END;
+ return 0;
+}
+
+static krb5_error_code
+krb5_kt_store_data(krb5_storage *sp,
+ krb5_data data)
+{
+ int ret;
+ ret = krb5_store_int16(sp, data.length);
+ if(ret < 0)
+ return ret;
+ ret = sp->store(sp, data.data, data.length);
+ if(ret != data.length){
+ if(ret < 0)
+ return errno;
+ return KRB5_KT_END;
+ }
+ return 0;
+}
+
+static krb5_error_code
+krb5_kt_store_string(krb5_storage *sp,
+ general_string data)
+{
+ int ret;
+ size_t len = strlen(data);
+ ret = krb5_store_int16(sp, len);
+ if(ret < 0)
+ return ret;
+ ret = sp->store(sp, data, len);
+ if(ret != len){
+ if(ret < 0)
+ return errno;
+ return KRB5_KT_END;
+ }
+ return 0;
+}
+
+static krb5_error_code
+krb5_kt_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
+{
+ int ret;
+ int16_t tmp;
+
+ ret = krb5_ret_int16(sp, &tmp); /* keytype + etype */
+ if(ret) return ret;
+ p->keytype = tmp;
+ ret = krb5_kt_ret_data(sp, &p->keyvalue);
+ return ret;
+}
+
+static krb5_error_code
+krb5_kt_store_keyblock(krb5_storage *sp,
+ krb5_keyblock *p)
+{
+ int ret;
+
+ ret = krb5_store_int16(sp, p->keytype); /* keytype + etype */
+ if(ret) return ret;
+ ret = krb5_kt_store_data(sp, p->keyvalue);
+ return ret;
+}
+
+
+static krb5_error_code
+krb5_kt_ret_principal(krb5_storage *sp,
+ krb5_principal *princ)
+{
+ int i;
+ int ret;
+ krb5_principal p;
+ int16_t tmp;
+
+ ALLOC(p, 1);
+ if(p == NULL)
+ return ENOMEM;
+
+ ret = krb5_ret_int16(sp, &tmp);
+ if(ret)
+ return ret;
+ if (sp->flags & KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)
+ tmp--;
+ p->name.name_string.len = tmp;
+ ret = krb5_kt_ret_string(sp, &p->realm);
+ if(ret) return ret;
+ p->name.name_string.val = calloc(p->name.name_string.len,
+ sizeof(*p->name.name_string.val));
+ if(p->name.name_string.val == NULL)
+ return ENOMEM;
+ for(i = 0; i < p->name.name_string.len; i++){
+ ret = krb5_kt_ret_string(sp, p->name.name_string.val + i);
+ if(ret) return ret;
+ }
+ if (krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
+ p->name.name_type = KRB5_NT_UNKNOWN;
+ else {
+ int32_t tmp32;
+ ret = krb5_ret_int32(sp, &tmp32);
+ p->name.name_type = tmp32;
+ if (ret)
+ return ret;
+ }
+ *princ = p;
+ return 0;
+}
+
+static krb5_error_code
+krb5_kt_store_principal(krb5_storage *sp,
+ krb5_principal p)
+{
+ int i;
+ int ret;
+
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
+ ret = krb5_store_int16(sp, p->name.name_string.len + 1);
+ else
+ ret = krb5_store_int16(sp, p->name.name_string.len);
+ if(ret) return ret;
+ ret = krb5_kt_store_string(sp, p->realm);
+ if(ret) return ret;
+ for(i = 0; i < p->name.name_string.len; i++){
+ ret = krb5_kt_store_string(sp, p->name.name_string.val[i]);
+ if(ret) return ret;
+ }
+ if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
+ ret = krb5_store_int32(sp, p->name.name_type);
+ if(ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static krb5_error_code
+fkt_resolve(krb5_context context, const char *name, krb5_keytab id)
+{
+ struct fkt_data *d;
+ d = malloc(sizeof(*d));
+ if(d == NULL)
+ return ENOMEM;
+ d->filename = strdup(name);
+ if(d->filename == NULL) {
+ free(d);
+ return ENOMEM;
+ }
+ id->data = d;
+ return 0;
+}
+
+static krb5_error_code
+fkt_close(krb5_context context, krb5_keytab id)
+{
+ struct fkt_data *d = id->data;
+ free(d->filename);
+ free(d);
+ return 0;
+}
+
+static krb5_error_code
+fkt_get_name(krb5_context context,
+ krb5_keytab id,
+ char *name,
+ size_t namesize)
+{
+ /* This function is XXX */
+ struct fkt_data *d = id->data;
+ strlcpy(name, d->filename, namesize);
+ return 0;
+}
+
+static void
+storage_set_flags(krb5_context context, krb5_storage *sp, int vno)
+{
+ int flags = 0;
+ switch(vno) {
+ case KRB5_KT_VNO_1:
+ flags |= KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS;
+ flags |= KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE;
+ flags |= KRB5_STORAGE_HOST_BYTEORDER;
+ break;
+ case KRB5_KT_VNO_2:
+ break;
+ default:
+ krb5_abortx(context,
+ "storage_set_flags called with bad vno (%x)", vno);
+ }
+ krb5_storage_set_flags(sp, flags);
+}
+
+static krb5_error_code
+fkt_start_seq_get_int(krb5_context context,
+ krb5_keytab id,
+ int flags,
+ krb5_kt_cursor *c)
+{
+ int8_t pvno, tag;
+ krb5_error_code ret;
+ struct fkt_data *d = id->data;
+
+ c->fd = open (d->filename, flags);
+ if (c->fd < 0)
+ return errno;
+ c->sp = krb5_storage_from_fd(c->fd);
+ ret = krb5_ret_int8(c->sp, &pvno);
+ if(ret) {
+ krb5_storage_free(c->sp);
+ close(c->fd);
+ return ret;
+ }
+ if(pvno != 5) {
+ krb5_storage_free(c->sp);
+ close(c->fd);
+ return KRB5_KEYTAB_BADVNO;
+ }
+ ret = krb5_ret_int8(c->sp, &tag);
+ if (ret) {
+ krb5_storage_free(c->sp);
+ close(c->fd);
+ return ret;
+ }
+ id->version = tag;
+ storage_set_flags(context, c->sp, id->version);
+ return 0;
+}
+
+static krb5_error_code
+fkt_start_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *c)
+{
+ return fkt_start_seq_get_int(context, id, O_RDONLY | O_BINARY, c);
+}
+
+static krb5_error_code
+fkt_next_entry_int(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor,
+ off_t *start,
+ off_t *end)
+{
+ int32_t len;
+ int ret;
+ int8_t tmp8;
+ int32_t tmp32;
+ off_t pos;
+
+ pos = cursor->sp->seek(cursor->sp, 0, SEEK_CUR);
+loop:
+ ret = krb5_ret_int32(cursor->sp, &len);
+ if (ret)
+ return ret;
+ if(len < 0) {
+ pos = cursor->sp->seek(cursor->sp, -len, SEEK_CUR);
+ goto loop;
+ }
+ ret = krb5_kt_ret_principal (cursor->sp, &entry->principal);
+ if (ret)
+ goto out;
+ ret = krb5_ret_int32(cursor->sp, &tmp32);
+ entry->timestamp = tmp32;
+ if (ret)
+ goto out;
+ ret = krb5_ret_int8(cursor->sp, &tmp8);
+ if (ret)
+ goto out;
+ entry->vno = tmp8;
+ ret = krb5_kt_ret_keyblock (cursor->sp, &entry->keyblock);
+ if (ret)
+ goto out;
+ if(start) *start = pos;
+ if(end) *end = *start + 4 + len;
+ out:
+ cursor->sp->seek(cursor->sp, pos + 4 + len, SEEK_SET);
+ return ret;
+}
+
+static krb5_error_code
+fkt_next_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor)
+{
+ return fkt_next_entry_int(context, id, entry, cursor, NULL, NULL);
+}
+
+static krb5_error_code
+fkt_end_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ krb5_storage_free(cursor->sp);
+ close(cursor->fd);
+ return 0;
+}
+
+static krb5_error_code
+fkt_add_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ int ret;
+ int fd;
+ krb5_storage *sp;
+ struct fkt_data *d = id->data;
+ krb5_data keytab;
+ int32_t len;
+
+ fd = open (d->filename, O_RDWR | O_BINARY);
+ if (fd < 0) {
+ fd = open (d->filename, O_RDWR | O_CREAT | O_BINARY, 0600);
+ if (fd < 0)
+ return errno;
+ sp = krb5_storage_from_fd(fd);
+ ret = krb5_store_int8(sp, 5);
+ if(ret) {
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+ }
+ if(id->version == 0)
+ id->version = KRB5_KT_VNO;
+ ret = krb5_store_int8 (sp, id->version);
+ if (ret) {
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+ }
+ storage_set_flags(context, sp, id->version);
+ } else {
+ int8_t pvno, tag;
+ sp = krb5_storage_from_fd(fd);
+ ret = krb5_ret_int8(sp, &pvno);
+ if(ret) {
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+ }
+ if(pvno != 5) {
+ krb5_storage_free(sp);
+ close(fd);
+ return KRB5_KEYTAB_BADVNO;
+ }
+ ret = krb5_ret_int8 (sp, &tag);
+ if (ret) {
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+ }
+ id->version = tag;
+ storage_set_flags(context, sp, id->version);
+ }
+
+ {
+ krb5_storage *emem;
+ emem = krb5_storage_emem();
+ if(emem == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret = krb5_kt_store_principal(emem, entry->principal);
+ if(ret) {
+ krb5_storage_free(emem);
+ goto out;
+ }
+ ret = krb5_store_int32 (emem, entry->timestamp);
+ if(ret) {
+ krb5_storage_free(emem);
+ goto out;
+ }
+ ret = krb5_store_int8 (emem, entry->vno);
+ if(ret) {
+ krb5_storage_free(emem);
+ goto out;
+ }
+ ret = krb5_kt_store_keyblock (emem, &entry->keyblock);
+ if(ret) {
+ krb5_storage_free(emem);
+ goto out;
+ }
+ ret = krb5_storage_to_data(emem, &keytab);
+ krb5_storage_free(emem);
+ if(ret)
+ goto out;
+ }
+
+ while(1) {
+ ret = krb5_ret_int32(sp, &len);
+ if(ret == KRB5_CC_END) {
+ len = keytab.length;
+ break;
+ }
+ if(len < 0) {
+ len = -len;
+ if(len >= keytab.length) {
+ sp->seek(sp, -4, SEEK_CUR);
+ break;
+ }
+ }
+ sp->seek(sp, len, SEEK_CUR);
+ }
+ ret = krb5_store_int32(sp, len);
+ if(sp->store(sp, keytab.data, keytab.length) < 0)
+ ret = errno;
+ memset(keytab.data, 0, keytab.length);
+ krb5_data_free(&keytab);
+ out:
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+}
+
+static krb5_error_code
+fkt_remove_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ krb5_keytab_entry e;
+ krb5_kt_cursor cursor;
+ off_t pos_start, pos_end;
+ int found = 0;
+
+ fkt_start_seq_get_int(context, id, O_RDWR | O_BINARY, &cursor);
+ while(fkt_next_entry_int(context, id, &e, &cursor,
+ &pos_start, &pos_end) == 0) {
+ if(krb5_kt_compare(context, &e, entry->principal,
+ entry->vno, entry->keyblock.keytype)) {
+ int32_t len;
+ unsigned char buf[128];
+ found = 1;
+ cursor.sp->seek(cursor.sp, pos_start, SEEK_SET);
+ len = pos_end - pos_start - 4;
+ krb5_store_int32(cursor.sp, -len);
+ memset(buf, 0, sizeof(buf));
+ while(len > 0) {
+ cursor.sp->store(cursor.sp, buf, min(len, sizeof(buf)));
+ len -= min(len, sizeof(buf));
+ }
+ }
+ }
+ krb5_kt_end_seq_get(context, id, &cursor);
+ if (!found)
+ return KRB5_KT_NOTFOUND;
+ return 0;
+}
+
+const krb5_kt_ops krb5_fkt_ops = {
+ "FILE",
+ fkt_resolve,
+ fkt_get_name,
+ fkt_close,
+ NULL, /* get */
+ fkt_start_seq_get,
+ fkt_next_entry,
+ fkt_end_seq_get,
+ fkt_add_entry,
+ fkt_remove_entry
+};
diff --git a/crypto/heimdal/lib/krb5/keytab_keyfile.c b/crypto/heimdal/lib/krb5/keytab_keyfile.c
new file mode 100644
index 000000000000..fa14e624f00e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keytab_keyfile.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: keytab_keyfile.c,v 1.7 2000/01/02 04:00:22 assar Exp $");
+
+/* afs keyfile operations --------------------------------------- */
+
+/*
+ * Minimum tools to handle the AFS KeyFile.
+ *
+ * Format of the KeyFile is:
+ * <int32_t numkeys> {[<int32_t kvno> <char[8] deskey>] * numkeys}
+ *
+ * It just adds to the end of the keyfile, deleting isn't implemented.
+ * Use your favorite text/hex editor to delete keys.
+ *
+ */
+
+#define AFS_SERVERTHISCELL "/usr/afs/etc/ThisCell"
+#define AFS_SERVERMAGICKRBCONF "/usr/afs/etc/krb.conf"
+
+struct akf_data {
+ int num_entries;
+ char *filename;
+ char *cell;
+ char *realm;
+};
+
+/*
+ * set `d->cell' and `d->realm'
+ */
+
+static int
+get_cell_and_realm (struct akf_data *d)
+{
+ FILE *f;
+ char buf[BUFSIZ], *cp;
+
+ f = fopen (AFS_SERVERTHISCELL, "r");
+ if (f == NULL)
+ return errno;
+ if (fgets (buf, sizeof(buf), f) == NULL) {
+ fclose (f);
+ return EINVAL;
+ }
+ if (buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ fclose(f);
+
+ d->cell = strdup (buf);
+ if (d->cell == NULL)
+ return errno;
+
+ f = fopen (AFS_SERVERMAGICKRBCONF, "r");
+ if (f != NULL) {
+ if (fgets (buf, sizeof(buf), f) == NULL) {
+ fclose (f);
+ return EINVAL;
+ }
+ if (buf[strlen(buf)-1] == '\n')
+ buf[strlen(buf)-1] = '\0';
+ fclose(f);
+ }
+ /* uppercase */
+ for (cp = buf; *cp != '\0'; cp++)
+ *cp = toupper(*cp);
+
+ d->realm = strdup (buf);
+ if (d->realm == NULL) {
+ free (d->cell);
+ return errno;
+ }
+ return 0;
+}
+
+/*
+ * init and get filename
+ */
+
+static krb5_error_code
+akf_resolve(krb5_context context, const char *name, krb5_keytab id)
+{
+ int ret;
+ struct akf_data *d = malloc(sizeof (struct akf_data));
+
+ if (d == NULL)
+ return errno;
+
+ d->num_entries = 0;
+ ret = get_cell_and_realm (d);
+ if (ret) {
+ free (d);
+ return ret;
+ }
+ d->filename = strdup (name);
+ if (d->filename == NULL) {
+ free (d->cell);
+ free (d->realm);
+ free (d);
+ return ENOMEM;
+ }
+ id->data = d;
+
+ return 0;
+}
+
+/*
+ * cleanup
+ */
+
+static krb5_error_code
+akf_close(krb5_context context, krb5_keytab id)
+{
+ struct akf_data *d = id->data;
+
+ free (d->filename);
+ free (d->cell);
+ free (d);
+ return 0;
+}
+
+/*
+ * Return filename
+ */
+
+static krb5_error_code
+akf_get_name(krb5_context context,
+ krb5_keytab id,
+ char *name,
+ size_t name_sz)
+{
+ struct akf_data *d = id->data;
+
+ strlcpy (name, d->filename, name_sz);
+ return 0;
+}
+
+/*
+ * Init
+ */
+
+static krb5_error_code
+akf_start_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *c)
+{
+ int32_t ret;
+ struct akf_data *d = id->data;
+
+ c->fd = open (d->filename, O_RDONLY|O_BINARY, 0600);
+ if (c->fd < 0)
+ return errno;
+
+ c->sp = krb5_storage_from_fd(c->fd);
+ ret = krb5_ret_int32(c->sp, &d->num_entries);
+ if(ret) {
+ krb5_storage_free(c->sp);
+ close(c->fd);
+ return ret;
+ }
+
+ return 0;
+}
+
+static krb5_error_code
+akf_next_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor)
+{
+ struct akf_data *d = id->data;
+ int32_t kvno;
+ off_t pos;
+ int ret;
+
+ pos = cursor->sp->seek(cursor->sp, 0, SEEK_CUR);
+
+ if ((pos - 4) / (4 + 8) >= d->num_entries)
+ return KRB5_KT_END;
+
+ ret = krb5_make_principal (context, &entry->principal,
+ d->realm, "afs", d->cell, NULL);
+ if (ret)
+ goto out;
+
+ ret = krb5_ret_int32(cursor->sp, &kvno);
+ if (ret) {
+ krb5_free_principal (context, entry->principal);
+ goto out;
+ }
+
+ entry->vno = (int8_t) kvno;
+
+ entry->keyblock.keytype = ETYPE_DES_CBC_MD5;
+ entry->keyblock.keyvalue.length = 8;
+ entry->keyblock.keyvalue.data = malloc (8);
+ if (entry->keyblock.keyvalue.data == NULL) {
+ krb5_free_principal (context, entry->principal);
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = cursor->sp->fetch(cursor->sp, entry->keyblock.keyvalue.data, 8);
+ if(ret != 8)
+ ret = (ret < 0) ? errno : KRB5_KT_END;
+
+ entry->timestamp = time(NULL);
+
+ out:
+ cursor->sp->seek(cursor->sp, pos + 4 + 8, SEEK_SET);
+ return ret;
+}
+
+static krb5_error_code
+akf_end_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ krb5_storage_free(cursor->sp);
+ close(cursor->fd);
+ return 0;
+}
+
+static krb5_error_code
+akf_add_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ struct akf_data *d = id->data;
+ int fd, created = 0;
+ int32_t kvno;
+
+ fd = open (d->filename, O_RDWR | O_BINARY);
+ if (fd < 0) {
+ fd = open (d->filename,
+ O_RDWR | O_BINARY | O_CREAT, 0600);
+ if (fd < 0)
+ return errno;
+ created = 1;
+ }
+
+ if (entry->keyblock.keyvalue.length == 8
+ && entry->keyblock.keytype == ETYPE_DES_CBC_MD5) {
+
+ int32_t len = 0;
+
+ if (!created) {
+ if (lseek (fd, 0, SEEK_SET))
+ return errno;
+
+ if (read (fd, &len, sizeof(len)) != sizeof(len))
+ return errno;
+ }
+ len += 1;
+
+ if (lseek (fd, 0, SEEK_SET))
+ return errno;
+
+ if (write (fd, &len, sizeof(len)) != sizeof(len))
+ return errno;
+
+ if (lseek (fd, 4 + (len-1) * (8+4), SEEK_SET))
+ return errno;
+
+ kvno = entry->vno;
+ write(fd, &kvno, sizeof(kvno));
+ write(fd, entry->keyblock.keyvalue.data, 8);
+ }
+ close (fd);
+ return 0;
+}
+
+const krb5_kt_ops krb5_akf_ops = {
+ "AFSKEYFILE",
+ akf_resolve,
+ akf_get_name,
+ akf_close,
+ NULL, /* get */
+ akf_start_seq_get,
+ akf_next_entry,
+ akf_end_seq_get,
+ akf_add_entry,
+ NULL /* remove */
+};
diff --git a/crypto/heimdal/lib/krb5/keytab_krb4.c b/crypto/heimdal/lib/krb5/keytab_krb4.c
new file mode 100644
index 000000000000..b1f425c575ed
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keytab_krb4.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+#include <krb.h>
+
+RCSID("$Id: keytab_krb4.c,v 1.5 2000/01/06 08:04:58 assar Exp $");
+
+struct krb4_kt_data {
+ char *filename;
+};
+
+static krb5_error_code
+krb4_kt_resolve(krb5_context context, const char *name, krb5_keytab id)
+{
+ struct krb4_kt_data *d;
+
+ d = malloc (sizeof(*d));
+ if (d == NULL)
+ return ENOMEM;
+ d->filename = strdup (name);
+ if (d->filename == NULL) {
+ free(d);
+ return ENOMEM;
+ }
+ id->data = d;
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_get_name (krb5_context context,
+ krb5_keytab id,
+ char *name,
+ size_t name_sz)
+{
+ struct krb4_kt_data *d = id->data;
+
+ strlcpy (name, d->filename, name_sz);
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_close (krb5_context context,
+ krb5_keytab id)
+{
+ struct krb4_kt_data *d = id->data;
+
+ free (d->filename);
+ free (d);
+ return 0;
+}
+
+struct krb4_cursor_extra_data {
+ krb5_keytab_entry entry;
+ int num;
+};
+
+static krb5_error_code
+krb4_kt_start_seq_get_int (krb5_context context,
+ krb5_keytab id,
+ int flags,
+ krb5_kt_cursor *c)
+{
+ struct krb4_kt_data *d = id->data;
+ struct krb4_cursor_extra_data *ed;
+
+ ed = malloc (sizeof(*ed));
+ if (ed == NULL)
+ return ENOMEM;
+ ed->entry.principal = NULL;
+ ed->num = -1;
+ c->data = ed;
+ c->fd = open (d->filename, flags);
+ if (c->fd < 0) {
+ free (ed);
+ return errno;
+ }
+ c->sp = krb5_storage_from_fd(c->fd);
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_start_seq_get (krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *c)
+{
+ return krb4_kt_start_seq_get_int (context, id, O_BINARY | O_RDONLY, c);
+}
+
+static krb5_error_code
+read_v4_entry (krb5_context context,
+ struct krb4_kt_data *d,
+ krb5_kt_cursor *c,
+ struct krb4_cursor_extra_data *ed)
+{
+ krb5_error_code ret;
+ char *service, *instance, *realm;
+ int8_t kvno;
+ des_cblock key;
+
+ ret = krb5_ret_stringz(c->sp, &service);
+ if (ret)
+ return ret;
+ ret = krb5_ret_stringz(c->sp, &instance);
+ if (ret) {
+ free (service);
+ return ret;
+ }
+ ret = krb5_ret_stringz(c->sp, &realm);
+ if (ret) {
+ free (service);
+ free (instance);
+ return ret;
+ }
+ ret = krb5_425_conv_principal (context, service, instance, realm,
+ &ed->entry.principal);
+ free (service);
+ free (instance);
+ free (realm);
+ if (ret)
+ return ret;
+ ret = krb5_ret_int8(c->sp, &kvno);
+ if (ret) {
+ krb5_free_principal (context, ed->entry.principal);
+ return ret;
+ }
+ ret = c->sp->fetch(c->sp, key, 8);
+ if (ret < 0) {
+ krb5_free_principal(context, ed->entry.principal);
+ return ret;
+ }
+ if (ret < 8) {
+ krb5_free_principal(context, ed->entry.principal);
+ return EINVAL;
+ }
+ ed->entry.vno = kvno;
+ ret = krb5_data_copy (&ed->entry.keyblock.keyvalue,
+ key, 8);
+ if (ret)
+ return ret;
+ ed->entry.timestamp = time(NULL);
+ ed->num = 0;
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_next_entry (krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *c)
+{
+ krb5_error_code ret;
+ struct krb4_kt_data *d = id->data;
+ struct krb4_cursor_extra_data *ed = c->data;
+ const krb5_enctype keytypes[] = {ETYPE_DES_CBC_MD5,
+ ETYPE_DES_CBC_MD4,
+ ETYPE_DES_CBC_CRC};
+
+ if (ed->num == -1) {
+ ret = read_v4_entry (context, d, c, ed);
+ if (ret)
+ return ret;
+ }
+ ret = krb5_kt_copy_entry_contents (context,
+ &ed->entry,
+ entry);
+ if (ret)
+ return ret;
+ entry->keyblock.keytype = keytypes[ed->num];
+ if (++ed->num == 3) {
+ krb5_kt_free_entry (context, &ed->entry);
+ ed->num = -1;
+ }
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_end_seq_get (krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *c)
+{
+ struct krb4_cursor_extra_data *ed = c->data;
+
+ krb5_storage_free (c->sp);
+ if (ed->num != -1)
+ krb5_kt_free_entry (context, &ed->entry);
+ free (c->data);
+ close (c->fd);
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_add_entry (krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ struct krb4_kt_data *d = id->data;
+ krb5_error_code ret;
+ int fd;
+ char service[ANAME_SZ];
+ char instance[INST_SZ];
+ char realm[REALM_SZ];
+ int8_t kvno;
+
+ fd = open (d->filename, O_WRONLY | O_APPEND | O_BINARY);
+ if (fd < 0) {
+ fd = open (d->filename,
+ O_WRONLY | O_APPEND | O_BINARY | O_CREAT, 0600);
+ if (fd < 0)
+ return errno;
+ }
+ ret = krb5_524_conv_principal (context, entry->principal,
+ service, instance, realm);
+ if (ret) {
+ close (fd);
+ return ret;
+ }
+ if (entry->keyblock.keyvalue.length == 8
+ && entry->keyblock.keytype == ETYPE_DES_CBC_MD5) {
+ write(fd, service, strlen(service)+1);
+ write(fd, instance, strlen(instance)+1);
+ write(fd, realm, strlen(realm)+1);
+ kvno = entry->vno;
+ write(fd, &kvno, sizeof(kvno));
+ write(fd, entry->keyblock.keyvalue.data, 8);
+ }
+ close (fd);
+ return 0;
+}
+
+krb5_kt_ops krb4_fkt_ops = {
+ "krb4",
+ krb4_kt_resolve,
+ krb4_kt_get_name,
+ krb4_kt_close,
+ NULL, /* get */
+ krb4_kt_start_seq_get,
+ krb4_kt_next_entry,
+ krb4_kt_end_seq_get,
+ krb4_kt_add_entry, /* add_entry */
+ NULL /* remove_entry */
+};
diff --git a/crypto/heimdal/lib/krb5/keytab_memory.c b/crypto/heimdal/lib/krb5/keytab_memory.c
new file mode 100644
index 000000000000..924b4cd0e622
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keytab_memory.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: keytab_memory.c,v 1.3 1999/12/02 17:05:10 joda Exp $");
+
+/* memory operations -------------------------------------------- */
+
+struct mkt_data {
+ krb5_keytab_entry *entries;
+ int num_entries;
+};
+
+static krb5_error_code
+mkt_resolve(krb5_context context, const char *name, krb5_keytab id)
+{
+ struct mkt_data *d;
+ d = malloc(sizeof(*d));
+ if(d == NULL)
+ return ENOMEM;
+ d->entries = NULL;
+ d->num_entries = 0;
+ id->data = d;
+ return 0;
+}
+
+static krb5_error_code
+mkt_close(krb5_context context, krb5_keytab id)
+{
+ struct mkt_data *d = id->data;
+ int i;
+ for(i = 0; i < d->num_entries; i++)
+ krb5_kt_free_entry(context, &d->entries[i]);
+ free(d->entries);
+ free(d);
+ return 0;
+}
+
+static krb5_error_code
+mkt_get_name(krb5_context context,
+ krb5_keytab id,
+ char *name,
+ size_t namesize)
+{
+ strncpy(name, "", namesize);
+ return 0;
+}
+
+static krb5_error_code
+mkt_start_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *c)
+{
+ /* XXX */
+ c->fd = 0;
+ return 0;
+}
+
+static krb5_error_code
+mkt_next_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *c)
+{
+ struct mkt_data *d = id->data;
+ if(c->fd >= d->num_entries)
+ return KRB5_KT_END;
+ return krb5_kt_copy_entry_contents(context, &d->entries[c->fd++], entry);
+}
+
+static krb5_error_code
+mkt_end_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ return 0;
+}
+
+static krb5_error_code
+mkt_add_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ struct mkt_data *d = id->data;
+ krb5_keytab_entry *tmp;
+ tmp = realloc(d->entries, (d->num_entries + 1) * sizeof(*d->entries));
+ if(tmp == NULL)
+ return ENOMEM;
+ d->entries = tmp;
+ return krb5_kt_copy_entry_contents(context, entry,
+ &d->entries[d->num_entries++]);
+}
+
+static krb5_error_code
+mkt_remove_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ struct mkt_data *d = id->data;
+ krb5_keytab_entry *e, *end;
+
+ /* do this backwards to minimize copying */
+ for(end = d->entries + d->num_entries, e = end - 1; e >= d->entries; e--) {
+ if(krb5_kt_compare(context, e, entry->principal,
+ entry->vno, entry->keyblock.keytype)) {
+ krb5_kt_free_entry(context, e);
+ memmove(e, e + 1, (end - e - 1) * sizeof(*e));
+ memset(end - 1, 0, sizeof(*end));
+ d->num_entries--;
+ end--;
+ }
+ }
+ e = realloc(d->entries, d->num_entries * sizeof(*d->entries));
+ if(e != NULL)
+ d->entries = e;
+ return 0;
+}
+
+const krb5_kt_ops krb5_mkt_ops = {
+ "MEMORY",
+ mkt_resolve,
+ mkt_get_name,
+ mkt_close,
+ NULL, /* get */
+ mkt_start_seq_get,
+ mkt_next_entry,
+ mkt_end_seq_get,
+ mkt_add_entry,
+ mkt_remove_entry
+};
diff --git a/crypto/heimdal/lib/krb5/krb5-private.h b/crypto/heimdal/lib/krb5/krb5-private.h
new file mode 100644
index 000000000000..b24328a43abd
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5-private.h
@@ -0,0 +1,58 @@
+/* This is a generated file */
+#ifndef __krb5_private_h__
+#define __krb5_private_h__
+
+#ifdef __STDC__
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+void
+_krb5_crc_init_table __P((void));
+
+u_int32_t
+_krb5_crc_update __P((
+ char *p,
+ size_t len,
+ u_int32_t res));
+
+int
+_krb5_extract_ticket __P((
+ krb5_context context,
+ krb5_kdc_rep *rep,
+ krb5_creds *creds,
+ krb5_keyblock *key,
+ krb5_const_pointer keyseed,
+ krb5_key_usage key_usage,
+ krb5_addresses *addrs,
+ unsigned nonce,
+ krb5_boolean allow_server_mismatch,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg));
+
+ssize_t
+_krb5_get_int __P((
+ void *buffer,
+ unsigned long *value,
+ size_t size));
+
+void
+_krb5_n_fold __P((
+ const void *str,
+ size_t len,
+ void *key,
+ size_t size));
+
+ssize_t
+_krb5_put_int __P((
+ void *buffer,
+ unsigned long value,
+ size_t size));
+
+#endif /* __krb5_private_h__ */
diff --git a/crypto/heimdal/lib/krb5/krb5-protos.h b/crypto/heimdal/lib/krb5/krb5-protos.h
new file mode 100644
index 000000000000..8813c7a848f5
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5-protos.h
@@ -0,0 +1,2352 @@
+/* This is a generated file */
+#ifndef __krb5_protos_h__
+#define __krb5_protos_h__
+
+#ifdef __STDC__
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(x)
+#endif
+
+krb5_error_code
+krb524_convert_creds_kdc __P((
+ krb5_context context,
+ krb5_ccache ccache,
+ krb5_creds *in_cred,
+ struct credentials *v4creds));
+
+krb5_error_code
+krb5_425_conv_principal __P((
+ krb5_context context,
+ const char *name,
+ const char *instance,
+ const char *realm,
+ krb5_principal *princ));
+
+krb5_error_code
+krb5_425_conv_principal_ext __P((
+ krb5_context context,
+ const char *name,
+ const char *instance,
+ const char *realm,
+ krb5_boolean (*func)(krb5_context, krb5_principal),
+ krb5_boolean resolve,
+ krb5_principal *princ));
+
+krb5_error_code
+krb5_524_conv_principal __P((
+ krb5_context context,
+ const krb5_principal principal,
+ char *name,
+ char *instance,
+ char *realm));
+
+krb5_error_code
+krb5_abort __P((
+ krb5_context context,
+ krb5_error_code code,
+ const char *fmt,
+ ...))
+ __attribute__ ((noreturn, format (printf, 3, 4)));
+
+krb5_error_code
+krb5_abortx __P((
+ krb5_context context,
+ const char *fmt,
+ ...))
+ __attribute__ ((noreturn, format (printf, 2, 3)));
+
+krb5_error_code
+krb5_add_et_list __P((
+ krb5_context context,
+ void (*func)(struct et_list **)));
+
+krb5_error_code
+krb5_add_extra_addresses __P((
+ krb5_context context,
+ krb5_addresses *addresses));
+
+krb5_error_code
+krb5_addlog_dest __P((
+ krb5_context context,
+ krb5_log_facility *f,
+ const char *p));
+
+krb5_error_code
+krb5_addlog_func __P((
+ krb5_context context,
+ krb5_log_facility *fac,
+ int min,
+ int max,
+ krb5_log_log_func_t log,
+ krb5_log_close_func_t close,
+ void *data));
+
+krb5_error_code
+krb5_addr2sockaddr __P((
+ const krb5_address *addr,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port));
+
+krb5_boolean
+krb5_address_compare __P((
+ krb5_context context,
+ const krb5_address *addr1,
+ const krb5_address *addr2));
+
+int
+krb5_address_order __P((
+ krb5_context context,
+ const krb5_address *addr1,
+ const krb5_address *addr2));
+
+krb5_boolean
+krb5_address_search __P((
+ krb5_context context,
+ const krb5_address *addr,
+ const krb5_addresses *addrlist));
+
+krb5_error_code
+krb5_aname_to_localname __P((
+ krb5_context context,
+ krb5_const_principal aname,
+ size_t lnsize,
+ char *lname));
+
+krb5_error_code
+krb5_anyaddr __P((
+ int af,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port));
+
+krb5_error_code
+krb5_append_addresses __P((
+ krb5_context context,
+ krb5_addresses *dest,
+ const krb5_addresses *source));
+
+krb5_error_code
+krb5_auth_con_free __P((
+ krb5_context context,
+ krb5_auth_context auth_context));
+
+krb5_error_code
+krb5_auth_con_getaddrs __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_address **local_addr,
+ krb5_address **remote_addr));
+
+krb5_error_code
+krb5_auth_con_getflags __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *flags));
+
+krb5_error_code
+krb5_auth_con_getkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock));
+
+krb5_error_code
+krb5_auth_con_getlocalsubkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock));
+
+krb5_error_code
+krb5_auth_con_getremotesubkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock));
+
+krb5_error_code
+krb5_auth_con_init __P((
+ krb5_context context,
+ krb5_auth_context *auth_context));
+
+krb5_error_code
+krb5_auth_con_setaddrs __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_address *local_addr,
+ krb5_address *remote_addr));
+
+krb5_error_code
+krb5_auth_con_setaddrs_from_fd __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ void *p_fd));
+
+krb5_error_code
+krb5_auth_con_setflags __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t flags));
+
+krb5_error_code
+krb5_auth_con_setkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock));
+
+krb5_error_code
+krb5_auth_con_setlocalsubkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock));
+
+krb5_error_code
+krb5_auth_con_setremotesubkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock));
+
+krb5_error_code
+krb5_auth_con_setuserkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock));
+
+krb5_error_code
+krb5_auth_getauthenticator __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_authenticator *authenticator));
+
+krb5_error_code
+krb5_auth_getcksumtype __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_cksumtype *cksumtype));
+
+krb5_error_code
+krb5_auth_getkeytype __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keytype *keytype));
+
+krb5_error_code
+krb5_auth_getlocalseqnumber __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *seqnumber));
+
+krb5_error_code
+krb5_auth_getremoteseqnumber __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *seqnumber));
+
+krb5_error_code
+krb5_auth_setcksumtype __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_cksumtype cksumtype));
+
+krb5_error_code
+krb5_auth_setkeytype __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keytype keytype));
+
+krb5_error_code
+krb5_auth_setlocalseqnumber __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t seqnumber));
+
+krb5_error_code
+krb5_auth_setremoteseqnumber __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t seqnumber));
+
+krb5_error_code
+krb5_build_ap_req __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ krb5_creds *cred,
+ krb5_flags ap_options,
+ krb5_data authenticator,
+ krb5_data *retdata));
+
+krb5_error_code
+krb5_build_authenticator __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_enctype enctype,
+ krb5_creds *cred,
+ Checksum *cksum,
+ Authenticator **auth_result,
+ krb5_data *result));
+
+krb5_error_code
+krb5_build_principal __P((
+ krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ ...));
+
+krb5_error_code
+krb5_build_principal_ext __P((
+ krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ ...));
+
+krb5_error_code
+krb5_build_principal_va __P((
+ krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ va_list ap));
+
+krb5_error_code
+krb5_build_principal_va_ext __P((
+ krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ va_list ap));
+
+krb5_error_code
+krb5_cc_close __P((
+ krb5_context context,
+ krb5_ccache id));
+
+krb5_error_code
+krb5_cc_copy_cache __P((
+ krb5_context context,
+ const krb5_ccache from,
+ krb5_ccache to));
+
+krb5_error_code
+krb5_cc_default __P((
+ krb5_context context,
+ krb5_ccache *id));
+
+const char*
+krb5_cc_default_name __P((krb5_context context));
+
+krb5_error_code
+krb5_cc_destroy __P((
+ krb5_context context,
+ krb5_ccache id));
+
+krb5_error_code
+krb5_cc_end_seq_get __P((
+ krb5_context context,
+ const krb5_ccache id,
+ krb5_cc_cursor *cursor));
+
+krb5_error_code
+krb5_cc_gen_new __P((
+ krb5_context context,
+ const krb5_cc_ops *ops,
+ krb5_ccache *id));
+
+const char*
+krb5_cc_get_name __P((
+ krb5_context context,
+ krb5_ccache id));
+
+krb5_error_code
+krb5_cc_get_principal __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_principal *principal));
+
+const char*
+krb5_cc_get_type __P((
+ krb5_context context,
+ krb5_ccache id));
+
+krb5_error_code
+krb5_cc_get_version __P((
+ krb5_context context,
+ const krb5_ccache id));
+
+krb5_error_code
+krb5_cc_initialize __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_principal primary_principal));
+
+krb5_error_code
+krb5_cc_next_cred __P((
+ krb5_context context,
+ const krb5_ccache id,
+ krb5_creds *creds,
+ krb5_cc_cursor *cursor));
+
+krb5_error_code
+krb5_cc_register __P((
+ krb5_context context,
+ const krb5_cc_ops *ops,
+ krb5_boolean override));
+
+krb5_error_code
+krb5_cc_remove_cred __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_flags which,
+ krb5_creds *cred));
+
+krb5_error_code
+krb5_cc_resolve __P((
+ krb5_context context,
+ const char *name,
+ krb5_ccache *id));
+
+krb5_error_code
+krb5_cc_retrieve_cred __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_flags whichfields,
+ const krb5_creds *mcreds,
+ krb5_creds *creds));
+
+krb5_error_code
+krb5_cc_set_flags __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_flags flags));
+
+krb5_error_code
+krb5_cc_start_seq_get __P((
+ krb5_context context,
+ const krb5_ccache id,
+ krb5_cc_cursor *cursor));
+
+krb5_error_code
+krb5_cc_store_cred __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_creds *creds));
+
+krb5_error_code
+krb5_change_password __P((
+ krb5_context context,
+ krb5_creds *creds,
+ char *newpw,
+ int *result_code,
+ krb5_data *result_code_string,
+ krb5_data *result_string));
+
+krb5_boolean
+krb5_checksum_is_collision_proof __P((
+ krb5_context context,
+ krb5_cksumtype type));
+
+krb5_boolean
+krb5_checksum_is_keyed __P((
+ krb5_context context,
+ krb5_cksumtype type));
+
+krb5_error_code
+krb5_checksumsize __P((
+ krb5_context context,
+ krb5_cksumtype type,
+ size_t *size));
+
+krb5_error_code
+krb5_closelog __P((
+ krb5_context context,
+ krb5_log_facility *fac));
+
+krb5_boolean
+krb5_compare_creds __P((
+ krb5_context context,
+ krb5_flags whichfields,
+ const krb5_creds *mcreds,
+ const krb5_creds *creds));
+
+krb5_error_code
+krb5_config_file_free __P((
+ krb5_context context,
+ krb5_config_section *s));
+
+void
+krb5_config_free_strings __P((char **strings));
+
+const void *
+krb5_config_get __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int type,
+ ...));
+
+krb5_boolean
+krb5_config_get_bool __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+krb5_boolean
+krb5_config_get_bool_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ krb5_boolean def_value,
+ ...));
+
+int
+krb5_config_get_int __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+int
+krb5_config_get_int_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ ...));
+
+const krb5_config_binding *
+krb5_config_get_list __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+const void *
+krb5_config_get_next __P((
+ krb5_context context,
+ krb5_config_section *c,
+ krb5_config_binding **pointer,
+ int type,
+ ...));
+
+const char *
+krb5_config_get_string __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+char**
+krb5_config_get_strings __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+int
+krb5_config_get_time __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+int
+krb5_config_get_time_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ ...));
+
+krb5_error_code
+krb5_config_parse_file __P((
+ const char *fname,
+ krb5_config_section **res));
+
+krb5_error_code
+krb5_config_parse_file_debug __P((
+ const char *fname,
+ krb5_config_section **res,
+ unsigned *lineno,
+ char **error_message));
+
+const void *
+krb5_config_vget __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int type,
+ va_list args));
+
+krb5_boolean
+krb5_config_vget_bool __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+krb5_boolean
+krb5_config_vget_bool_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ krb5_boolean def_value,
+ va_list args));
+
+int
+krb5_config_vget_int __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+int
+krb5_config_vget_int_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ va_list args));
+
+const krb5_config_binding *
+krb5_config_vget_list __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+const void *
+krb5_config_vget_next __P((
+ krb5_context context,
+ krb5_config_section *c,
+ krb5_config_binding **pointer,
+ int type,
+ va_list args));
+
+const char *
+krb5_config_vget_string __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+char **
+krb5_config_vget_strings __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+int
+krb5_config_vget_time __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+int
+krb5_config_vget_time_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ va_list args));
+
+krb5_error_code
+krb5_copy_address __P((
+ krb5_context context,
+ const krb5_address *inaddr,
+ krb5_address *outaddr));
+
+krb5_error_code
+krb5_copy_addresses __P((
+ krb5_context context,
+ const krb5_addresses *inaddr,
+ krb5_addresses *outaddr));
+
+krb5_error_code
+krb5_copy_creds __P((
+ krb5_context context,
+ const krb5_creds *incred,
+ krb5_creds **outcred));
+
+krb5_error_code
+krb5_copy_creds_contents __P((
+ krb5_context context,
+ const krb5_creds *incred,
+ krb5_creds *c));
+
+krb5_error_code
+krb5_copy_data __P((
+ krb5_context context,
+ const krb5_data *indata,
+ krb5_data **outdata));
+
+krb5_error_code
+krb5_copy_host_realm __P((
+ krb5_context context,
+ const krb5_realm *from,
+ krb5_realm **to));
+
+krb5_error_code
+krb5_copy_keyblock __P((
+ krb5_context context,
+ const krb5_keyblock *inblock,
+ krb5_keyblock **to));
+
+krb5_error_code
+krb5_copy_keyblock_contents __P((
+ krb5_context context,
+ const krb5_keyblock *inblock,
+ krb5_keyblock *to));
+
+krb5_error_code
+krb5_copy_principal __P((
+ krb5_context context,
+ krb5_const_principal inprinc,
+ krb5_principal *outprinc));
+
+krb5_error_code
+krb5_copy_ticket __P((
+ krb5_context context,
+ const krb5_ticket *from,
+ krb5_ticket **to));
+
+krb5_error_code
+krb5_create_checksum __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage_or_type,
+ void *data,
+ size_t len,
+ Checksum *result));
+
+krb5_error_code
+krb5_crypto_destroy __P((
+ krb5_context context,
+ krb5_crypto crypto));
+
+krb5_error_code
+krb5_crypto_init __P((
+ krb5_context context,
+ krb5_keyblock *key,
+ krb5_enctype etype,
+ krb5_crypto *crypto));
+
+krb5_error_code
+krb5_data_alloc __P((
+ krb5_data *p,
+ int len));
+
+krb5_error_code
+krb5_data_copy __P((
+ krb5_data *p,
+ const void *data,
+ size_t len));
+
+void
+krb5_data_free __P((krb5_data *p));
+
+krb5_error_code
+krb5_data_realloc __P((
+ krb5_data *p,
+ int len));
+
+void
+krb5_data_zero __P((krb5_data *p));
+
+krb5_error_code
+krb5_decode_Authenticator __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ Authenticator *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_ETYPE_INFO __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ ETYPE_INFO *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_EncAPRepPart __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ EncAPRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_EncASRepPart __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ EncASRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_EncKrbCredPart __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ EncKrbCredPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_EncTGSRepPart __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ EncTGSRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_EncTicketPart __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ EncTicketPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_ap_req __P((
+ krb5_context context,
+ const krb5_data *inbuf,
+ krb5_ap_req *ap_req));
+
+krb5_error_code
+krb5_decrypt __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result));
+
+krb5_error_code
+krb5_decrypt_EncryptedData __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ EncryptedData *e,
+ krb5_data *result));
+
+krb5_error_code
+krb5_decrypt_ticket __P((
+ krb5_context context,
+ Ticket *ticket,
+ krb5_keyblock *key,
+ EncTicketPart *out,
+ krb5_flags flags));
+
+krb5_error_code
+krb5_domain_x500_decode __P((
+ krb5_data tr,
+ char ***realms,
+ int *num_realms,
+ const char *client_realm,
+ const char *server_realm));
+
+krb5_error_code
+krb5_domain_x500_encode __P((
+ char **realms,
+ int num_realms,
+ krb5_data *encoding));
+
+krb5_error_code
+krb5_encode_Authenticator __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ Authenticator *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_ETYPE_INFO __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ ETYPE_INFO *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_EncAPRepPart __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ EncAPRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_EncASRepPart __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ EncASRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_EncKrbCredPart __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ EncKrbCredPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_EncTGSRepPart __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ EncTGSRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_EncTicketPart __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ EncTicketPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encrypt __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result));
+
+krb5_error_code
+krb5_encrypt_EncryptedData __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ int kvno,
+ EncryptedData *result));
+
+krb5_error_code
+krb5_enctype_to_keytype __P((
+ krb5_context context,
+ krb5_enctype etype,
+ krb5_keytype *keytype));
+
+krb5_error_code
+krb5_enctype_to_string __P((
+ krb5_context context,
+ krb5_enctype etype,
+ char **string));
+
+krb5_error_code
+krb5_enctype_valid __P((
+ krb5_context context,
+ krb5_enctype etype));
+
+krb5_boolean
+krb5_enctypes_compatible_keys __P((
+ krb5_context context,
+ krb5_enctype etype1,
+ krb5_enctype etype2));
+
+krb5_error_code
+krb5_err __P((
+ krb5_context context,
+ int eval,
+ krb5_error_code code,
+ const char *fmt,
+ ...))
+ __attribute__ ((noreturn, format (printf, 4, 5)));
+
+krb5_error_code
+krb5_errx __P((
+ krb5_context context,
+ int eval,
+ const char *fmt,
+ ...))
+ __attribute__ ((noreturn, format (printf, 3, 4)));
+
+krb5_error_code
+krb5_expand_hostname __P((
+ krb5_context context,
+ const char *orig_hostname,
+ char **new_hostname));
+
+PA_DATA *
+krb5_find_padata __P((
+ PA_DATA *val,
+ unsigned len,
+ int type,
+ int *index));
+
+krb5_error_code
+krb5_free_address __P((
+ krb5_context context,
+ krb5_address *address));
+
+krb5_error_code
+krb5_free_addresses __P((
+ krb5_context context,
+ krb5_addresses *addresses));
+
+void
+krb5_free_ap_rep_enc_part __P((
+ krb5_context context,
+ krb5_ap_rep_enc_part *val));
+
+void
+krb5_free_authenticator __P((
+ krb5_context context,
+ krb5_authenticator *authenticator));
+
+void
+krb5_free_context __P((krb5_context context));
+
+krb5_error_code
+krb5_free_cred_contents __P((
+ krb5_context context,
+ krb5_creds *c));
+
+krb5_error_code
+krb5_free_creds __P((
+ krb5_context context,
+ krb5_creds *c));
+
+krb5_error_code
+krb5_free_creds_contents __P((
+ krb5_context context,
+ krb5_creds *c));
+
+void
+krb5_free_data __P((
+ krb5_context context,
+ krb5_data *p));
+
+void
+krb5_free_error __P((
+ krb5_context context,
+ krb5_error *error));
+
+void
+krb5_free_error_contents __P((
+ krb5_context context,
+ krb5_error *error));
+
+krb5_error_code
+krb5_free_host_realm __P((
+ krb5_context context,
+ krb5_realm *realmlist));
+
+krb5_error_code
+krb5_free_kdc_rep __P((
+ krb5_context context,
+ krb5_kdc_rep *rep));
+
+void
+krb5_free_keyblock __P((
+ krb5_context context,
+ krb5_keyblock *keyblock));
+
+void
+krb5_free_keyblock_contents __P((
+ krb5_context context,
+ krb5_keyblock *keyblock));
+
+krb5_error_code
+krb5_free_krbhst __P((
+ krb5_context context,
+ char **hostlist));
+
+void
+krb5_free_principal __P((
+ krb5_context context,
+ krb5_principal p));
+
+krb5_error_code
+krb5_free_salt __P((
+ krb5_context context,
+ krb5_salt salt));
+
+krb5_error_code
+krb5_free_ticket __P((
+ krb5_context context,
+ krb5_ticket *ticket));
+
+krb5_error_code
+krb5_fwd_tgt_creds __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const char *hostname,
+ krb5_principal client,
+ krb5_principal server,
+ krb5_ccache ccache,
+ int forwardable,
+ krb5_data *out_data));
+
+void
+krb5_generate_random_block __P((
+ void *buf,
+ size_t len));
+
+krb5_error_code
+krb5_generate_random_keyblock __P((
+ krb5_context context,
+ krb5_enctype type,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_generate_seq_number __P((
+ krb5_context context,
+ const krb5_keyblock *key,
+ int32_t *seqno));
+
+krb5_error_code
+krb5_generate_subkey __P((
+ krb5_context context,
+ const krb5_keyblock *key,
+ krb5_keyblock **subkey));
+
+krb5_error_code
+krb5_get_all_client_addrs __P((
+ krb5_context context,
+ krb5_addresses *res));
+
+krb5_error_code
+krb5_get_all_server_addrs __P((
+ krb5_context context,
+ krb5_addresses *res));
+
+krb5_error_code
+krb5_get_cred_from_kdc __P((
+ krb5_context context,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds,
+ krb5_creds ***ret_tgts));
+
+krb5_error_code
+krb5_get_credentials __P((
+ krb5_context context,
+ krb5_flags options,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds));
+
+krb5_error_code
+krb5_get_credentials_with_flags __P((
+ krb5_context context,
+ krb5_flags options,
+ krb5_kdc_flags flags,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds));
+
+krb5_error_code
+krb5_get_default_in_tkt_etypes __P((
+ krb5_context context,
+ krb5_enctype **etypes));
+
+krb5_error_code
+krb5_get_default_principal __P((
+ krb5_context context,
+ krb5_principal *princ));
+
+krb5_error_code
+krb5_get_default_realm __P((
+ krb5_context context,
+ krb5_realm *realm));
+
+krb5_error_code
+krb5_get_default_realms __P((
+ krb5_context context,
+ krb5_realm **realms));
+
+const char *
+krb5_get_err_text __P((
+ krb5_context context,
+ krb5_error_code code));
+
+krb5_error_code
+krb5_get_extra_addresses __P((
+ krb5_context context,
+ krb5_addresses *addresses));
+
+krb5_error_code
+krb5_get_fcache_version __P((
+ krb5_context context,
+ int *version));
+
+krb5_error_code
+krb5_get_forwarded_creds __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_ccache ccache,
+ krb5_flags flags,
+ const char *hostname,
+ krb5_creds *in_creds,
+ krb5_data *out_data));
+
+krb5_error_code
+krb5_get_host_realm __P((
+ krb5_context context,
+ const char *host,
+ krb5_realm **realms));
+
+krb5_error_code
+krb5_get_host_realm_int __P((
+ krb5_context context,
+ const char *host,
+ krb5_realm **realms));
+
+krb5_error_code
+krb5_get_in_cred __P((
+ krb5_context context,
+ krb5_flags options,
+ const krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *ptypes,
+ const krb5_preauthdata *preauth,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply));
+
+krb5_error_code
+krb5_get_in_tkt __P((
+ krb5_context context,
+ krb5_flags options,
+ const krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *ptypes,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg,
+ krb5_creds *creds,
+ krb5_ccache ccache,
+ krb5_kdc_rep *ret_as_reply));
+
+krb5_error_code
+krb5_get_in_tkt_with_keytab __P((
+ krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ krb5_keytab keytab,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply));
+
+krb5_error_code
+krb5_get_in_tkt_with_password __P((
+ krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ const char *password,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply));
+
+krb5_error_code
+krb5_get_in_tkt_with_skey __P((
+ krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ const krb5_keyblock *key,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply));
+
+krb5_error_code
+krb5_get_init_creds_keytab __P((
+ krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_keytab keytab,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options));
+
+void
+krb5_get_init_creds_opt_init __P((krb5_get_init_creds_opt *opt));
+
+void
+krb5_get_init_creds_opt_set_address_list __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_addresses *addresses));
+
+void
+krb5_get_init_creds_opt_set_etype_list __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_enctype *etype_list,
+ int etype_list_length));
+
+void
+krb5_get_init_creds_opt_set_forwardable __P((
+ krb5_get_init_creds_opt *opt,
+ int forwardable));
+
+void
+krb5_get_init_creds_opt_set_preauth_list __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_preauthtype *preauth_list,
+ int preauth_list_length));
+
+void
+krb5_get_init_creds_opt_set_proxiable __P((
+ krb5_get_init_creds_opt *opt,
+ int proxiable));
+
+void
+krb5_get_init_creds_opt_set_renew_life __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_deltat renew_life));
+
+void
+krb5_get_init_creds_opt_set_salt __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_data *salt));
+
+void
+krb5_get_init_creds_opt_set_tkt_life __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_deltat tkt_life));
+
+krb5_error_code
+krb5_get_init_creds_password __P((
+ krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ const char *password,
+ krb5_prompter_fct prompter,
+ void *data,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options));
+
+krb5_error_code
+krb5_get_kdc_cred __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_kdc_flags flags,
+ krb5_addresses *addresses,
+ Ticket *second_ticket,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds ));
+
+krb5_error_code
+krb5_get_krb_admin_hst __P((
+ krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist));
+
+krb5_error_code
+krb5_get_krb_changepw_hst __P((
+ krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist));
+
+krb5_error_code
+krb5_get_krbhst __P((
+ krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist));
+
+krb5_error_code
+krb5_get_pw_salt __P((
+ krb5_context context,
+ krb5_const_principal principal,
+ krb5_salt *salt));
+
+krb5_boolean
+krb5_get_use_admin_kdc __P((krb5_context context));
+
+size_t
+krb5_get_wrapped_length __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ size_t data_len));
+
+int
+krb5_getportbyname __P((
+ krb5_context context,
+ const char *service,
+ const char *proto,
+ int default_port));
+
+krb5_error_code
+krb5_h_addr2addr __P((
+ int af,
+ const char *haddr,
+ krb5_address *addr));
+
+krb5_error_code
+krb5_h_addr2sockaddr __P((
+ int af,
+ const char *addr,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port));
+
+krb5_error_code
+krb5_init_context __P((krb5_context *context));
+
+void
+krb5_init_ets __P((krb5_context context));
+
+krb5_error_code
+krb5_init_etype __P((
+ krb5_context context,
+ unsigned *len,
+ int **val,
+ const krb5_enctype *etypes));
+
+krb5_error_code
+krb5_initlog __P((
+ krb5_context context,
+ const char *program,
+ krb5_log_facility **fac));
+
+krb5_error_code
+krb5_keyblock_key_proc __P((
+ krb5_context context,
+ krb5_keytype type,
+ krb5_data *salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key));
+
+krb5_error_code
+krb5_keytab_key_proc __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key));
+
+krb5_error_code
+krb5_keytype_to_enctypes __P((
+ krb5_context context,
+ krb5_keytype keytype,
+ unsigned *len,
+ int **val));
+
+krb5_error_code
+krb5_keytype_to_enctypes_default __P((
+ krb5_context context,
+ krb5_keytype keytype,
+ unsigned *len,
+ int **val));
+
+krb5_error_code
+krb5_keytype_to_string __P((
+ krb5_context context,
+ krb5_keytype keytype,
+ char **string));
+
+krb5_error_code
+krb5_kt_add_entry __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry));
+
+krb5_error_code
+krb5_kt_close __P((
+ krb5_context context,
+ krb5_keytab id));
+
+krb5_boolean
+krb5_kt_compare __P((
+ krb5_context context,
+ krb5_keytab_entry *entry,
+ krb5_const_principal principal,
+ krb5_kvno vno,
+ krb5_enctype enctype));
+
+krb5_error_code
+krb5_kt_copy_entry_contents __P((
+ krb5_context context,
+ const krb5_keytab_entry *in,
+ krb5_keytab_entry *out));
+
+krb5_error_code
+krb5_kt_default __P((
+ krb5_context context,
+ krb5_keytab *id));
+
+krb5_error_code
+krb5_kt_default_name __P((
+ krb5_context context,
+ char *name,
+ size_t namesize));
+
+krb5_error_code
+krb5_kt_end_seq_get __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor));
+
+krb5_error_code
+krb5_kt_free_entry __P((
+ krb5_context context,
+ krb5_keytab_entry *entry));
+
+krb5_error_code
+krb5_kt_get_entry __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_const_principal principal,
+ krb5_kvno kvno,
+ krb5_enctype enctype,
+ krb5_keytab_entry *entry));
+
+krb5_error_code
+krb5_kt_get_name __P((
+ krb5_context context,
+ krb5_keytab keytab,
+ char *name,
+ size_t namesize));
+
+krb5_error_code
+krb5_kt_next_entry __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor));
+
+krb5_error_code
+krb5_kt_read_service_key __P((
+ krb5_context context,
+ krb5_pointer keyprocarg,
+ krb5_principal principal,
+ krb5_kvno vno,
+ krb5_enctype enctype,
+ krb5_keyblock **key));
+
+krb5_error_code
+krb5_kt_register __P((
+ krb5_context context,
+ const krb5_kt_ops *ops));
+
+krb5_error_code
+krb5_kt_remove_entry __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry));
+
+krb5_error_code
+krb5_kt_resolve __P((
+ krb5_context context,
+ const char *name,
+ krb5_keytab *id));
+
+krb5_error_code
+krb5_kt_start_seq_get __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor));
+
+krb5_boolean
+krb5_kuserok __P((
+ krb5_context context,
+ krb5_principal principal,
+ const char *luser));
+
+krb5_error_code
+krb5_log __P((
+ krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ const char *fmt,
+ ...))
+ __attribute__((format (printf, 4, 5)));
+
+krb5_error_code
+krb5_log_msg __P((
+ krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ char **reply,
+ const char *fmt,
+ ...))
+ __attribute__((format (printf, 5, 6)));
+
+krb5_error_code
+krb5_make_addrport __P((
+ krb5_address **res,
+ const krb5_address *addr,
+ int16_t port));
+
+krb5_error_code
+krb5_make_principal __P((
+ krb5_context context,
+ krb5_principal *principal,
+ krb5_const_realm realm,
+ ...));
+
+size_t
+krb5_max_sockaddr_size __P((void));
+
+krb5_error_code
+krb5_mk_error __P((
+ krb5_context context,
+ krb5_error_code error_code,
+ const char *e_text,
+ const krb5_data *e_data,
+ const krb5_principal client,
+ const krb5_principal server,
+ time_t ctime,
+ krb5_data *reply));
+
+krb5_error_code
+krb5_mk_priv __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *userdata,
+ krb5_data *outbuf,
+ void *outdata));
+
+krb5_error_code
+krb5_mk_rep __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_data *outbuf));
+
+krb5_error_code
+krb5_mk_req __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ char *service,
+ char *hostname,
+ krb5_data *in_data,
+ krb5_ccache ccache,
+ krb5_data *outbuf));
+
+krb5_error_code
+krb5_mk_req_extended __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_data *outbuf));
+
+krb5_error_code
+krb5_mk_req_internal __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_data *outbuf,
+ krb5_key_usage usage));
+
+krb5_error_code
+krb5_mk_safe __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *userdata,
+ krb5_data *outbuf,
+ void *outdata));
+
+ssize_t
+krb5_net_read __P((
+ krb5_context context,
+ void *p_fd,
+ void *buf,
+ size_t len));
+
+ssize_t
+krb5_net_write __P((
+ krb5_context context,
+ void *p_fd,
+ const void *buf,
+ size_t len));
+
+krb5_error_code
+krb5_openlog __P((
+ krb5_context context,
+ const char *program,
+ krb5_log_facility **fac));
+
+krb5_error_code
+krb5_parse_address __P((
+ krb5_context context,
+ const char *string,
+ krb5_addresses *addresses));
+
+krb5_error_code
+krb5_parse_name __P((
+ krb5_context context,
+ const char *name,
+ krb5_principal *principal));
+
+krb5_error_code
+krb5_password_key_proc __P((
+ krb5_context context,
+ krb5_enctype type,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key));
+
+krb5_realm*
+krb5_princ_realm __P((
+ krb5_context context,
+ krb5_principal principal));
+
+void
+krb5_princ_set_realm __P((
+ krb5_context context,
+ krb5_principal principal,
+ krb5_realm *realm));
+
+krb5_error_code
+krb5_principal2principalname __P((
+ PrincipalName *p,
+ const krb5_principal from));
+
+krb5_boolean
+krb5_principal_compare __P((
+ krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2));
+
+krb5_boolean
+krb5_principal_compare_any_realm __P((
+ krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2));
+
+krb5_error_code
+krb5_print_address __P((
+ const krb5_address *addr,
+ char *str,
+ size_t len,
+ size_t *ret_len));
+
+int
+krb5_program_setup __P((
+ krb5_context *context,
+ int argc,
+ char **argv,
+ struct getargs *args,
+ int num_args,
+ void (*usage)(int, struct getargs*, int)));
+
+int
+krb5_prompter_posix __P((
+ krb5_context context,
+ void *data,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[]));
+
+krb5_error_code
+krb5_rd_cred __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_ccache ccache,
+ krb5_data *in_data));
+
+krb5_error_code
+krb5_rd_error __P((
+ krb5_context context,
+ krb5_data *msg,
+ KRB_ERROR *result));
+
+krb5_error_code
+krb5_rd_priv __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_data *outbuf,
+ void *outdata));
+
+krb5_error_code
+krb5_rd_rep __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_ap_rep_enc_part **repl));
+
+krb5_error_code
+krb5_rd_req __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_data *inbuf,
+ krb5_const_principal server,
+ krb5_keytab keytab,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket));
+
+krb5_error_code
+krb5_rd_req_with_keyblock __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_data *inbuf,
+ krb5_const_principal server,
+ krb5_keyblock *keyblock,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket));
+
+krb5_error_code
+krb5_rd_safe __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_data *outbuf,
+ void *outdata));
+
+krb5_error_code
+krb5_read_message __P((
+ krb5_context context,
+ krb5_pointer p_fd,
+ krb5_data *data));
+
+krb5_boolean
+krb5_realm_compare __P((
+ krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2));
+
+krb5_error_code
+krb5_recvauth __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ char *appl_version,
+ krb5_principal server,
+ int32_t flags,
+ krb5_keytab keytab,
+ krb5_ticket **ticket));
+
+krb5_error_code
+krb5_recvauth_match_version __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ krb5_boolean (*match_appl_version)(void *, const char*),
+ void *match_data,
+ krb5_principal server,
+ int32_t flags,
+ krb5_keytab keytab,
+ krb5_ticket **ticket));
+
+krb5_error_code
+krb5_ret_address __P((
+ krb5_storage *sp,
+ krb5_address *adr));
+
+krb5_error_code
+krb5_ret_addrs __P((
+ krb5_storage *sp,
+ krb5_addresses *adr));
+
+krb5_error_code
+krb5_ret_authdata __P((
+ krb5_storage *sp,
+ krb5_authdata *auth));
+
+krb5_error_code
+krb5_ret_creds __P((
+ krb5_storage *sp,
+ krb5_creds *creds));
+
+krb5_error_code
+krb5_ret_data __P((
+ krb5_storage *sp,
+ krb5_data *data));
+
+krb5_error_code
+krb5_ret_int16 __P((
+ krb5_storage *sp,
+ int16_t *value));
+
+krb5_error_code
+krb5_ret_int32 __P((
+ krb5_storage *sp,
+ int32_t *value));
+
+krb5_error_code
+krb5_ret_int8 __P((
+ krb5_storage *sp,
+ int8_t *value));
+
+krb5_error_code
+krb5_ret_keyblock __P((
+ krb5_storage *sp,
+ krb5_keyblock *p));
+
+krb5_error_code
+krb5_ret_principal __P((
+ krb5_storage *sp,
+ krb5_principal *princ));
+
+krb5_error_code
+krb5_ret_string __P((
+ krb5_storage *sp,
+ char **string));
+
+krb5_error_code
+krb5_ret_stringz __P((
+ krb5_storage *sp,
+ char **string));
+
+krb5_error_code
+krb5_ret_times __P((
+ krb5_storage *sp,
+ krb5_times *times));
+
+krb5_error_code
+krb5_salttype_to_string __P((
+ krb5_context context,
+ krb5_enctype etype,
+ krb5_salttype stype,
+ char **string));
+
+krb5_error_code
+krb5_sendauth __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ const char *appl_version,
+ krb5_principal client,
+ krb5_principal server,
+ krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_ccache ccache,
+ krb5_error **ret_error,
+ krb5_ap_rep_enc_part **rep_result,
+ krb5_creds **out_creds));
+
+krb5_error_code
+krb5_sendto_kdc __P((
+ krb5_context context,
+ const krb5_data *send,
+ const krb5_realm *realm,
+ krb5_data *receive));
+
+krb5_error_code
+krb5_set_default_in_tkt_etypes __P((
+ krb5_context context,
+ const krb5_enctype *etypes));
+
+krb5_error_code
+krb5_set_default_realm __P((
+ krb5_context context,
+ char *realm));
+
+krb5_error_code
+krb5_set_extra_addresses __P((
+ krb5_context context,
+ krb5_addresses *addresses));
+
+krb5_error_code
+krb5_set_fcache_version __P((
+ krb5_context context,
+ int version));
+
+void
+krb5_set_use_admin_kdc __P((
+ krb5_context context,
+ krb5_boolean flag));
+
+krb5_error_code
+krb5_set_warn_dest __P((
+ krb5_context context,
+ krb5_log_facility *fac));
+
+krb5_error_code
+krb5_sname_to_principal __P((
+ krb5_context context,
+ const char *hostname,
+ const char *sname,
+ int32_t type,
+ krb5_principal *ret_princ));
+
+krb5_error_code
+krb5_sock_to_principal __P((
+ krb5_context context,
+ int sock,
+ const char *sname,
+ int32_t type,
+ krb5_principal *ret_princ));
+
+krb5_error_code
+krb5_sockaddr2address __P((
+ const struct sockaddr *sa,
+ krb5_address *addr));
+
+krb5_error_code
+krb5_sockaddr2port __P((
+ const struct sockaddr *sa,
+ int16_t *port));
+
+krb5_boolean
+krb5_sockaddr_uninteresting __P((const struct sockaddr *sa));
+
+void
+krb5_std_usage __P((
+ int code,
+ struct getargs *args,
+ int num_args));
+
+void
+krb5_storage_clear_flags __P((
+ krb5_storage *sp,
+ krb5_flags flags));
+
+krb5_storage *
+krb5_storage_emem __P((void));
+
+krb5_error_code
+krb5_storage_free __P((krb5_storage *sp));
+
+krb5_storage *
+krb5_storage_from_data __P((krb5_data *data));
+
+krb5_storage *
+krb5_storage_from_fd __P((int fd));
+
+krb5_storage *
+krb5_storage_from_mem __P((
+ void *buf,
+ size_t len));
+
+krb5_boolean
+krb5_storage_is_flags __P((
+ krb5_storage *sp,
+ krb5_flags flags));
+
+void
+krb5_storage_set_flags __P((
+ krb5_storage *sp,
+ krb5_flags flags));
+
+krb5_error_code
+krb5_storage_to_data __P((
+ krb5_storage *sp,
+ krb5_data *data));
+
+krb5_error_code
+krb5_store_address __P((
+ krb5_storage *sp,
+ krb5_address p));
+
+krb5_error_code
+krb5_store_addrs __P((
+ krb5_storage *sp,
+ krb5_addresses p));
+
+krb5_error_code
+krb5_store_authdata __P((
+ krb5_storage *sp,
+ krb5_authdata auth));
+
+krb5_error_code
+krb5_store_creds __P((
+ krb5_storage *sp,
+ krb5_creds *creds));
+
+krb5_error_code
+krb5_store_data __P((
+ krb5_storage *sp,
+ krb5_data data));
+
+krb5_error_code
+krb5_store_int16 __P((
+ krb5_storage *sp,
+ int16_t value));
+
+krb5_error_code
+krb5_store_int32 __P((
+ krb5_storage *sp,
+ int32_t value));
+
+krb5_error_code
+krb5_store_int8 __P((
+ krb5_storage *sp,
+ int8_t value));
+
+krb5_error_code
+krb5_store_keyblock __P((
+ krb5_storage *sp,
+ krb5_keyblock p));
+
+krb5_error_code
+krb5_store_principal __P((
+ krb5_storage *sp,
+ krb5_principal p));
+
+krb5_error_code
+krb5_store_string __P((
+ krb5_storage *sp,
+ const char *s));
+
+krb5_error_code
+krb5_store_stringz __P((
+ krb5_storage *sp,
+ char *s));
+
+krb5_error_code
+krb5_store_times __P((
+ krb5_storage *sp,
+ krb5_times times));
+
+krb5_error_code
+krb5_string_to_enctype __P((
+ krb5_context context,
+ const char *string,
+ krb5_enctype *etype));
+
+krb5_error_code
+krb5_string_to_key __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ const char *password,
+ krb5_principal principal,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_string_to_key_data __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_principal principal,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_string_to_key_data_salt __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_string_to_key_derived __P((
+ krb5_context context,
+ const void *str,
+ size_t len,
+ krb5_enctype etype,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_string_to_key_salt __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ const char *password,
+ krb5_salt salt,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_string_to_keytype __P((
+ krb5_context context,
+ const char *string,
+ krb5_keytype *keytype));
+
+krb5_error_code
+krb5_string_to_salttype __P((
+ krb5_context context,
+ krb5_enctype etype,
+ const char *string,
+ krb5_salttype *salttype));
+
+krb5_error_code
+krb5_timeofday __P((
+ krb5_context context,
+ int32_t *timeret));
+
+krb5_error_code
+krb5_unparse_name __P((
+ krb5_context context,
+ krb5_const_principal principal,
+ char **name));
+
+krb5_error_code
+krb5_unparse_name_fixed __P((
+ krb5_context context,
+ krb5_const_principal principal,
+ char *name,
+ size_t len));
+
+krb5_error_code
+krb5_unparse_name_fixed_short __P((
+ krb5_context context,
+ krb5_const_principal principal,
+ char *name,
+ size_t len));
+
+krb5_error_code
+krb5_unparse_name_short __P((
+ krb5_context context,
+ krb5_const_principal principal,
+ char **name));
+
+krb5_error_code
+krb5_us_timeofday __P((
+ krb5_context context,
+ int32_t *sec,
+ int32_t *usec));
+
+krb5_error_code
+krb5_vabort __P((
+ krb5_context context,
+ krb5_error_code code,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((noreturn, format (printf, 3, 0)));
+
+krb5_error_code
+krb5_vabortx __P((
+ krb5_context context,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((noreturn, format (printf, 2, 0)));
+
+krb5_error_code
+krb5_verify_ap_req __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_ap_req *ap_req,
+ krb5_const_principal server,
+ krb5_keyblock *keyblock,
+ krb5_flags flags,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket));
+
+krb5_error_code
+krb5_verify_authenticator_checksum __P((
+ krb5_context context,
+ krb5_auth_context ac,
+ void *data,
+ size_t len));
+
+krb5_error_code
+krb5_verify_checksum __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ krb5_key_usage usage,
+ void *data,
+ size_t len,
+ Checksum *cksum));
+
+krb5_error_code
+krb5_verify_init_creds __P((
+ krb5_context context,
+ krb5_creds *creds,
+ krb5_principal ap_req_server,
+ krb5_keytab ap_req_keytab,
+ krb5_ccache *ccache,
+ krb5_verify_init_creds_opt *options));
+
+void
+krb5_verify_init_creds_opt_init __P((krb5_verify_init_creds_opt *options));
+
+void
+krb5_verify_init_creds_opt_set_ap_req_nofail __P((
+ krb5_verify_init_creds_opt *options,
+ int ap_req_nofail));
+
+krb5_error_code
+krb5_verify_user __P((
+ krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ const char *password,
+ krb5_boolean secure,
+ const char *service));
+
+krb5_error_code
+krb5_verify_user_lrealm __P((
+ krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ const char *password,
+ krb5_boolean secure,
+ const char *service));
+
+krb5_error_code
+krb5_verr __P((
+ krb5_context context,
+ int eval,
+ krb5_error_code code,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((noreturn, format (printf, 4, 0)));
+
+krb5_error_code
+krb5_verrx __P((
+ krb5_context context,
+ int eval,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((noreturn, format (printf, 3, 0)));
+
+krb5_error_code
+krb5_vlog __P((
+ krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ const char *fmt,
+ va_list ap))
+ __attribute__((format (printf, 4, 0)));
+
+krb5_error_code
+krb5_vlog_msg __P((
+ krb5_context context,
+ krb5_log_facility *fac,
+ char **reply,
+ int level,
+ const char *fmt,
+ va_list ap))
+ __attribute__((format (printf, 5, 0)));
+
+krb5_error_code
+krb5_vwarn __P((
+ krb5_context context,
+ krb5_error_code code,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((format (printf, 3, 0)));
+
+krb5_error_code
+krb5_vwarnx __P((
+ krb5_context context,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((format (printf, 2, 0)));
+
+krb5_error_code
+krb5_warn __P((
+ krb5_context context,
+ krb5_error_code code,
+ const char *fmt,
+ ...))
+ __attribute__ ((format (printf, 3, 4)));
+
+krb5_error_code
+krb5_warnx __P((
+ krb5_context context,
+ const char *fmt,
+ ...))
+ __attribute__ ((format (printf, 2, 3)));
+
+krb5_error_code
+krb5_write_message __P((
+ krb5_context context,
+ krb5_pointer p_fd,
+ krb5_data *data));
+
+krb5_error_code
+krb5_xfree __P((void *ptr));
+
+krb5_error_code
+principalname2krb5_principal __P((
+ krb5_principal *principal,
+ const PrincipalName from,
+ const Realm realm));
+
+#endif /* __krb5_protos_h__ */
diff --git a/crypto/heimdal/lib/krb5/krb5.conf.5 b/crypto/heimdal/lib/krb5/krb5.conf.5
new file mode 100644
index 000000000000..2a0adb6859dd
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5.conf.5
@@ -0,0 +1,167 @@
+.\" $Id: krb5.conf.5,v 1.7 1999/11/04 01:57:28 assar Exp $
+.\"
+.Dd April 11, 1999
+.Dt KRB5.CONF 5
+.Os HEIMDAL
+.Sh NAME
+.Nm /etc/krb5.conf
+.Nd
+Configuration file for Kerberos 5
+.Sh DESCRIPTION
+The
+.Nm
+file specifies several configuration parameters for the Kerberos 5
+library, as well as for some programs.
+.Pp
+The file consists of one or more sections, containing a number of
+bindings. The value of each binding can be either a string or a list
+of other bindings. The grammar looks like:
+.Bd -literal -offset indent
+file:
+ /* empty */
+ sections
+
+sections:
+ section sections
+ section
+
+section:
+ '[' section_name ']' bindings
+
+section_name:
+ STRING
+
+bindings:
+ binding bindings
+ binding
+
+binding:
+ name '=' STRING
+ name '=' '{' bindings '}'
+
+name:
+ STRING
+
+.Ed
+.Li STRINGs
+consists of one or more non-white space characters.
+Currently recognised sections and bindings are:
+
+.Bl -tag -width "xxx" -offset indent
+.It Li [libdefaults]
+.Bl -tag -width "xxx" -offset indent
+.It Li default_realm = Va REALM
+Default realm to use, this is also known as your
+.Dq local realm .
+The default is the result of
+.Fn krb5_get_host_realm "local hostname" .
+.It Li clockskew = Va time
+Maximum time differential (in seconds) allowed when comparing
+times. Default is 300 seconds (five minutes).
+.It Li kdc_timeout = Va time
+Maximum time to wait for a reply from the kdc, default is 3 seconds.
+.It v4_name_convert
+.It v4_instance_resolve
+These are decribed in the
+.Xr krb5_425_conv_principal 3
+manual page.
+.It Li capath = Va realm-routing-table
+.It Li default_etypes = Va etypes...
+A list of default etypes to use.
+.It Li default_etypes_des = Va etypes...
+A list of default etypes to use when requesting a DES credential.
+.It Li default_keytab_name = Va keytab
+The keytab to use if none other is specified, default is
+.Dq FILE:/etc/krb5.keytab .
+.It Li kdc_timesync = Va boolean
+Try to keep track of the time differential between the local machine
+and the KDC, and then compensate for that when issuing requests.
+.It Li max_retries = Va number
+The max number of times to try to contact each KDC.
+.It Li ticket_lifetime = Va time
+Default ticket lifetime.
+.It Li renew_lifetime = Va time
+Default renewable ticket lifetime.
+.It Li verify_ap_req_nofail = Va boolean
+Enable to make a failure to verify obtained credentials
+non-fatal. This can be useful if there is no keytab on a host.
+.It Li warn_pwexpire = Va time
+How soon to warn for expiring password. Default is seven days.
+.It Li http_proxy = Va proxy-spec
+A HTTP-proxy to use when talking to the KDC via HTTP.
+.It Li dns_proxy = Va proxy-spec
+Enable using DNS via HTTP.
+.It Li extra_addresses = Va address...
+A list of addresses to get tickets for along with all local addresses.
+.It Li time_format = Va string
+How to print time strings in logs, this string is passed to
+.Xr strftime 3 .
+.It Li log_utc = Va boolean
+Write log-entries using UTC instead of your local time zone.
+.El
+.It Li [domain_realm]
+This is a list of mappings from DNS domain to Kerberos realm. Each
+binding in this section looks like:
+.Pp
+.Dl domain = realm
+.Pp
+The domain can be either a full name of a host or a trailing
+component, in the latter case the domain-string should start with a
+perid.
+.It Li [realms]
+.Bl -tag -width "xxx" -offset indent
+.It Va REALM Li = {
+.Bl -tag -width "xxx" -offset indent
+.It Li kdc = Va host[:port]
+Specifies a kdc for this realm. If the optional port is absent, the
+default value for the
+.Dq kerberos/udp
+service will be used.
+.It Li v4_instance_convert
+.It Li v4_name_convert
+.It Li default_domain
+See
+.Xr krb5_425_conv_principal 3 .
+.El
+.It Li }
+.El
+.It Li [logging]
+.Bl -tag -width "xxx" -offset indent
+.It Va entity Li = Va destination
+Specifies that
+.Va entity
+should use the specified
+.Li destination
+for logging. See the
+.Xr krb5_openlog 3
+manual page for a list of defined destinations.
+.El
+.El
+.Sh EXAMPLE
+.Bd -literal -offset indent
+[lib_defaults]
+ default_domain = FOO.SE
+[domain_realm]
+ .foo.se = FOO.SE
+ .bar.se = FOO.SE
+[realms]
+ FOO.SE = {
+ kdc = kerberos.foo.se
+ v4_name_convert = {
+ rcmd = host
+ }
+ v4_instance_convert = {
+ xyz = xyz.bar.se
+ }
+ default_domain = foo.se
+ }
+[logging]
+ kdc = FILE:/var/heimdal/kdc.log
+ kdc = SYSLOG:INFO
+ default = SYSLOG:INFO:USER
+.Ed
+.Sh SEE ALSO
+.Xr krb5_openlog 3 ,
+.Xr krb5_425_conv_principal 3 ,
+.Xr strftime 3 ,
+.Xr Source tm
diff --git a/crypto/heimdal/lib/krb5/krb5.h b/crypto/heimdal/lib/krb5/krb5.h
new file mode 100644
index 000000000000..11cabc6575f6
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5.h
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: krb5.h,v 1.162 2000/01/02 00:19:24 assar Exp $ */
+
+#ifndef __KRB5_H__
+#define __KRB5_H__
+
+#include <time.h>
+#include <krb5-types.h>
+
+#include <des.h>
+#include <asn1_err.h>
+#include <krb5_err.h>
+#include <heim_err.h>
+
+#include <asn1.h>
+
+/* simple constants */
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+typedef int krb5_boolean;
+
+typedef int32_t krb5_error_code;
+
+typedef int krb5_kvno;
+
+typedef u_int32_t krb5_flags;
+
+typedef void *krb5_pointer;
+typedef const void *krb5_const_pointer;
+
+typedef octet_string krb5_data;
+
+struct krb5_crypto_data;
+typedef struct krb5_crypto_data *krb5_crypto;
+
+typedef enum krb5_cksumtype {
+ CKSUMTYPE_NONE = 0,
+ CKSUMTYPE_CRC32 = 1,
+ CKSUMTYPE_RSA_MD4 = 2,
+ CKSUMTYPE_RSA_MD4_DES = 3,
+ CKSUMTYPE_DES_MAC = 4,
+ CKSUMTYPE_DES_MAC_K = 5,
+ CKSUMTYPE_RSA_MD4_DES_K = 6,
+ CKSUMTYPE_RSA_MD5 = 7,
+ CKSUMTYPE_RSA_MD5_DES = 8,
+ CKSUMTYPE_RSA_MD5_DES3 = 9,
+/* CKSUMTYPE_SHA1 = 10,*/
+ CKSUMTYPE_HMAC_SHA1_DES3 = 12,
+ CKSUMTYPE_SHA1 = 1000, /* correct value? */
+ CKSUMTYPE_HMAC_MD5 = -138 /* unofficial microsoft number */
+} krb5_cksumtype;
+
+
+typedef enum krb5_enctype {
+ ETYPE_NULL = 0,
+ ETYPE_DES_CBC_CRC = 1,
+ ETYPE_DES_CBC_MD4 = 2,
+ ETYPE_DES_CBC_MD5 = 3,
+ ETYPE_DES3_CBC_MD5 = 5,
+ ETYPE_OLD_DES3_CBC_SHA1 = 7,
+ ETYPE_SIGN_DSA_GENERATE = 8,
+ ETYPE_ENCRYPT_RSA_PRIV = 9,
+ ETYPE_ENCRYPT_RSA_PUB = 10,
+ ETYPE_DES3_CBC_SHA1 = 16, /* with key derivation */
+ ETYPE_ARCFOUR_HMAC_MD5 = 23,
+ ETYPE_ARCFOUR_HMAC_MD5_56 = 24,
+ ETYPE_ENCTYPE_PK_CROSS = 48,
+ ETYPE_DES_CBC_NONE = 0x1000,
+ ETYPE_DES3_CBC_NONE = 0x1001
+} krb5_enctype;
+
+typedef enum krb5_preauthtype {
+ KRB5_PADATA_NONE = 0,
+ KRB5_PADATA_AP_REQ,
+ KRB5_PADATA_TGS_REQ = 1,
+ KRB5_PADATA_ENC_TIMESTAMP = 2,
+ KRB5_PADATA_ENC_SECURID
+} krb5_preauthtype;
+
+typedef enum krb5_key_usage {
+ KRB5_KU_PA_ENC_TIMESTAMP = 1,
+ /* AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
+ client key (section 5.4.1) */
+ KRB5_KU_TICKET = 2,
+ /* AS-REP Ticket and TGS-REP Ticket (includes tgs session key or
+ application session key), encrypted with the service key
+ (section 5.4.2) */
+ KRB5_KU_AS_REP_ENC_PART = 3,
+ /* AS-REP encrypted part (includes tgs session key or application
+ session key), encrypted with the client key (section 5.4.2) */
+ KRB5_KU_TGS_REQ_AUTH_DAT_SESSION = 4,
+ /* TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ session key (section 5.4.1) */
+ KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY = 5,
+ /* TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ authenticator subkey (section 5.4.1) */
+ KRB5_KU_TGS_REQ_AUTH_CKSUM = 6,
+ /* TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
+ with the tgs session key (sections 5.3.2, 5.4.1) */
+ KRB5_KU_TGS_REQ_AUTH = 7,
+ /* TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes tgs
+ authenticator subkey), encrypted with the tgs session key
+ (section 5.3.2) */
+ KRB5_KU_TGS_REP_ENC_PART_SESSION = 8,
+ /* TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs session key (section 5.4.2) */
+ KRB5_KU_TGS_REP_ENC_PART_SUB_KEY = 9,
+ /* TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs authenticator subkey (section 5.4.2) */
+ KRB5_KU_AP_REQ_AUTH_CKSUM = 10,
+ /* AP-REQ Authenticator cksum, keyed with the application session
+ key (section 5.3.2) */
+ KRB5_KU_AP_REQ_AUTH = 11,
+ /* AP-REQ Authenticator (includes application authenticator
+ subkey), encrypted with the application session key (section
+ 5.3.2) */
+ KRB5_KU_AP_REQ_ENC_PART = 12,
+ /* AP-REP encrypted part (includes application session subkey),
+ encrypted with the application session key (section 5.5.2) */
+ KRB5_KU_KRB_PRIV = 13,
+ /* KRB-PRIV encrypted part, encrypted with a key chosen by the
+ application (section 5.7.1) */
+ KRB5_KU_KRB_CRED = 14,
+ /* KRB-CRED encrypted part, encrypted with a key chosen by the
+ application (section 5.8.1) */
+ KRB5_KU_KRB_SAFE_CKSUM = 15,
+ /* KRB-SAFE cksum, keyed with a key chosen by the application
+ (section 5.6.1) */
+ KRB5_KU_OTHER_ENCRYPTED = 16,
+ /* Data which is defined in some specification outside of
+ Kerberos to be encrypted using an RFC1510 encryption type. */
+ KRB5_KU_OTHER_CKSUM = 17
+ /* Data which is defined in some specification outside of
+ Kerberos to be checksummed using an RFC1510 checksum type. */
+} krb5_key_usage;
+
+typedef enum krb5_salttype {
+ KRB5_PW_SALT = pa_pw_salt,
+ KRB5_AFS3_SALT = pa_afs3_salt
+}krb5_salttype;
+
+typedef struct krb5_salt {
+ krb5_salttype salttype;
+ krb5_data saltvalue;
+} krb5_salt;
+
+typedef ETYPE_INFO krb5_preauthinfo;
+
+typedef struct {
+ krb5_preauthtype type;
+ krb5_preauthinfo info; /* list of preauthinfo for this type */
+} krb5_preauthdata_entry;
+
+typedef struct krb5_preauthdata {
+ unsigned len;
+ krb5_preauthdata_entry *val;
+}krb5_preauthdata;
+
+typedef enum krb5_address_type {
+ KRB5_ADDRESS_INET = 2,
+ KRB5_ADDRESS_INET6 = 24,
+ KRB5_ADDRESS_ADDRPORT = 256,
+ KRB5_ADDRESS_IPPORT = 257
+} krb5_address_type;
+
+enum {
+ AP_OPTS_USE_SESSION_KEY = 1,
+ AP_OPTS_MUTUAL_REQUIRED = 2
+};
+
+typedef HostAddress krb5_address;
+
+typedef HostAddresses krb5_addresses;
+
+typedef enum krb5_keytype {
+ KEYTYPE_NULL = 0,
+ KEYTYPE_DES = 1,
+ KEYTYPE_DES3 = 7,
+ KEYTYPE_ARCFOUR = 23
+} krb5_keytype;
+
+typedef EncryptionKey krb5_keyblock;
+
+typedef AP_REQ krb5_ap_req;
+
+struct krb5_cc_ops;
+
+#define KRB5_DEFAULT_CCROOT "FILE:/tmp/krb5cc_"
+
+typedef void *krb5_cc_cursor;
+
+typedef struct krb5_ccache_data {
+ const struct krb5_cc_ops *ops;
+ krb5_data data;
+}krb5_ccache_data;
+
+typedef struct krb5_ccache_data *krb5_ccache;
+
+typedef struct krb5_context_data *krb5_context;
+
+typedef Realm krb5_realm;
+typedef const char *krb5_const_realm; /* stupid language */
+typedef Principal krb5_principal_data;
+typedef struct Principal *krb5_principal;
+typedef const struct Principal *krb5_const_principal;
+
+typedef time_t krb5_deltat;
+typedef time_t krb5_timestamp;
+
+typedef struct krb5_times {
+ krb5_timestamp authtime;
+ krb5_timestamp starttime;
+ krb5_timestamp endtime;
+ krb5_timestamp renew_till;
+} krb5_times;
+
+typedef union {
+ TicketFlags b;
+ krb5_flags i;
+} krb5_ticket_flags;
+
+/* options for krb5_get_in_tkt() */
+#define KDC_OPT_FORWARDABLE (1 << 1)
+#define KDC_OPT_FORWARDED (1 << 2)
+#define KDC_OPT_PROXIABLE (1 << 3)
+#define KDC_OPT_PROXY (1 << 4)
+#define KDC_OPT_ALLOW_POSTDATE (1 << 5)
+#define KDC_OPT_POSTDATED (1 << 6)
+#define KDC_OPT_RENEWABLE (1 << 8)
+#define KDC_OPT_REQUEST_ANONYMOUS (1 << 14)
+#define KDC_OPT_DISABLE_TRANSITED_CHECK (1 << 26)
+#define KDC_OPT_RENEWABLE_OK (1 << 27)
+#define KDC_OPT_ENC_TKT_IN_SKEY (1 << 28)
+#define KDC_OPT_RENEW (1 << 30)
+#define KDC_OPT_VALIDATE (1 << 31)
+
+typedef union {
+ KDCOptions b;
+ krb5_flags i;
+} krb5_kdc_flags;
+
+/* flags for krb5_verify_ap_req */
+
+#define KRB5_VERIFY_AP_REQ_IGNORE_INVALID (1 << 0)
+
+#define KRB5_GC_CACHED 1
+#define KRB5_GC_USER_USER 2
+
+/* constants for compare_creds (and cc_retrieve_cred) */
+#define KRB5_TC_DONT_MATCH_REALM (1U << 31)
+#define KRB5_TC_MATCH_KEYTYPE (1U << 30)
+
+typedef AuthorizationData krb5_authdata;
+
+typedef KRB_ERROR krb5_error;
+
+typedef struct krb5_creds {
+ krb5_principal client;
+ krb5_principal server;
+ krb5_keyblock session;
+ krb5_times times;
+ krb5_data ticket;
+ krb5_data second_ticket;
+ krb5_authdata authdata;
+ krb5_addresses addresses;
+ krb5_ticket_flags flags;
+} krb5_creds;
+
+typedef struct krb5_cc_ops {
+ char *prefix;
+ char* (*get_name)(krb5_context, krb5_ccache);
+ krb5_error_code (*resolve)(krb5_context, krb5_ccache *, const char *);
+ krb5_error_code (*gen_new)(krb5_context, krb5_ccache *);
+ krb5_error_code (*init)(krb5_context, krb5_ccache, krb5_principal);
+ krb5_error_code (*destroy)(krb5_context, krb5_ccache);
+ krb5_error_code (*close)(krb5_context, krb5_ccache);
+ krb5_error_code (*store)(krb5_context, krb5_ccache, krb5_creds*);
+ krb5_error_code (*retrieve)(krb5_context, krb5_ccache,
+ krb5_flags, krb5_creds*, krb5_creds);
+ krb5_error_code (*get_princ)(krb5_context, krb5_ccache, krb5_principal*);
+ krb5_error_code (*get_first)(krb5_context, krb5_ccache, krb5_cc_cursor *);
+ krb5_error_code (*get_next)(krb5_context, krb5_ccache,
+ krb5_cc_cursor*, krb5_creds*);
+ krb5_error_code (*end_get)(krb5_context, krb5_ccache, krb5_cc_cursor*);
+ krb5_error_code (*remove_cred)(krb5_context, krb5_ccache,
+ krb5_flags, krb5_creds*);
+ krb5_error_code (*set_flags)(krb5_context, krb5_ccache, krb5_flags);
+ int (*get_version)(krb5_context, krb5_ccache);
+} krb5_cc_ops;
+
+struct krb5_log_facility;
+
+struct krb5_config_binding {
+ enum { krb5_config_string, krb5_config_list } type;
+ char *name;
+ struct krb5_config_binding *next;
+ union {
+ char *string;
+ struct krb5_config_binding *list;
+ void *generic;
+ } u;
+};
+
+typedef struct krb5_config_binding krb5_config_binding;
+
+typedef krb5_config_binding krb5_config_section;
+
+typedef struct krb5_context_data {
+ krb5_enctype *etypes;
+ krb5_enctype *etypes_des;
+ char **default_realms;
+ time_t max_skew;
+ time_t kdc_timeout;
+ unsigned max_retries;
+ int32_t kdc_sec_offset;
+ int32_t kdc_usec_offset;
+ krb5_config_section *cf;
+ struct et_list *et_list;
+ struct krb5_log_facility *warn_dest;
+ krb5_cc_ops *cc_ops;
+ int num_cc_ops;
+ const char *http_proxy;
+ const char *time_fmt;
+ krb5_boolean log_utc;
+ const char *default_keytab;
+ krb5_boolean use_admin_kdc;
+ krb5_addresses *extra_addresses;
+ krb5_boolean scan_interfaces; /* `ifconfig -a' */
+ krb5_boolean srv_lookup; /* do SRV lookups */
+ krb5_boolean srv_try_txt; /* try TXT records also */
+ krb5_boolean srv_try_rfc2052; /* try RFC2052 compatible records */
+ int32_t fcache_vno; /* create cache files w/ this
+ version */
+ int num_kt_types; /* # of registered keytab types */
+ struct krb5_keytab_data *kt_types; /* registered keytab types */
+} krb5_context_data;
+
+enum {
+ KRB5_NT_UNKNOWN = 0,
+ KRB5_NT_PRINCIPAL = 1,
+ KRB5_NT_SRV_INST = 2,
+ KRB5_NT_SRV_HST = 3,
+ KRB5_NT_SRV_XHST = 4,
+ KRB5_NT_UID = 5
+};
+
+
+typedef struct krb5_ticket {
+ EncTicketPart ticket;
+ krb5_principal client;
+ krb5_principal server;
+} krb5_ticket;
+
+typedef Authenticator krb5_authenticator_data;
+
+typedef krb5_authenticator_data *krb5_authenticator;
+
+struct krb5_rcache_data;
+typedef struct krb5_rcache_data *krb5_rcache;
+typedef Authenticator krb5_donot_reply;
+
+#define KRB5_STORAGE_HOST_BYTEORDER 0x01
+#define KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS 0x02
+#define KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE 0x04
+#define KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE 0x08
+
+typedef struct krb5_storage {
+ void *data;
+ ssize_t (*fetch)(struct krb5_storage*, void*, size_t);
+ ssize_t (*store)(struct krb5_storage*, void*, size_t);
+ off_t (*seek)(struct krb5_storage*, off_t, int);
+ void (*free)(struct krb5_storage*);
+ krb5_flags flags;
+} krb5_storage;
+
+typedef struct krb5_keytab_entry {
+ krb5_principal principal;
+ krb5_kvno vno;
+ krb5_keyblock keyblock;
+ u_int32_t timestamp;
+} krb5_keytab_entry;
+
+typedef struct krb5_kt_cursor {
+ int fd;
+ krb5_storage *sp;
+ void *data;
+} krb5_kt_cursor;
+
+struct krb5_keytab_data;
+
+typedef struct krb5_keytab_data *krb5_keytab;
+
+struct krb5_keytab_data {
+ char *prefix;
+ krb5_error_code (*resolve)(krb5_context, const char*, krb5_keytab);
+ krb5_error_code (*get_name)(krb5_context, krb5_keytab, char*, size_t);
+ krb5_error_code (*close)(krb5_context, krb5_keytab);
+ krb5_error_code (*get)(krb5_context, krb5_keytab, krb5_const_principal,
+ krb5_kvno, krb5_enctype, krb5_keytab_entry*);
+ krb5_error_code (*start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
+ krb5_error_code (*next_entry)(krb5_context, krb5_keytab,
+ krb5_keytab_entry*, krb5_kt_cursor*);
+ krb5_error_code (*end_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
+ krb5_error_code (*add)(krb5_context, krb5_keytab, krb5_keytab_entry*);
+ krb5_error_code (*remove)(krb5_context, krb5_keytab, krb5_keytab_entry*);
+ void *data;
+ int32_t version;
+};
+
+typedef struct krb5_keytab_data krb5_kt_ops;
+
+struct krb5_keytab_key_proc_args {
+ krb5_keytab keytab;
+ krb5_principal principal;
+};
+
+typedef struct krb5_keytab_key_proc_args krb5_keytab_key_proc_args;
+
+enum {
+ KRB5_AUTH_CONTEXT_DO_TIME = 1,
+ KRB5_AUTH_CONTEXT_RET_TIME = 2,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE = 4,
+ KRB5_AUTH_CONTEXT_RET_SEQUENCE = 8
+};
+
+typedef struct krb5_auth_context_data {
+ unsigned int flags;
+
+ krb5_address *local_address;
+ krb5_address *remote_address;
+ int16_t local_port;
+ int16_t remote_port;
+ krb5_keyblock *keyblock;
+ krb5_keyblock *local_subkey;
+ krb5_keyblock *remote_subkey;
+
+ int32_t local_seqnumber;
+ int32_t remote_seqnumber;
+
+ krb5_authenticator authenticator;
+
+ krb5_pointer i_vector;
+
+ krb5_rcache rcache;
+
+ krb5_keytype keytype; /* ¿requested key type ? */
+ krb5_cksumtype cksumtype; /* ¡requested checksum type! */
+
+}krb5_auth_context_data, *krb5_auth_context;
+
+typedef struct {
+ KDC_REP kdc_rep;
+ EncKDCRepPart enc_part;
+ KRB_ERROR error;
+} krb5_kdc_rep;
+
+extern char *heimdal_version, *heimdal_long_version;
+
+typedef void (*krb5_log_log_func_t)(const char*, const char*, void*);
+typedef void (*krb5_log_close_func_t)(void*);
+
+typedef struct krb5_log_facility {
+ const char *program;
+ int len;
+ struct facility *val;
+} krb5_log_facility;
+
+typedef EncAPRepPart krb5_ap_rep_enc_part;
+
+#define KRB5_RECVAUTH_IGNORE_VERSION 1
+
+#define KRB5_SENDAUTH_VERSION "KRB5_SENDAUTH_V1.0"
+
+#define KRB5_TGS_NAME_SIZE (6)
+#define KRB5_TGS_NAME ("krbtgt")
+
+/* variables */
+
+extern const char krb5_config_file[];
+extern const char krb5_defkeyname[];
+
+typedef struct _krb5_prompt {
+ char *prompt;
+ int hidden;
+ krb5_data *reply;
+} krb5_prompt;
+
+typedef int (*krb5_prompter_fct)(krb5_context context,
+ void *data,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[]);
+
+typedef krb5_error_code (*krb5_key_proc)(krb5_context context,
+ krb5_enctype type,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key);
+typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context,
+ krb5_keyblock *key,
+ krb5_key_usage usage,
+ krb5_const_pointer decrypt_arg,
+ krb5_kdc_rep *dec_rep);
+
+
+typedef struct _krb5_get_init_creds_opt {
+ krb5_flags flags;
+ krb5_deltat tkt_life;
+ krb5_deltat renew_life;
+ int forwardable;
+ int proxiable;
+ krb5_enctype *etype_list;
+ int etype_list_length;
+ krb5_addresses *address_list;
+#if 0 /* this is the MIT-way */
+ krb5_address **address_list;
+#endif
+ /* XXX the next three should not be used, as they may be
+ removed later */
+ krb5_preauthtype *preauth_list;
+ int preauth_list_length;
+ krb5_data *salt;
+} krb5_get_init_creds_opt;
+
+#define KRB5_GET_INIT_CREDS_OPT_TKT_LIFE 0x0001
+#define KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE 0x0002
+#define KRB5_GET_INIT_CREDS_OPT_FORWARDABLE 0x0004
+#define KRB5_GET_INIT_CREDS_OPT_PROXIABLE 0x0008
+#define KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST 0x0010
+#define KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST 0x0020
+#define KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST 0x0040
+#define KRB5_GET_INIT_CREDS_OPT_SALT 0x0080
+
+typedef struct _krb5_verify_init_creds_opt {
+ krb5_flags flags;
+ int ap_req_nofail;
+} krb5_verify_init_creds_opt;
+
+#define KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL 0x0001
+
+extern const krb5_cc_ops krb5_fcc_ops;
+extern const krb5_cc_ops krb5_mcc_ops;
+
+extern const krb5_kt_ops krb5_fkt_ops;
+extern const krb5_kt_ops krb5_mkt_ops;
+extern const krb5_kt_ops krb5_akf_ops;
+
+#define KRB5_KPASSWD_SUCCESS 0
+#define KRB5_KPASSWD_MALFORMED 0
+#define KRB5_KPASSWD_HARDERROR 0
+#define KRB5_KPASSWD_AUTHERROR 0
+#define KRB5_KPASSWD_SOFTERROR 0
+
+#define KPASSWD_PORT 464
+
+struct credentials; /* this is to keep the compiler happy */
+struct getargs;
+
+struct sockaddr;
+
+#include <krb5-protos.h>
+
+#endif /* __KRB5_H__ */
+
diff --git a/crypto/heimdal/lib/krb5/krb5_425_conv_principal.3 b/crypto/heimdal/lib/krb5/krb5_425_conv_principal.3
new file mode 100644
index 000000000000..231c3ff15e73
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_425_conv_principal.3
@@ -0,0 +1,198 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_425_conv_principal.3,v 1.3 1999/04/11 01:47:22 joda Exp $
+.Dd April 11, 1999
+.Dt KRB5_425_CONV_PRINCIPAL 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_425_conv_principal ,
+.Nm krb5_425_conv_principal_ext ,
+.Nm krb5_524_conv_principal
+.Nd Converts to and from version 4 principals
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_425_conv_principal "krb5_context context" "const char *name" "const char *instance" "const char *realm" "krb5_principal *principal"
+
+.Ft krb5_error_code
+.Fn krb5_425_conv_principal_ext "krb5_context context" "const char *name" "const char *instance" "const char *realm" "krb5_boolean (*func)(krb5_context, krb5_principal)" "krb5_boolean resolve" "krb5_principal *principal"
+
+.Ft krb5_error_code
+.Fn krb5_524_conv_principal "krb5_context context" "const krb5_principal principal" "char *name" "char *instance" "char *realm"
+
+.Sh DESCRIPTION
+
+Converting between version 4 and version 5 principals can at best be
+described as a mess.
+.Pp
+A version 4 principal consists of a name, an instance, and a realm. A
+version 5 principal consists of one or more components, and a
+realm. In some cases also the first component/name will differ between
+version 4 and version 5. Furthermore the second component of a host
+principal will be the fully qualified domain name of the host in
+question, while the instance of a version 4 principal will only
+contain the first component. Because of these problems the conversion
+between principals will have to be site customized.
+.Pp
+.Fn krb5_425_conv_principal_ext
+will try to convert a version 4 principal, given by
+.Fa name ,
+.Fa instance ,
+and
+.Fa realm ,
+to a version 5 principal. This can result in several possible
+principals, and if
+.Fa func
+is non-NULL, it will be called for each candidate principal.
+.Fa func
+should return true if the principal was
+.Dq good .
+To accomplish this,
+.Fn krb5_425_conv_principal_ext
+will look up the name in
+.Pa krb5.conf .
+It first looks in the
+.Li v4_name_convert/host
+subsection, which should contain a list of version 4 names whose
+instance should be treated as a hostname. This list can be specified
+for each realm (in the
+.Li realms
+section), or in the
+.Li libdefaults
+section. If the name is found the resulting name of the principal
+will be the value of this binding. The instance is then first looked
+up in
+.Li v4_instance_convert
+for the specified realm. If found the resulting value will be used as
+instance (this can be used for special cases), no further attempts
+will be made to find a conversion if this fails (with
+.Fa func ) .
+If the
+.Fa resolve
+parameter is true, the instance will be looked up with
+.Fn gethostbyname .
+This can be a time consuming, error prone, and unsafe operation. Next
+a list of hostnames will be created from the instance and the
+.Li v4_domains
+variable, which should contain a list of possible domains for the
+specific realm.
+.Pp
+On the other hand, if the name is not found in a
+.Li host
+section, it is looked up in a
+.Li v4_name_convert/plain
+binding. If found here the name will be converted, but the instance
+will be untouched.
+.Pp
+This list of default host-type conversions is compiled-in:
+.Bd -literal -offset indent
+v4_name_convert = {
+ host = {
+ ftp = ftp
+ hprop = hprop
+ pop = pop
+ rcmd = host
+ }
+}
+.Ed
+.Pp
+It will only be used if there isn't an entry for these names in the
+config file, so you can override these defaults.
+.Pp
+.Fn krb5_425_conv_principal
+will call
+.Fn krb5_425_conv_principal_ext
+with
+.Dv NULL
+as
+.Fa func ,
+and the value of
+.Li v4_instance_resolve
+(from the
+.Li libdefaults
+section) as
+.Fa resolve .
+.Pp
+.Fn krb5_524_conv_principal
+basically does the opposite of
+.Fn krb5_425_conv_principal ,
+it just doesn't have to look up any names, but will instead truncate
+instances found to belong to a host principal. The
+.Fa name ,
+.Fa instance ,
+and
+.Fa realm
+should be at least 40 characters long.
+
+.Sh EXAMPLES
+
+Since this is confusing an example is in place.
+.Pp
+Assume that we have the
+.Dq foo.com ,
+and
+.Dq bar.com
+domains that have shared a single version 4 realm, FOO.COM. The version 4
+.Pa krb.realms
+file looked like:
+.Bd -literal -offset indent
+foo.com FOO.COM
+\&.foo.com FOO.COM
+\&.bar.com FOO.COM
+.Ed
+.Pp
+A
+.Pa krb5.conf
+file that covers this case might look like:
+.Bd -literal -offset indent
+[libdefaults]
+ v4_instance_resolve = yes
+[realms]
+ FOO.COM = {
+ kdc = kerberos.foo.com
+ v4_instance_convert = {
+ foo = foo.com
+ }
+ v4_domains = foo.com
+ }
+.Ed
+.Pp
+With this setup and the following host table:
+.Bd -literal -offset indent
+foo.com
+a-host.foo.com
+b-host.bar.com
+.Ed
+the following conversions will be made:
+.Bd -literal -offset indent
+rcmd.a-host \(-> host/a-host.foo.com
+ftp.b-host \(-> ftp/b-host.bar.com
+pop.foo \(-> pop/foo.com
+ftp.other \(-> ftp/other.foo.com
+other.a-host \(-> other/a-host
+.Ed
+.Pp
+The first three are what you expect. If you remove the
+.Dq v4_domains ,
+the fourth entry will result in an error (since the host
+.Dq other
+can't be found). Even if
+.Dq a-host
+is a valid host name, the last entry will not be converted, since the
+.Dq other
+name is not known to represent a host-type principal.
+If you turn off
+.Dq v4_instance_resolve
+the second example will result in
+.Dq ftp/b-host.foo.com
+(because of the default domain). And all of this is of course only
+valid if you have working name resolving.
+
+.Sh SEE ALSO
+.Xr krb5_build_principal 3 ,
+.Xr krb5_free_principal 3 ,
+.Xr krb5_parse_name 3 ,
+.Xr krb5_sname_to_principal 3 ,
+.Xr krb5_unparse_name 3 ,
+.Xr krb5.conf 5
diff --git a/crypto/heimdal/lib/krb5/krb5_build_principal.3 b/crypto/heimdal/lib/krb5/krb5_build_principal.3
new file mode 100644
index 000000000000..16ccf72ace3a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_build_principal.3
@@ -0,0 +1,78 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_build_principal.3,v 1.1 1997/08/14 00:03:16 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_BUILD_PRINCIPAL 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_build_principal ,
+.Nm krb5_build_principal_ext ,
+.Nm krb5_build_principal_va ,
+.Nm krb5_build_principal_va_ext ,
+.Nm krb5_make_principal
+.Nd Principal creation functions
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_build_principal "krb5_context context" "krb5_principal *principal" "int realm_len" "krb5_const_realm realm" "..."
+
+.Ft krb5_error_code
+.Fn krb5_build_principal_ext "krb5_context context" "krb5_principal *principal" "int realm_len" "krb5_const_realm realm" "..."
+
+.Ft krb5_error_code
+.Fn krb5_build_principal_va "krb5_context context" "krb5_principal *principal" "int realm_len" "krb5_const_realm realm" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_build_principal_va_ext "krb5_context context" "krb5_principal *principal" "int realm_len" "krb5_const_realm realm" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_make_principal "krb5_context context" "krb5_principal *principal" "krb5_const_realm realm" "..."
+
+
+.Sh DESCRIPTION
+
+These functions create a Kerberos 5 principal from a realm and a list
+of components.
+All of these functions return an allocated principal in the
+.Fa principal
+parameter, this should be freed with
+.Fn krb5_free_principal
+after use.
+.Pp
+The
+.Dq build
+functions take a
+.Fa realm
+and the length of the realm. The
+.Fn krb5_build_principal
+and
+.Fn krb5_build_principal_va
+also takes a list of components (zero-terminated strings), terminated
+with
+.Dv NULL .
+The
+.Fn krb5_build_principal_ext
+and
+.Fn krb5_build_principal_va_ext
+takes a list of length-value pairs, the list is terminated with a zero
+length.
+.Pp
+The
+.Fn krb5_make_principal
+is a wrapper around
+.Fn krb5_build_principal .
+If the realm is
+.Dv NULL ,
+the default realm will be used.
+
+.Sh BUGS
+You can not have a NUL in a component. Until someone can give a good
+example of where it would be a good idea to have NUL's in a component,
+this will not be fixed.
+.Sh SEE ALSO
+.Xr krb5_425_conv_principal 3 ,
+.Xr krb5_free_principal 3 ,
+.Xr krb5_parse_name 3 ,
+.Xr krb5_sname_to_principal 3 ,
+.Xr krb5_unparse_name 3
diff --git a/crypto/heimdal/lib/krb5/krb5_create_checksum.3 b/crypto/heimdal/lib/krb5/krb5_create_checksum.3
new file mode 100644
index 000000000000..e2362a98acb9
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_create_checksum.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1999 Kungliga Tekniska Högskolan
+.\" $Id: krb5_create_checksum.3,v 1.1 1999/04/18 13:47:11 joda Exp $
+.Dd April 7, 1999
+.Dt NAME 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_checksum_is_collision_proof ,
+.Nm krb5_checksum_is_keyed ,
+.Nm krb5_checksumsize ,
+.Nm krb5_create_checksum ,
+.Nm krb5_verify_checksum
+.Nd creates and verifies checksums
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_create_checksum "krb5_context context" "krb5_crypto crypto" "unsigned usage_or_type" "void *data" "size_t len" "Checksum *result"
+
+.Ft krb5_error_code
+.Fn krb5_verify_checksum "krb5_context context" "krb5_crypto crypto" "krb5_key_usage usage" "void *data" "size_t len" "Checksum *cksum"
+
+.Ft krb5_boolean
+.Fn krb5_checksum_is_collision_proof "krb5_context context" "krb5_cksumtype type"
+
+.Ft krb5_boolean
+.Fn krb5_checksum_is_keyed "krb5_context context" "krb5_cksumtype type"
+
+.Sh DESCRIPTION
+These functions are used to create and verify checksums.
+.Fn krb5_create_checksum
+creates a checksum of the specified data, and puts it in
+.Fa result .
+If
+.Fa crypto
+is
+.Dv NULL ,
+.Fa usage_or_type
+specifies the checksum type to use; it must not be keyed. Otherwise
+.Fa crypto
+is an encryption context created by
+.Fn krb5_crypto_init ,
+and
+.Fa usage_or_type
+specifies a key-usage.
+.Pp
+.Fn krb5_verify_checksum
+verifies the
+.Fa checksum ,
+against the provided data.
+.Pp
+.Fn krb5_checksum_is_collision_proof
+returns true is the specified checksum is collision proof (that it's
+very unlikely that two strings has the same hash value, and that it's
+hard to find two strings that has the same hash). Examples of
+collision proof checksums are MD5, and SHA1, while CRC32 is not.
+.Pp
+.Fn krb5_checksum_is_keyed
+returns true if the specified checksum type is keyed (that the hash
+value is a function of both the data, and a separate key). Examples of
+keyed hash algorithms are HMAC-SHA1-DES3, and RSA-MD5-DES. The
+.Dq plain
+hash functions MD5, and SHA1 are not keyed.
+
+.\" .Sh EXAMPLE
+.\" .Sh BUGS
+.Sh SEE ALSO
+.Xr krb5_crypto_init 3 ,
+.Xr krb5_encrypt 3
diff --git a/crypto/heimdal/lib/krb5/krb5_crypto_init.3 b/crypto/heimdal/lib/krb5/krb5_crypto_init.3
new file mode 100644
index 000000000000..29db8c1e59e8
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_crypto_init.3
@@ -0,0 +1,41 @@
+.\" Copyright (c) 1999 Kungliga Tekniska Högskolan
+.\" $Id: krb5_crypto_init.3,v 1.1 1999/04/18 13:47:21 joda Exp $
+.Dd April 7, 1999
+.Dt NAME 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_crypto_init ,
+.Nm krb5_crypto_destroy
+.Nd initialize encryption context
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_crypto_init "krb5_context context" "krb5_keyblock *key" "krb5_enctype enctype" "krb5_crypto *crypto"
+
+.Ft krb5_error_code
+.Fn krb5_crypto_destroy "krb5_context context" "krb5_crypto crypto"
+
+.Sh DESCRIPTION
+These functions are used to initialize an encryption context that can
+be used to encrypt or checksum data.
+.Pp
+The
+.Fn krb5_crypt_init
+initializes the encrytion context
+.Fa crypto .
+The
+.Fa key
+parameter is the key to use for encryption, and checksums. The
+encryption type to use is taken from the key, but can be overridden
+with the
+.Fa enctype parameter .
+.Pp
+.Fn krb5_crypto_destroy
+frees a previously allocated encrypion context.
+
+.\" .Sh EXAMPLE
+.\" .Sh BUGS
+.Sh SEE ALSO
+.Xr krb5_create_checksum 3 ,
+.Xr krb5_encrypt 3
diff --git a/crypto/heimdal/lib/krb5/krb5_encrypt.3 b/crypto/heimdal/lib/krb5/krb5_encrypt.3
new file mode 100644
index 000000000000..d8cc89eee3d2
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_encrypt.3
@@ -0,0 +1,60 @@
+.\" Copyright (c) 1999 Kungliga Tekniska Högskolan
+.\" $Id: krb5_encrypt.3,v 1.1 1999/04/18 13:47:30 joda Exp $
+.Dd April 7, 1999
+.Dt KRB5_ENCRYPT 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_decrypt ,
+.Nm krb5_decrypt_EncryptedData ,
+.Nm krb5_encrypt ,
+.Nm krb5_encrypt_EncryptedData
+.Nd encrypt and decrypt data
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_encrypt "krb5_context context" "krb5_crypto crypto" "unsigned usage" "void *data" "size_t len" "krb5_data *result"
+
+.Ft krb5_error_code
+.Fn krb5_encrypt_EncryptedData "krb5_context context" "krb5_crypto crypto" "unsigned usage" "void *data" "size_t len" "int kvno" "EncryptedData *result"
+
+.Ft krb5_error_code
+.Fn krb5_decrypt "krb5_context context" "krb5_crypto crypto" "unsigned usage" "void *data" "size_t len" "krb5_data *result"
+
+.Ft krb5_error_code
+.Fn krb5_decrypt_EncryptedData "krb5_context context" "krb5_crypto crypto" "unsigned usage" "EncryptedData *e" "krb5_data *result"
+
+.Sh DESCRIPTION
+These functions are used to encrypt and decrypt data.
+.Pp
+.Fn krb5_encrypt
+puts the encrypted version of
+.Fa data
+(of size
+.Fa len )
+in
+.Fa result .
+If the encryption type supports using derived keys,
+.Fa usage
+should be the appropriate key-usage.
+.Fn krb5_encrypt_EncryptedData
+does the same as
+.Fn krb5_encrypt ,
+but it puts the encrypted data in a
+.Fa EncryptedData
+structure instead. If
+.Fa kvno
+is not zero, it will be put in the
+.Fa kvno field in the
+.Fa EncryptedData .
+.Pp
+.Fn krb5_decrypt ,
+and
+.Fn krb5_decrypt_EncryptedData
+works similarly.
+
+.\" .Sh EXAMPLE
+.\" .Sh BUGS
+.Sh SEE ALSO
+.Xr krb5_crypto_init 3 ,
+.Xr krb5_create_checksum 3
diff --git a/crypto/heimdal/lib/krb5/krb5_err.et b/crypto/heimdal/lib/krb5/krb5_err.et
new file mode 100644
index 000000000000..e8779df82b27
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_err.et
@@ -0,0 +1,215 @@
+#
+# Error messages for the krb5 library
+#
+# This might look like a com_err file, but is not
+#
+id "$Id: krb5_err.et,v 1.7 1999/02/11 21:03:40 joda Exp $"
+
+error_table krb5
+
+prefix KRB5KDC_ERR
+error_code NONE, "No error"
+error_code NAME_EXP, "Client's entry in database has expired"
+error_code SERVICE_EXP, "Server's entry in database has expired"
+error_code BAD_PVNO, "Requested protocol version not supported"
+error_code C_OLD_MAST_KVNO, "Client's key is encrypted in an old master key"
+error_code S_OLD_MAST_KVNO, "Server's key is encrypted in an old master key"
+error_code C_PRINCIPAL_UNKNOWN, "Client not found in Kerberos database"
+error_code S_PRINCIPAL_UNKNOWN, "Server not found in Kerberos database"
+error_code PRINCIPAL_NOT_UNIQUE,"Principal has multiple entries in Kerberos database"
+error_code NULL_KEY, "Client or server has a null key"
+error_code CANNOT_POSTDATE, "Ticket is ineligible for postdating"
+error_code NEVER_VALID, "Requested effective lifetime is negative or too short"
+error_code POLICY, "KDC policy rejects request"
+error_code BADOPTION, "KDC can't fulfill requested option"
+error_code ETYPE_NOSUPP, "KDC has no support for encryption type"
+error_code SUMTYPE_NOSUPP, "KDC has no support for checksum type"
+error_code PADATA_TYPE_NOSUPP, "KDC has no support for padata type"
+error_code TRTYPE_NOSUPP, "KDC has no support for transited type"
+error_code CLIENT_REVOKED, "Clients credentials have been revoked"
+error_code SERVICE_REVOKED, "Credentials for server have been revoked"
+error_code TGT_REVOKED, "TGT has been revoked"
+error_code CLIENT_NOTYET, "Client not yet valid - try again later"
+error_code SERVICE_NOTYET, "Server not yet valid - try again later"
+error_code KEY_EXPIRED, "Password has expired"
+error_code PREAUTH_FAILED, "Preauthentication failed"
+error_code PREAUTH_REQUIRED, "Additional pre-authentication required"
+error_code SERVER_NOMATCH, "Requested server and ticket don't match"
+
+# 27-30 are reserved
+index 31
+prefix KRB5KRB_AP
+error_code ERR_BAD_INTEGRITY, "Decrypt integrity check failed"
+error_code ERR_TKT_EXPIRED, "Ticket expired"
+error_code ERR_TKT_NYV, "Ticket not yet valid"
+error_code ERR_REPEAT, "Request is a replay"
+error_code ERR_NOT_US, "The ticket isn't for us"
+error_code ERR_BADMATCH, "Ticket/authenticator don't match"
+error_code ERR_SKEW, "Clock skew too great"
+error_code ERR_BADADDR, "Incorrect net address"
+error_code ERR_BADVERSION, "Protocol version mismatch"
+error_code ERR_MSG_TYPE, "Invalid message type"
+error_code ERR_MODIFIED, "Message stream modified"
+error_code ERR_BADORDER, "Message out of order"
+error_code ERR_ILL_CR_TKT, "Illegal cross-realm ticket"
+error_code ERR_BADKEYVER, "Key version is not available"
+error_code ERR_NOKEY, "Service key not available"
+error_code ERR_MUT_FAIL, "Mutual authentication failed"
+error_code ERR_BADDIRECTION, "Incorrect message direction"
+error_code ERR_METHOD, "Alternative authentication method required"
+error_code ERR_BADSEQ, "Incorrect sequence number in message"
+error_code ERR_INAPP_CKSUM, "Inappropriate type of checksum in message"
+error_code PATH_NOT_ACCEPTED, "Policy rejects transited path"
+
+prefix KRB5KRB_ERR
+error_code RESPONSE_TOO_BIG, "Response too big for UDP, retry with TCP"
+# 53-59 are reserved
+index 60
+error_code GENERIC, "Generic error (see e-text)"
+error_code FIELD_TOOLONG, "Field is too long for this implementation"
+
+# 62-127 are reserved
+index 128
+prefix
+error_code KRB5_ERR_RCSID, "$Id: krb5_err.et,v 1.7 1999/02/11 21:03:40 joda Exp $"
+
+error_code KRB5_LIBOS_BADLOCKFLAG, "Invalid flag for file lock mode"
+error_code KRB5_LIBOS_CANTREADPWD, "Cannot read password"
+error_code KRB5_LIBOS_BADPWDMATCH, "Password mismatch"
+error_code KRB5_LIBOS_PWDINTR, "Password read interrupted"
+
+error_code KRB5_PARSE_ILLCHAR, "Illegal character in component name"
+error_code KRB5_PARSE_MALFORMED, "Malformed representation of principal"
+
+error_code KRB5_CONFIG_CANTOPEN, "Can't open/find configuration file"
+error_code KRB5_CONFIG_BADFORMAT, "Improper format of configuration file"
+error_code KRB5_CONFIG_NOTENUFSPACE, "Insufficient space to return complete information"
+
+error_code KRB5_BADMSGTYPE, "Invalid message type specified for encoding"
+
+error_code KRB5_CC_BADNAME, "Credential cache name malformed"
+error_code KRB5_CC_UNKNOWN_TYPE, "Unknown credential cache type"
+error_code KRB5_CC_NOTFOUND, "Matching credential not found"
+error_code KRB5_CC_END, "End of credential cache reached"
+
+error_code KRB5_NO_TKT_SUPPLIED, "Request did not supply a ticket"
+
+error_code KRB5KRB_AP_WRONG_PRINC, "Wrong principal in request"
+error_code KRB5KRB_AP_ERR_TKT_INVALID, "Ticket has invalid flag set"
+
+error_code KRB5_PRINC_NOMATCH, "Requested principal and ticket don't match"
+error_code KRB5_KDCREP_MODIFIED, "KDC reply did not match expectations"
+error_code KRB5_KDCREP_SKEW, "Clock skew too great in KDC reply"
+error_code KRB5_IN_TKT_REALM_MISMATCH, "Client/server realm mismatch in initial ticket request"
+
+error_code KRB5_PROG_ETYPE_NOSUPP, "Program lacks support for encryption type"
+error_code KRB5_PROG_KEYTYPE_NOSUPP, "Program lacks support for key type"
+error_code KRB5_WRONG_ETYPE, "Requested encryption type not used in message"
+error_code KRB5_PROG_SUMTYPE_NOSUPP, "Program lacks support for checksum type"
+
+error_code KRB5_REALM_UNKNOWN, "Cannot find KDC for requested realm"
+error_code KRB5_SERVICE_UNKNOWN, "Kerberos service unknown"
+error_code KRB5_KDC_UNREACH, "Cannot contact any KDC for requested realm"
+error_code KRB5_NO_LOCALNAME, "No local name found for principal name"
+
+error_code KRB5_MUTUAL_FAILED, "Mutual authentication failed"
+
+# some of these should be combined/supplanted by system codes
+
+error_code KRB5_RC_TYPE_EXISTS, "Replay cache type is already registered"
+error_code KRB5_RC_MALLOC, "No more memory to allocate (in replay cache code)"
+error_code KRB5_RC_TYPE_NOTFOUND, "Replay cache type is unknown"
+error_code KRB5_RC_UNKNOWN, "Generic unknown RC error"
+error_code KRB5_RC_REPLAY, "Message is a replay"
+error_code KRB5_RC_IO, "Replay I/O operation failed XXX"
+error_code KRB5_RC_NOIO, "Replay cache type does not support non-volatile storage"
+error_code KRB5_RC_PARSE, "Replay cache name parse/format error"
+
+error_code KRB5_RC_IO_EOF, "End-of-file on replay cache I/O"
+error_code KRB5_RC_IO_MALLOC, "No more memory to allocate (in replay cache I/O code)"
+error_code KRB5_RC_IO_PERM, "Permission denied in replay cache code"
+error_code KRB5_RC_IO_IO, "I/O error in replay cache i/o code"
+error_code KRB5_RC_IO_UNKNOWN, "Generic unknown RC/IO error"
+error_code KRB5_RC_IO_SPACE, "Insufficient system space to store replay information"
+
+error_code KRB5_TRANS_CANTOPEN, "Can't open/find realm translation file"
+error_code KRB5_TRANS_BADFORMAT, "Improper format of realm translation file"
+
+error_code KRB5_LNAME_CANTOPEN, "Can't open/find lname translation database"
+error_code KRB5_LNAME_NOTRANS, "No translation available for requested principal"
+error_code KRB5_LNAME_BADFORMAT, "Improper format of translation database entry"
+
+error_code KRB5_CRYPTO_INTERNAL, "Cryptosystem internal error"
+
+error_code KRB5_KT_BADNAME, "Key table name malformed"
+error_code KRB5_KT_UNKNOWN_TYPE, "Unknown Key table type"
+error_code KRB5_KT_NOTFOUND, "Key table entry not found"
+error_code KRB5_KT_END, "End of key table reached"
+error_code KRB5_KT_NOWRITE, "Cannot write to specified key table"
+error_code KRB5_KT_IOERR, "Error writing to key table"
+
+error_code KRB5_NO_TKT_IN_RLM, "Cannot find ticket for requested realm"
+error_code KRB5DES_BAD_KEYPAR, "DES key has bad parity"
+error_code KRB5DES_WEAK_KEY, "DES key is a weak key"
+
+error_code KRB5_BAD_ENCTYPE, "Bad encryption type"
+error_code KRB5_BAD_KEYSIZE, "Key size is incompatible with encryption type"
+error_code KRB5_BAD_MSIZE, "Message size is incompatible with encryption type"
+
+error_code KRB5_CC_TYPE_EXISTS, "Credentials cache type is already registered."
+error_code KRB5_KT_TYPE_EXISTS, "Key table type is already registered."
+
+error_code KRB5_CC_IO, "Credentials cache I/O operation failed XXX"
+error_code KRB5_FCC_PERM, "Credentials cache file permissions incorrect"
+error_code KRB5_FCC_NOFILE, "No credentials cache file found"
+error_code KRB5_FCC_INTERNAL, "Internal file credentials cache error"
+error_code KRB5_CC_WRITE, "Error writing to credentials cache file"
+error_code KRB5_CC_NOMEM, "No more memory to allocate (in credentials cache code)"
+error_code KRB5_CC_FORMAT, "Bad format in credentials cache"
+
+# errors for dual tgt library calls
+error_code KRB5_INVALID_FLAGS, "Invalid KDC option combination (library internal error)"
+error_code KRB5_NO_2ND_TKT, "Request missing second ticket"
+
+error_code KRB5_NOCREDS_SUPPLIED, "No credentials supplied to library routine"
+
+# errors for sendauth (and recvauth)
+
+error_code KRB5_SENDAUTH_BADAUTHVERS, "Bad sendauth version was sent"
+error_code KRB5_SENDAUTH_BADAPPLVERS, "Bad application version was sent (via sendauth)"
+error_code KRB5_SENDAUTH_BADRESPONSE, "Bad response (during sendauth exchange)"
+error_code KRB5_SENDAUTH_REJECTED, "Server rejected authentication (during sendauth exchange)"
+
+# errors for preauthentication
+
+error_code KRB5_PREAUTH_BAD_TYPE, "Unsupported preauthentication type"
+error_code KRB5_PREAUTH_NO_KEY, "Required preauthentication key not supplied"
+error_code KRB5_PREAUTH_FAILED, "Generic preauthentication failure"
+
+# version number errors
+
+error_code KRB5_RCACHE_BADVNO, "Unsupported replay cache format version number"
+error_code KRB5_CCACHE_BADVNO, "Unsupported credentials cache format version number"
+error_code KRB5_KEYTAB_BADVNO, "Unsupported key table format version number"
+
+#
+#
+
+error_code KRB5_PROG_ATYPE_NOSUPP, "Program lacks support for address type"
+error_code KRB5_RC_REQUIRED, "Message replay detection requires rcache parameter"
+error_code KRB5_ERR_BAD_HOSTNAME, "Hostname cannot be canonicalized"
+error_code KRB5_ERR_HOST_REALM_UNKNOWN, "Cannot determine realm for host"
+error_code KRB5_SNAME_UNSUPP_NAMETYPE, "Conversion to service principal undefined for name type"
+
+error_code KRB5KRB_AP_ERR_V4_REPLY, "Initial Ticket response appears to be Version 4"
+error_code KRB5_REALM_CANT_RESOLVE, "Cannot resolve KDC for requested realm"
+error_code KRB5_TKT_NOT_FORWARDABLE, "Requesting ticket can't get forwardable tickets"
+error_code KRB5_FWD_BAD_PRINCIPAL, "Bad principal name while trying to forward credentials"
+
+error_code KRB5_GET_IN_TKT_LOOP, "Looping detected inside krb5_get_in_tkt"
+error_code KRB5_CONFIG_NODEFREALM, "Configuration file does not specify default realm"
+
+error_code KRB5_SAM_UNSUPPORTED, "Bad SAM flags in obtain_sam_padata"
+error_code KRB5_KT_NAME_TOOLONG, "Keytab name too long"
+
+end
diff --git a/crypto/heimdal/lib/krb5/krb5_free_principal.3 b/crypto/heimdal/lib/krb5/krb5_free_principal.3
new file mode 100644
index 000000000000..ba5888af3d9a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_free_principal.3
@@ -0,0 +1,30 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_free_principal.3,v 1.1 1997/08/14 00:03:17 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_FREE_PRINCIPAL 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_free_principal
+.Nd Principal free function
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft void
+.Fn krb5_free_principal "krb5_context context" "krb5_principal principal"
+
+.Sh DESCRIPTION
+
+The
+.Fn krb5_free_principal
+will free a principal that has been created with
+.Fn krb5_build_principal ,
+.Fn krb5_parse_name ,
+or with some other function.
+
+.Sh SEE ALSO
+.Xr krb5_425_conv_principal 3 ,
+.Xr krb5_build_principal 3 ,
+.Xr krb5_parse_name 3 ,
+.Xr krb5_sname_to_principal 3 ,
+.Xr krb5_unparse_name 3
diff --git a/crypto/heimdal/lib/krb5/krb5_locl.h b/crypto/heimdal/lib/krb5/krb5_locl.h
new file mode 100644
index 000000000000..b7093b1b14d0
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_locl.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: krb5_locl.h,v 1.63 1999/12/02 17:05:11 joda Exp $ */
+
+#ifndef __KRB5_LOCL_H__
+#define __KRB5_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <time.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef _AIX
+struct ether_addr;
+struct mbuf;
+struct sockaddr_dl;
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+#include <roken.h>
+#include <parse_time.h>
+#include <base64.h>
+
+#include <des.h>
+#include <md4.h>
+#include <md5.h>
+#include <sha.h>
+#include <rc4.h>
+
+#include <asn1.h>
+#include <der.h>
+
+#include <krb5.h>
+#include <krb5_err.h>
+#include <asn1_err.h>
+#include <krb5-private.h>
+
+#define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
+#define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0)
+
+/* should this be public? */
+#define KEYTAB_DEFAULT "FILE:/etc/krb5.keytab"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#endif /* __KRB5_LOCL_H__ */
diff --git a/crypto/heimdal/lib/krb5/krb5_openlog.3 b/crypto/heimdal/lib/krb5/krb5_openlog.3
new file mode 100644
index 000000000000..87040ba89c91
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_openlog.3
@@ -0,0 +1,225 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_openlog.3,v 1.4 1999/04/07 14:06:32 joda Exp $
+.Dd August 6, 1997
+.Dt KRB5_OPENLOG 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_initlog ,
+.Nm krb5_openlog ,
+.Nm krb5_closelog ,
+.Nm krb5_addlog_dest ,
+.Nm krb5_addlog_func ,
+.Nm krb5_log ,
+.Nm krb5_vlog ,
+.Nm krb5_log_msg ,
+.Nm krb5_vlog_msg
+.Nd Heimdal logging functions
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.\" ouch!
+.ds xx \\*(fP\fR(\fP\\*(lI*\\*(fP
+.ds xy \fR)\|\fP
+.Fn "\\*(lItypedef void \\*(xxkrb5_log_log_func_t\\*(xy" "const char *time" "const char *message" "void *data"
+.Fn "\\*(lItypedef void \\*(xxkrb5_log_close_func_t\\*(xy" "void *data"
+
+.Ft krb5_error_code
+.Fn krb5_addlog_dest "krb5_context context" "krb5_log_facility *facility" "const char *destination"
+
+.Ft krb5_error_code
+.Fn krb5_addlog_func "krb5_context context" "krb5_log_facility *facility" "int min" "int max" "krb5_log_log_func_t log" "krb5_log_close_func_t close" "void *data"
+
+.Ft krb5_error_code
+.Fn krb5_closelog "krb5_context context" "krb5_log_facility *facility"
+
+.Ft krb5_error_code
+.Fn krb5_initlog "krb5_context context" "const char *program" "krb5_log_facility **facility"
+
+.Ft krb5_error_code
+.Fn krb5_log "krb5_context context" "krb5_log_facility *facility" "int level" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_log_msg "krb5_context context" "krb5_log_facility *facility" "char **reply" "int level" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_openlog "krb5_context context" "const char *program" "krb5_log_facility **facility"
+
+.Ft krb5_error_code
+.Fn krb5_vlog "krb5_context context" "krb5_log_facility *facility" "int level" "const char *format" "va_list arglist"
+
+.Ft krb5_error_code
+.Fn krb5_vlog_msg "krb5_context context" "krb5_log_facility *facility" "char **reply" "int level" "const char *format" "va_list arglist"
+
+.Sh DESCRIPTION
+These functions logs messages to one or more destinations.
+.Pp
+The
+.Fn krb5_openlog
+function creates a logging
+.Fa facility ,
+that is used to log messages. A facility consists of one or more
+destinations (which can be files or syslog or some other device). The
+.Fa program
+parameter should be the generic name of the program that is doing the
+logging. This name is used to lookup which destinations to use. This
+information is contained in the
+.Li logging
+section of the
+.Pa krb5.conf
+configuration file. If no entry is found for
+.Fa program ,
+the entry for
+.Li default
+is used, or if that is missing too,
+.Li SYSLOG
+will be used as destination.
+.Pp
+To close a logging facility, use the
+.Fn krb5_closelog
+function.
+.Pp
+To log a message to a facility use one of the functions
+.Fn krb5_log ,
+.Fn krb5_log_msg ,
+.Fn krb5_vlog ,
+or
+.Fn krb5_vlog_msg .
+The functions ending in
+.Li _msg
+return in
+.Fa reply
+a pointer to the message that just got logged. This string is allocated,
+and should be freed with
+.Fn free .
+The
+.Fa format
+is a standard
+.Fn printf
+style format string (but see the BUGS section).
+.Pp
+
+If you want better control of where things gets logged, you can instead of using
+.Fn krb5_openlog
+call
+.Fn krb5_initlog ,
+which just initializes a facility, but doesn't define any actual logging
+destinations. You can then add destinations with the
+.Fn krb5_addlog_dest
+and
+.Fn krb5_addlog_func
+functions. The first of these takes a string specifying a logging
+destination, and adds this to the facility. If you want to do some
+non-standard logging you can use the
+.Fn krb5_addlog_func
+function, which takes a function to use when logging.
+The
+.Fa log
+function is called for each message with
+.Fa time
+being a string specifying the current time, and
+.Fa message
+the message to log.
+.Fa close
+is called when the facility is closed. You can pass application specific data in the
+.Fa data
+parameter. The
+.Fa min
+and
+.Fa max
+parameter are the same as in a destination (defined below). To specify a
+max of infinity, pass -1.
+.Pp
+.Fn krb5_openlog
+calls
+.Fn krb5_initlog
+and then calls
+.Fn krb5_addlog_dest
+for each destination found.
+
+.Ss Destinations
+
+The defined destinations (as specified in
+.Pa krb5.conf )
+follows:
+.Bl -tag -width "xxx" -offset indent
+.It Li STDERR
+This logs to the program's stderr.
+.It Li FILE: Ns Pa /file
+.It Li FILE= Ns Pa /file
+Log to the specified file. The form using a colon appends to the file, the
+form with an equal truncates the file. The truncating form keeps the file
+open, while the appending form closes it after each log message (which
+makes it possible to rotate logs). The truncating form is mainly for
+compatibility with the MIT libkrb5.
+.It Li DEVICE= Ns Pa /device
+This logs to the specified device, at present this is the same as
+.Li FILE:/device .
+.It Li CONSOLE
+Log to the console, this is the same as
+.Li DEVICE=/dev/console .
+.It Li SYSLOG Ns Op :priority Ns Op :facility
+Send messages to the syslog system, using priority, and facility. To
+get the name for one of these, you take the name of the macro passed
+to
+.Xr syslog 3 ,
+and remove the leading
+.Li LOG_
+.No ( Li LOG_NOTICE
+becomes
+.Li NOTICE ) .
+The default values (as well as the values used for unrecognised
+values), are
+.Li ERR ,
+and
+.Li AUTH ,
+respectively. See
+.Xr syslog 3
+for a list of priorities and facilities.
+.El
+.Pp
+Each destination may optionally be prepended with a range of logging
+levels, specified as
+.Li min-max/ .
+If the
+.Fa level
+parameter to
+.Fn krb5_log
+is within this range (inclusive) the message gets logged to this
+destination, otherwise not. Either of the min and max valued may be
+omitted, in this case min is assumed to be zero, and max is assumed to be
+infinity. If you don't include a dash, both min and max gets set to the
+specified value. If no range is specified, all messages gets logged.
+.Sh EXAMPLE
+.Bd -literal -offset indent
+[logging]
+ kdc = 0/FILE:/var/log/kdc.log
+ kdc = 1-/SYSLOG:INFO:USER
+ default = STDERR
+.Ed
+.Pp
+This will log all messages from the
+.Nm kdc
+program with level 0 to
+.Pa /var/log/kdc.log ,
+other messages will be logged to syslog with priority
+.Li LOG_INFO ,
+and facility
+.Li LOG_USER .
+All other programs will log all messages to their stderr.
+.Sh BUGS
+These functions use
+.Fn asprintf
+to format the message. If your operating system does not have a working
+.Fn asprintf ,
+a replacement will be used. At present this replacement does not handle
+some correct conversion specifications (like floating point numbers). Until
+this is fixed, the use of these conversions should be avoided.
+.Pp
+If logging is done to the syslog facility, these functions might not be
+thread-safe, depending on the implementation of
+.Fn openlog ,
+and
+.Fn syslog .
+.Sh SEE ALSO
+.Xr syslog 3 ,
+.Xr krb5.conf 5
diff --git a/crypto/heimdal/lib/krb5/krb5_parse_name.3 b/crypto/heimdal/lib/krb5/krb5_parse_name.3
new file mode 100644
index 000000000000..db9236c774f7
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_parse_name.3
@@ -0,0 +1,39 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_parse_name.3,v 1.1 1997/08/14 00:03:17 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_PARSE_NAME 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_parse_name
+.Nd String to principal conversion
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_parse_name "krb5_context context" "const char *name" "krb5_principal *principal"
+
+.Sh DESCRIPTION
+
+.Fn krb5_parse_name
+converts a string representation of a princpal name to
+.Nm krb5_principal .
+The
+.Fa principal
+will point to allocated data that should be freed with
+.Fn krb5_free_principal .
+.Pp
+The string should consist of one or more name components separated with slashes
+.Pq Dq / ,
+optionally followed with an
+.Dq @
+and a realm name. A slash or @ may be contained in a name component by
+quoting it with a back-slash
+.Pq Dq \ .
+A realm should not contain slashes or colons.
+.Sh SEE ALSO
+.Xr krb5_425_conv_principal 3 ,
+.Xr krb5_build_principal 3 ,
+.Xr krb5_free_principal 3 ,
+.Xr krb5_sname_to_principal 3 ,
+.Xr krb5_unparse_name 3
diff --git a/crypto/heimdal/lib/krb5/krb5_sname_to_principal.3 b/crypto/heimdal/lib/krb5/krb5_sname_to_principal.3
new file mode 100644
index 000000000000..aea4150189e0
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_sname_to_principal.3
@@ -0,0 +1,58 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_sname_to_principal.3,v 1.1 1997/08/14 00:03:18 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_PRINCIPAL 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_sname_to_principal ,
+.Nm krb5_sock_to_principal
+.Nd Create a service principal
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_sname_to_principal "krb5_context context" "const char *hostname" "const char *sname" "int32_t type" "krb5_principal *principal"
+
+.Ft krb5_error_code
+.Fn krb5_sock_to_principal "krb5_context context" "int socket" "const char *sname" "int32_t type" "krb5_principal *principal"
+
+.Sh DESCRIPTION
+
+These functions create a
+.Dq service
+principal that can, for instance, be used to lookup a key in a keytab. For both these function the
+.Fa sname
+parameter will be used for the first component of the created principal. If
+.Fa sname
+is
+.Dv NULL ,
+.Dq host
+will be used instead.
+.Fn krb5_sname_to_principal
+will use the passed
+.Fa hostname
+for the second component. If type
+.Dv KRB5_NT_SRV_HST
+this name will be looked up with
+.Fn gethostbyname .
+If
+.Fa hostname is
+.Dv NULL ,
+the local hostname will be used.
+.Pp
+.Fn krb5_sock_to_principal
+will use the
+.Dq sockname
+of the passed
+.Fa socket ,
+which should be a bound
+.Dv AF_INET
+socket.
+
+.Sh SEE ALSO
+.Xr krb5_425_conv_principal 3 ,
+.Xr krb5_build_principal 3 ,
+.Xr krb5_free_principal 3 ,
+.Xr krb5_parse_name 3 ,
+.Xr krb5_unparse_name 3
diff --git a/crypto/heimdal/lib/krb5/krb5_unparse_name.3 b/crypto/heimdal/lib/krb5/krb5_unparse_name.3
new file mode 100644
index 000000000000..13277d6b8d44
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_unparse_name.3
@@ -0,0 +1,34 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_unparse_name.3,v 1.1 1997/08/14 00:03:19 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_UNPARSE_NAME 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_unparse_name
+.\" .Nm krb5_unparse_name_ext
+.Nd Principal to string conversion
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_unparse_name "krb5_context context" "krb5_principal principal" "char **name"
+
+.\" .Ft krb5_error_code
+.\" .Fn krb5_unparse_name_ext "krb5_context context" "krb5_const_principal principal" "char **name" "size_t *size"
+
+.Sh DESCRIPTION
+
+This function takes a
+.Fa principal ,
+and will convert in to a printable representation with the same syntax as decribed in
+.Xr krb5_parse_name 3 .
+.Fa *name
+will point to allocated data and should be freed by the caller.
+
+.Sh SEE ALSO
+.Xr krb5_425_conv_principal 3 ,
+.Xr krb5_build_principal 3 ,
+.Xr krb5_free_principal 3 ,
+.Xr krb5_parse_name 3 ,
+.Xr krb5_sname_to_principal 3
diff --git a/crypto/heimdal/lib/krb5/krb5_warn.3 b/crypto/heimdal/lib/krb5/krb5_warn.3
new file mode 100644
index 000000000000..521da0e7a06a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_warn.3
@@ -0,0 +1,73 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_warn.3,v 1.2 1997/08/08 03:45:55 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_WARN 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_warn ,
+.Nm krb5_warnx ,
+.Nm krb5_vwarn ,
+.Nm krb5_vwarnx ,
+.Nm krb5_err ,
+.Nm krb5_errx ,
+.Nm krb5_verr ,
+.Nm krb5_verrx ,
+.Nm krb5_set_warn_dest
+.Nd Heimdal warning and error functions
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_err "krb5_context context" "int eval" "krb5_error_code code" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_errx "krb5_context context" "int eval" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_verr "krb5_context context" "int eval" "krb5_error_code code" "const char *format" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_verrx "krb5_context context" "int eval" "const char *format" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_vwarn "krb5_context context" "krb5_error_code code" "const char *format" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_vwarnx "krb5_context context" "const char *format" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_warn "krb5_context context" "krb5_error_code code" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_warnx "krb5_context context" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_set_warn_dest "krb5_context context" "krb5_log_facility *facility"
+
+.Sh DESCRIPTION
+
+These functions prints a warning message to some destination.
+.Fa format
+is a printf style format specifying the message to print. The forms not ending in an
+.Dq x
+prints the error string associated with
+.Fa code
+along with the message.
+The
+.Dq err
+functions exits with exit status
+.Fa eval
+after printing the message.
+.Pp
+The
+.Fn krb5_set_warn_func
+function sets the destination for warning messages to the specified
+.Fa facility .
+Messages logged with the
+.Dq warn
+functions have a log level of 1, while the
+.Dq err
+functions logs with level 0.
+
+.Sh SEE ALSO
+.Xr krb5_openlog 3
diff --git a/crypto/heimdal/lib/krb5/krbhst.c b/crypto/heimdal/lib/krb5/krbhst.c
new file mode 100644
index 000000000000..8d5c4e407180
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krbhst.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+#include <resolve.h>
+
+RCSID("$Id: krbhst.c,v 1.23 1999/12/11 23:14:25 assar Exp $");
+
+/*
+ * assuming that `*res' contains `*count' strings, add a copy of `string'.
+ */
+
+static int
+add_string(char ***res, int *count, const char *string)
+{
+ char **tmp = realloc(*res, (*count + 1) * sizeof(**res));
+
+ if(tmp == NULL)
+ return ENOMEM;
+ *res = tmp;
+ if(string) {
+ tmp[*count] = strdup(string);
+ if(tmp[*count] == NULL)
+ return ENOMEM;
+ } else
+ tmp[*count] = NULL;
+ (*count)++;
+ return 0;
+}
+
+static krb5_error_code
+srv_find_realm(krb5_context context, char ***res, int *count,
+ const char *realm, const char *proto, const char *service)
+{
+ char domain[1024];
+ char alt_domain[1024];
+ krb5_error_code ret;
+ struct dns_reply *r;
+ struct resource_record *rr;
+
+ snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);
+
+ r = dns_lookup(domain, "srv");
+ if(r == NULL && context->srv_try_rfc2052) {
+ snprintf(alt_domain, sizeof(alt_domain), "%s.%s.%s.",
+ service, proto, realm);
+ r = dns_lookup(alt_domain, "srv");
+ }
+ if(r == NULL && context->srv_try_txt)
+ r = dns_lookup(domain, "txt");
+ if(r == NULL && context->srv_try_rfc2052 && context->srv_try_txt)
+ r = dns_lookup(alt_domain, "txt");
+ if(r == NULL)
+ return 0;
+
+ for(rr = r->head; rr; rr = rr->next){
+ if(rr->type == T_SRV){
+ char buf[1024];
+ char **tmp;
+
+ tmp = realloc(*res, (*count + 1) * sizeof(**res));
+ if (tmp == NULL)
+ return ENOMEM;
+ *res = tmp;
+ snprintf (buf, sizeof(buf),
+ "%s/%s:%u",
+ proto,
+ rr->u.srv->target,
+ rr->u.srv->port);
+ ret = add_string(res, count, buf);
+ if(ret)
+ return ret;
+ }else if(rr->type == T_TXT) {
+ ret = add_string(res, count, rr->u.txt);
+ if(ret)
+ return ret;
+ }
+ }
+ dns_free_data(r);
+ return 0;
+}
+
+/*
+ * lookup the servers for realm `realm', looking for the config string
+ * `conf_string' in krb5.conf or for `serv_string' in SRV records.
+ * return a malloc-ed list of servers in hostlist.
+ */
+
+static krb5_error_code
+get_krbhst (krb5_context context,
+ const krb5_realm *realm,
+ const char *conf_string,
+ const char *serv_string,
+ char ***hostlist)
+{
+ char **res, **r;
+ int count;
+ krb5_error_code ret;
+
+ res = krb5_config_get_strings(context, NULL,
+ "realms", *realm, conf_string, NULL);
+ for(r = res, count = 0; r && *r; r++, count++);
+
+ if(context->srv_lookup) {
+ char *s[] = { "udp", "tcp", "http" }, **q;
+ for(q = s; q < s + sizeof(s) / sizeof(s[0]); q++) {
+ ret = srv_find_realm(context, &res, &count, *realm, *q,
+ serv_string);
+ if(ret) {
+ krb5_config_free_strings(res);
+ return ret;
+ }
+ }
+ }
+
+ if(count == 0) {
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "kerberos.%s", *realm);
+ ret = add_string(&res, &count, buf);
+ if(ret) {
+ krb5_config_free_strings(res);
+ return ret;
+ }
+ }
+ add_string(&res, &count, NULL);
+ *hostlist = res;
+ return 0;
+}
+
+krb5_error_code
+krb5_get_krb_admin_hst (krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist)
+{
+ return get_krbhst (context, realm, "admin_server", "kerberos-adm",
+ hostlist);
+}
+
+krb5_error_code
+krb5_get_krb_changepw_hst (krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist)
+{
+ return get_krbhst (context, realm, "admin_server", "kpasswd",
+ hostlist);
+}
+
+krb5_error_code
+krb5_get_krbhst (krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist)
+{
+ return get_krbhst (context, realm, "kdc", "kerberos", hostlist);
+}
+
+krb5_error_code
+krb5_free_krbhst (krb5_context context,
+ char **hostlist)
+{
+ char **p;
+
+ for (p = hostlist; *p; ++p)
+ free (*p);
+ free (hostlist);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/kuserok.c b/crypto/heimdal/lib/krb5/kuserok.c
new file mode 100644
index 000000000000..ae8ddece4403
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/kuserok.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: kuserok.c,v 1.5 1999/12/02 17:05:11 joda Exp $");
+
+/*
+ * Return TRUE iff `principal' is allowed to login as `luser'.
+ */
+
+krb5_boolean
+krb5_kuserok (krb5_context context,
+ krb5_principal principal,
+ const char *luser)
+{
+ char buf[BUFSIZ];
+ struct passwd *pwd;
+ FILE *f;
+ krb5_realm *realms, *r;
+ krb5_error_code ret;
+ krb5_boolean b;
+
+ ret = krb5_get_default_realms (context, &realms);
+ if (ret)
+ return FALSE;
+
+ for (r = realms; *r != NULL; ++r) {
+ krb5_principal local_principal;
+
+ ret = krb5_build_principal (context,
+ &local_principal,
+ strlen(*r),
+ *r,
+ luser,
+ NULL);
+ if (ret) {
+ krb5_free_host_realm (context, realms);
+ return FALSE;
+ }
+
+ b = krb5_principal_compare (context, principal, local_principal);
+ krb5_free_principal (context, local_principal);
+ if (b) {
+ krb5_free_host_realm (context, realms);
+ return TRUE;
+ }
+ }
+ krb5_free_host_realm (context, realms);
+
+ pwd = getpwnam (luser); /* XXX - Should use k_getpwnam? */
+ if (pwd == NULL)
+ return FALSE;
+ snprintf (buf, sizeof(buf), "%s/.k5login", pwd->pw_dir);
+ f = fopen (buf, "r");
+ if (f == NULL)
+ return FALSE;
+ while (fgets (buf, sizeof(buf), f) != NULL) {
+ krb5_principal tmp;
+
+ if(buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+
+ ret = krb5_parse_name (context, buf, &tmp);
+ if (ret) {
+ fclose (f);
+ return FALSE;
+ }
+ b = krb5_principal_compare (context, principal, tmp);
+ krb5_free_principal (context, tmp);
+ if (b) {
+ fclose (f);
+ return TRUE;
+ }
+ }
+ fclose (f);
+ return FALSE;
+}
diff --git a/crypto/heimdal/lib/krb5/log.c b/crypto/heimdal/lib/krb5/log.c
new file mode 100644
index 000000000000..e1511e255f91
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/log.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: log.c,v 1.21 1999/12/02 17:05:11 joda Exp $");
+
+struct facility {
+ int min;
+ int max;
+ krb5_log_log_func_t log;
+ krb5_log_close_func_t close;
+ void *data;
+};
+
+static struct facility*
+log_realloc(krb5_log_facility *f)
+{
+ struct facility *fp;
+ f->len++;
+ fp = realloc(f->val, f->len * sizeof(*f->val));
+ if(fp == NULL)
+ return NULL;
+ f->val = fp;
+ fp += f->len - 1;
+ return fp;
+}
+
+struct s2i{
+ char *s;
+ int val;
+};
+
+#define L(X) { #X, LOG_ ## X }
+
+struct s2i syslogvals[] = {
+ L(EMERG),
+ L(ALERT),
+ L(CRIT),
+ L(ERR),
+ L(WARNING),
+ L(NOTICE),
+ L(INFO),
+ L(DEBUG),
+
+ L(AUTH),
+#ifdef LOG_AUTHPRIV
+ L(AUTHPRIV),
+#endif
+#ifdef LOG_CRON
+ L(CRON),
+#endif
+ L(DAEMON),
+#ifdef LOG_FTP
+ L(FTP),
+#endif
+ L(KERN),
+ L(LPR),
+ L(MAIL),
+#ifdef LOG_NEWS
+ L(NEWS),
+#endif
+ L(SYSLOG),
+ L(USER),
+#ifdef LOG_UUCP
+ L(UUCP),
+#endif
+ L(LOCAL0),
+ L(LOCAL1),
+ L(LOCAL2),
+ L(LOCAL3),
+ L(LOCAL4),
+ L(LOCAL5),
+ L(LOCAL6),
+ L(LOCAL7),
+ { NULL, -1 }
+};
+
+static int
+find_value(const char *s, struct s2i *table)
+{
+ while(table->s && strcasecmp(table->s, s))
+ table++;
+ return table->val;
+}
+
+krb5_error_code
+krb5_initlog(krb5_context context,
+ const char *program,
+ krb5_log_facility **fac)
+{
+ krb5_log_facility *f = calloc(1, sizeof(*f));
+ if(f == NULL)
+ return ENOMEM;
+ f->program = strdup(program);
+ if(f->program == NULL){
+ free(f);
+ return ENOMEM;
+ }
+ *fac = f;
+ return 0;
+}
+
+krb5_error_code
+krb5_addlog_func(krb5_context context,
+ krb5_log_facility *fac,
+ int min,
+ int max,
+ krb5_log_log_func_t log,
+ krb5_log_close_func_t close,
+ void *data)
+{
+ struct facility *fp = log_realloc(fac);
+ if(fp == NULL)
+ return ENOMEM;
+ fp->min = min;
+ fp->max = max;
+ fp->log = log;
+ fp->close = close;
+ fp->data = data;
+ return 0;
+}
+
+
+struct syslog_data{
+ int priority;
+};
+
+static void
+log_syslog(const char *time,
+ const char *msg,
+ void *data)
+
+{
+ struct syslog_data *s = data;
+ syslog(s->priority, "%s", msg);
+}
+
+static void
+close_syslog(void *data)
+{
+ free(data);
+ closelog();
+}
+
+static krb5_error_code
+open_syslog(krb5_context context,
+ krb5_log_facility *facility, int min, int max,
+ const char *sev, const char *fac)
+{
+ struct syslog_data *sd = malloc(sizeof(*sd));
+ int i;
+
+ if(sd == NULL)
+ return ENOMEM;
+ i = find_value(sev, syslogvals);
+ if(i == -1)
+ i = LOG_ERR;
+ sd->priority = i;
+ i = find_value(fac, syslogvals);
+ if(i == -1)
+ i = LOG_AUTH;
+ sd->priority |= i;
+ roken_openlog(facility->program, LOG_PID | LOG_NDELAY, i);
+ return krb5_addlog_func(context, facility, min, max,
+ log_syslog, close_syslog, sd);
+}
+
+struct file_data{
+ char *filename;
+ char *mode;
+ FILE *fd;
+ int keep_open;
+};
+
+static void
+log_file(const char *time,
+ const char *msg,
+ void *data)
+{
+ struct file_data *f = data;
+ if(f->keep_open == 0)
+ f->fd = fopen(f->filename, f->mode);
+ if(f->fd == NULL)
+ return;
+ fprintf(f->fd, "%s %s\n", time, msg);
+ if(f->keep_open == 0)
+ fclose(f->fd);
+}
+
+static void
+close_file(void *data)
+{
+ struct file_data *f = data;
+ if(f->keep_open && f->filename)
+ fclose(f->fd);
+ free(data);
+}
+
+static krb5_error_code
+open_file(krb5_context context, krb5_log_facility *fac, int min, int max,
+ char *filename, char *mode, FILE *f, int keep_open)
+{
+ struct file_data *fd = malloc(sizeof(*fd));
+ if(fd == NULL)
+ return ENOMEM;
+ fd->filename = filename;
+ fd->mode = mode;
+ fd->fd = f;
+ fd->keep_open = keep_open;
+
+ return krb5_addlog_func(context, fac, min, max, log_file, close_file, fd);
+}
+
+
+
+krb5_error_code
+krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *p)
+{
+ krb5_error_code ret = 0;
+ int min = 0, max = -1, n;
+ char c;
+ n = sscanf(p, "%d%c%d/", &min, &c, &max);
+ if(n == 2){
+ if(c == '/') {
+ if(min < 0){
+ max = -min;
+ min = 0;
+ }else{
+ max = min;
+ }
+ }
+ }
+ if(n){
+ p = strchr(p, '/');
+ if(p == NULL) return HEIM_ERR_LOG_PARSE;
+ p++;
+ }
+ if(strcmp(p, "STDERR") == 0){
+ ret = open_file(context, f, min, max, NULL, NULL, stderr, 1);
+ }else if(strcmp(p, "CONSOLE") == 0){
+ ret = open_file(context, f, min, max, "/dev/console", "w", NULL, 0);
+ }else if(strncmp(p, "FILE:", 4) == 0 && (p[4] == ':' || p[4] == '=')){
+ char *fn;
+ FILE *file = NULL;
+ int keep_open = 0;
+ fn = strdup(p + 5);
+ if(fn == NULL)
+ return ENOMEM;
+ if(p[4] == '='){
+ int i = open(fn, O_WRONLY | O_CREAT |
+ O_TRUNC | O_APPEND, 0666);
+ if(i < 0)
+ return errno;
+ file = fdopen(i, "a");
+ if(file == NULL){
+ close(i);
+ return errno;
+ }
+ keep_open = 1;
+ }
+ ret = open_file(context, f, min, max, fn, "a", file, keep_open);
+ }else if(strncmp(p, "DEVICE=", 6) == 0){
+ ret = open_file(context, f, min, max, strdup(p + 7), "w", NULL, 0);
+ }else if(strncmp(p, "SYSLOG", 6) == 0){
+ char *severity;
+ char *facility;
+ severity = strchr(p, ':');
+ if(severity == NULL)
+ severity = "ERR";
+ facility = strchr(severity, ':');
+ if(facility == NULL)
+ facility = "AUTH";
+ ret = open_syslog(context, f, min, max, severity, facility);
+ }else{
+ ret = HEIM_ERR_LOG_PARSE; /* XXX */
+ }
+ return ret;
+}
+
+
+krb5_error_code
+krb5_openlog(krb5_context context,
+ const char *program,
+ krb5_log_facility **fac)
+{
+ krb5_error_code ret;
+ char **p, **q;
+
+ ret = krb5_initlog(context, program, fac);
+ if(ret)
+ return ret;
+
+ p = krb5_config_get_strings(context, NULL, "logging", program, NULL);
+ if(p == NULL)
+ p = krb5_config_get_strings(context, NULL, "logging", "default", NULL);
+ if(p){
+ for(q = p; *q; q++)
+ ret = krb5_addlog_dest(context, *fac, *q);
+ krb5_config_free_strings(p);
+ }else
+ ret = krb5_addlog_dest(context, *fac, "SYSLOG");
+ return 0;
+}
+
+krb5_error_code
+krb5_closelog(krb5_context context,
+ krb5_log_facility *fac)
+{
+ int i;
+ for(i = 0; i < fac->len; i++)
+ (*fac->val[i].close)(&fac->val[i].data);
+ return 0;
+}
+
+#undef __attribute__
+#define __attribute__(X)
+
+krb5_error_code
+krb5_vlog_msg(krb5_context context,
+ krb5_log_facility *fac,
+ char **reply,
+ int level,
+ const char *fmt,
+ va_list ap)
+ __attribute__((format (printf, 5, 0)))
+{
+ char *msg;
+ char buf[64];
+ time_t t;
+ int i;
+
+ vasprintf(&msg, fmt, ap);
+ t = time(NULL);
+ strftime(buf, sizeof(buf), context->time_fmt,
+ context->log_utc ? gmtime(&t) : localtime(&t));
+ for(i = 0; i < fac->len; i++)
+ if(fac->val[i].min <= level &&
+ (fac->val[i].max < 0 || fac->val[i].max >= level))
+ (*fac->val[i].log)(buf, msg, fac->val[i].data);
+ *reply = msg;
+ return 0;
+}
+
+krb5_error_code
+krb5_vlog(krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ const char *fmt,
+ va_list ap)
+ __attribute__((format (printf, 4, 0)))
+{
+ char *msg;
+ krb5_error_code ret;
+
+ ret = krb5_vlog_msg(context, fac, &msg, level, fmt, ap);
+ free(msg);
+ return ret;
+}
+
+krb5_error_code
+krb5_log_msg(krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ char **reply,
+ const char *fmt,
+ ...)
+ __attribute__((format (printf, 5, 6)))
+{
+ va_list ap;
+ krb5_error_code ret;
+
+ va_start(ap, fmt);
+ ret = krb5_vlog_msg(context, fac, reply, level, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+
+krb5_error_code
+krb5_log(krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ const char *fmt,
+ ...)
+ __attribute__((format (printf, 4, 5)))
+{
+ va_list ap;
+ krb5_error_code ret;
+
+ va_start(ap, fmt);
+ ret = krb5_vlog(context, fac, level, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
diff --git a/crypto/heimdal/lib/krb5/mcache.c b/crypto/heimdal/lib/krb5/mcache.c
new file mode 100644
index 000000000000..d45deea13d19
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mcache.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: mcache.c,v 1.10 1999/12/02 17:05:11 joda Exp $");
+
+typedef struct krb5_mcache {
+ krb5_principal primary_principal;
+ struct link {
+ krb5_creds cred;
+ struct link *next;
+ } *creds;
+} krb5_mcache;
+
+#define MCC_CURSOR(C) ((struct link*)(C))
+
+static char*
+mcc_get_name(krb5_context context,
+ krb5_ccache id)
+{
+ return ""; /* XXX */
+}
+
+static krb5_error_code
+mcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
+{
+ krb5_abortx(context, "unimplemented mcc_resolve called");
+}
+
+static krb5_error_code
+mcc_gen_new(krb5_context context, krb5_ccache *id)
+{
+ krb5_mcache *m;
+
+ m = malloc (sizeof(*m));
+ if (m == NULL)
+ return KRB5_CC_NOMEM;
+ m->primary_principal = NULL;
+ m->creds = NULL;
+ (*id)->data.data = m;
+ (*id)->data.length = sizeof(*m);
+ return 0;
+}
+
+static krb5_error_code
+mcc_initialize(krb5_context context,
+ krb5_ccache id,
+ krb5_principal primary_principal)
+{
+ krb5_error_code ret;
+ krb5_mcache *m;
+
+ m = (krb5_mcache *)id->data.data;
+
+ ret = krb5_copy_principal (context,
+ primary_principal,
+ &m->primary_principal);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+static krb5_error_code
+mcc_close(krb5_context context,
+ krb5_ccache id)
+{
+ krb5_mcache *m = (krb5_mcache *)id->data.data;
+ struct link *l;
+
+ krb5_free_principal (context, m->primary_principal);
+ l = m->creds;
+ while (l != NULL) {
+ struct link *old;
+
+ krb5_free_creds_contents (context, &l->cred);
+ old = l;
+ l = l->next;
+ free (old);
+ }
+ krb5_data_free(&id->data);
+ return 0;
+}
+
+static krb5_error_code
+mcc_destroy(krb5_context context,
+ krb5_ccache id)
+{
+ return 0;
+}
+
+static krb5_error_code
+mcc_store_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_creds *creds)
+{
+ krb5_error_code ret;
+ krb5_mcache *m = (krb5_mcache *)id->data.data;
+ struct link *l;
+
+ l = malloc (sizeof(*l));
+ if (l == NULL)
+ return KRB5_CC_NOMEM;
+ l->next = m->creds;
+ m->creds = l;
+ memset (&l->cred, 0, sizeof(l->cred));
+ ret = krb5_copy_creds_contents (context, creds, &l->cred);
+ if (ret) {
+ m->creds = l->next;
+ free (l);
+ return ret;
+ }
+ return 0;
+}
+
+static krb5_error_code
+mcc_get_principal(krb5_context context,
+ krb5_ccache id,
+ krb5_principal *principal)
+{
+ krb5_mcache *m = (krb5_mcache *)id->data.data;
+
+ return krb5_copy_principal (context,
+ m->primary_principal,
+ principal);
+}
+
+static krb5_error_code
+mcc_get_first (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ krb5_mcache *m = (krb5_mcache *)id->data.data;
+ *cursor = m->creds;
+ return 0;
+}
+
+static krb5_error_code
+mcc_get_next (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor,
+ krb5_creds *creds)
+{
+ struct link *l;
+
+ l = *cursor;
+ if (l != NULL) {
+ *cursor = l->next;
+ return krb5_copy_creds_contents (context,
+ &l->cred,
+ creds);
+ } else
+ return KRB5_CC_END;
+}
+
+static krb5_error_code
+mcc_end_get (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ return 0;
+}
+
+static krb5_error_code
+mcc_remove_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_flags which,
+ krb5_creds *cred)
+{
+ return 0; /* XXX */
+}
+
+static krb5_error_code
+mcc_set_flags(krb5_context context,
+ krb5_ccache id,
+ krb5_flags flags)
+{
+ return 0; /* XXX */
+}
+
+const krb5_cc_ops krb5_mcc_ops = {
+ "MEMORY",
+ mcc_get_name,
+ mcc_resolve,
+ mcc_gen_new,
+ mcc_initialize,
+ mcc_destroy,
+ mcc_close,
+ mcc_store_cred,
+ NULL, /* mcc_retrieve */
+ mcc_get_principal,
+ mcc_get_first,
+ mcc_get_next,
+ mcc_end_get,
+ mcc_remove_cred,
+ mcc_set_flags
+};
diff --git a/crypto/heimdal/lib/krb5/misc.c b/crypto/heimdal/lib/krb5/misc.c
new file mode 100644
index 000000000000..baf63f6d525d
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/misc.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: misc.c,v 1.5 1999/12/02 17:05:11 joda Exp $");
diff --git a/crypto/heimdal/lib/krb5/mk_error.c b/crypto/heimdal/lib/krb5/mk_error.c
new file mode 100644
index 000000000000..2b173db9b545
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_error.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: mk_error.c,v 1.14 1999/12/02 17:05:11 joda Exp $");
+
+krb5_error_code
+krb5_mk_error(krb5_context context,
+ krb5_error_code error_code,
+ const char *e_text,
+ const krb5_data *e_data,
+ const krb5_principal client,
+ const krb5_principal server,
+ time_t ctime,
+ krb5_data *reply)
+{
+ KRB_ERROR msg;
+ u_char *buf;
+ size_t buf_size;
+ int32_t sec, usec;
+ size_t len;
+ krb5_error_code ret = 0;
+
+ krb5_us_timeofday (context, &sec, &usec);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.pvno = 5;
+ msg.msg_type = krb_error;
+ msg.stime = sec;
+ msg.susec = usec;
+ if(ctime) {
+ msg.ctime = &ctime;
+ }
+ /* Make sure we only send `protocol' error codes */
+ if(error_code < KRB5KDC_ERR_NONE || error_code >= KRB5_ERR_RCSID) {
+ if(e_text == NULL)
+ e_text = krb5_get_err_text(context, error_code);
+ error_code = KRB5KRB_ERR_GENERIC;
+ }
+ msg.error_code = error_code - KRB5KDC_ERR_NONE;
+ if (e_text)
+ msg.e_text = (general_string*)&e_text;
+ if (e_data)
+ msg.e_data = (octet_string*)e_data;
+ if(server){
+ msg.realm = server->realm;
+ msg.sname = server->name;
+ }else{
+ msg.realm = "<unspecified realm>";
+ }
+ if(client){
+ msg.crealm = &client->realm;
+ msg.cname = &client->name;
+ }
+
+ buf_size = 1024;
+ buf = malloc (buf_size);
+ if (buf == NULL)
+ return ENOMEM;
+
+ do {
+ ret = encode_KRB_ERROR(buf + buf_size - 1,
+ buf_size,
+ &msg,
+ &len);
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ buf = tmp;
+ } else {
+ goto out;
+ }
+ }
+ } while (ret == ASN1_OVERFLOW);
+
+ reply->length = len;
+ reply->data = malloc(len);
+ if (reply->data == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ memcpy (reply->data, buf + buf_size - len, len);
+out:
+ free (buf);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/mk_priv.c b/crypto/heimdal/lib/krb5/mk_priv.c
new file mode 100644
index 000000000000..1ee2bed033f0
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_priv.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: mk_priv.c,v 1.25 1999/12/02 17:05:11 joda Exp $");
+
+/*
+ *
+ */
+
+krb5_error_code
+krb5_mk_priv(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *userdata,
+ krb5_data *outbuf,
+ /*krb5_replay_data*/ void *outdata)
+{
+ krb5_error_code ret;
+ KRB_PRIV s;
+ EncKrbPrivPart part;
+ u_char *buf;
+ size_t buf_size;
+ size_t len;
+ int tmp_seq;
+ krb5_keyblock *key;
+ int32_t sec, usec;
+ KerberosTime sec2;
+ int usec2;
+ krb5_crypto crypto;
+
+ /* XXX - Is this right? */
+
+ if (auth_context->local_subkey)
+ key = auth_context->local_subkey;
+ else if (auth_context->remote_subkey)
+ key = auth_context->remote_subkey;
+ else
+ key = auth_context->keyblock;
+
+ krb5_us_timeofday (context, &sec, &usec);
+
+ part.user_data = *userdata;
+ sec2 = sec;
+ part.timestamp = &sec2;
+ usec2 = usec;
+ part.usec = &usec2;
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ tmp_seq = ++auth_context->local_seqnumber;
+ part.seq_number = &tmp_seq;
+ } else {
+ part.seq_number = NULL;
+ }
+
+ part.s_address = auth_context->local_address;
+ part.r_address = auth_context->remote_address;
+
+ buf_size = 1024;
+ buf = malloc (buf_size);
+ if (buf == NULL)
+ return ENOMEM;
+
+ krb5_data_zero (&s.enc_part.cipher);
+
+ do {
+ ret = encode_EncKrbPrivPart (buf + buf_size - 1, buf_size,
+ &part, &len);
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ buf = tmp;
+ } else {
+ goto fail;
+ }
+ }
+ } while(ret == ASN1_OVERFLOW);
+
+ s.pvno = 5;
+ s.msg_type = krb_priv;
+ s.enc_part.etype = key->keytype;
+ s.enc_part.kvno = NULL;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_encrypt (context,
+ crypto,
+ KRB5_KU_KRB_PRIV,
+ buf + buf_size - len,
+ len,
+ &s.enc_part.cipher);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ free(buf);
+ return ret;
+ }
+
+ do {
+ ret = encode_KRB_PRIV (buf + buf_size - 1, buf_size, &s, &len);
+
+ if (ret){
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ buf = tmp;
+ } else {
+ goto fail;
+ }
+ }
+ } while(ret == ASN1_OVERFLOW);
+ krb5_data_free (&s.enc_part.cipher);
+
+ outbuf->length = len;
+ outbuf->data = malloc (len);
+ if (outbuf->data == NULL) {
+ free(buf);
+ return ENOMEM;
+ }
+ memcpy (outbuf->data, buf + buf_size - len, len);
+ free (buf);
+ return 0;
+
+fail:
+ free (buf);
+ krb5_data_free (&s.enc_part.cipher);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/mk_rep.c b/crypto/heimdal/lib/krb5/mk_rep.c
new file mode 100644
index 000000000000..060be033b13b
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_rep.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: mk_rep.c,v 1.16 1999/12/02 17:05:11 joda Exp $");
+
+krb5_error_code
+krb5_mk_rep(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_data *outbuf)
+{
+ krb5_error_code ret;
+ AP_REP ap;
+ EncAPRepPart body;
+ u_char *buf = NULL;
+ size_t buf_size;
+ size_t len;
+ krb5_crypto crypto;
+
+ ap.pvno = 5;
+ ap.msg_type = krb_ap_rep;
+
+ memset (&body, 0, sizeof(body));
+
+ body.ctime = (*auth_context)->authenticator->ctime;
+ body.cusec = (*auth_context)->authenticator->cusec;
+ body.subkey = NULL;
+ if ((*auth_context)->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ krb5_generate_seq_number (context,
+ (*auth_context)->keyblock,
+ &(*auth_context)->local_seqnumber);
+ body.seq_number = malloc (sizeof(*body.seq_number));
+ if (body.seq_number == NULL)
+ return ENOMEM;
+ *(body.seq_number) = (*auth_context)->local_seqnumber;
+ } else
+ body.seq_number = NULL;
+
+ ap.enc_part.etype = (*auth_context)->keyblock->keytype;
+ ap.enc_part.kvno = NULL;
+
+ buf_size = length_EncAPRepPart(&body);
+ buf = malloc (buf_size);
+ if (buf == NULL) {
+ free_EncAPRepPart (&body);
+ return ENOMEM;
+ }
+
+ ret = krb5_encode_EncAPRepPart (context,
+ buf + buf_size - 1,
+ buf_size,
+ &body,
+ &len);
+
+ free_EncAPRepPart (&body);
+ krb5_crypto_init(context, (*auth_context)->keyblock,
+ 0 /* ap.enc_part.etype */, &crypto);
+ ret = krb5_encrypt (context,
+ crypto,
+ KRB5_KU_AP_REQ_ENC_PART,
+ buf + buf_size - len,
+ len,
+ &ap.enc_part.cipher);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ free(buf);
+ return ret;
+ }
+
+ buf_size = length_AP_REP(&ap);
+ buf = realloc(buf, buf_size);
+ if(buf == NULL) {
+ free_AP_REP (&ap);
+ return ENOMEM;
+ }
+ ret = encode_AP_REP (buf + buf_size - 1, buf_size, &ap, &len);
+
+ free_AP_REP (&ap);
+
+ if(len != buf_size)
+ krb5_abortx(context, "krb5_mk_rep: encoded length != calculated length");
+ outbuf->data = buf;
+ outbuf->length = len;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/mk_req.c b/crypto/heimdal/lib/krb5/mk_req.c
new file mode 100644
index 000000000000..e92d326390a9
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_req.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: mk_req.c,v 1.18 1999/12/02 17:05:11 joda Exp $");
+
+krb5_error_code
+krb5_mk_req(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ char *service,
+ char *hostname,
+ krb5_data *in_data,
+ krb5_ccache ccache,
+ krb5_data *outbuf)
+{
+ krb5_error_code r;
+ krb5_creds this_cred, *cred;
+ char **realms;
+ krb5_data realm_data;
+ char *real_hostname;
+
+ memset(&this_cred, 0, sizeof(this_cred));
+
+ r = krb5_cc_get_principal(context, ccache, &this_cred.client);
+
+ if(r)
+ return r;
+
+ r = krb5_expand_hostname (context, hostname, &real_hostname);
+ if (r) {
+ krb5_free_principal (context, this_cred.client);
+ return r;
+ }
+
+ r = krb5_get_host_realm(context, real_hostname, &realms);
+ if (r) {
+ krb5_free_principal (context, this_cred.client);
+ return r;
+ }
+ realm_data.length = strlen(*realms);
+ realm_data.data = *realms;
+
+ r = krb5_build_principal (context, &this_cred.server,
+ strlen(*realms),
+ *realms,
+ service,
+ real_hostname,
+ NULL);
+ free (real_hostname);
+ krb5_free_host_realm (context, realms);
+
+ if (r) {
+ krb5_free_principal (context, this_cred.client);
+ return r;
+ }
+ this_cred.times.endtime = 0;
+ if (auth_context && *auth_context && (*auth_context)->keytype)
+ this_cred.session.keytype = (*auth_context)->keytype;
+
+ r = krb5_get_credentials (context, 0, ccache, &this_cred, &cred);
+ if (r)
+ return r;
+
+ return krb5_mk_req_extended (context,
+ auth_context,
+ ap_req_options,
+ in_data,
+ cred,
+ outbuf);
+}
diff --git a/crypto/heimdal/lib/krb5/mk_req_ext.c b/crypto/heimdal/lib/krb5/mk_req_ext.c
new file mode 100644
index 000000000000..2b7b886e6bb0
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_req_ext.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: mk_req_ext.c,v 1.21 1999/12/02 17:05:11 joda Exp $");
+
+krb5_error_code
+krb5_mk_req_internal(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_data *outbuf,
+ krb5_key_usage usage)
+{
+ krb5_error_code ret;
+ krb5_data authenticator;
+ Checksum c;
+ Checksum *c_opt;
+ krb5_auth_context ac;
+
+ if(auth_context) {
+ if(*auth_context == NULL)
+ ret = krb5_auth_con_init(context, auth_context);
+ else
+ ret = 0;
+ ac = *auth_context;
+ } else
+ ret = krb5_auth_con_init(context, &ac);
+ if(ret)
+ return ret;
+
+#if 0
+ {
+ /* This is somewhat bogus since we're possibly overwriting a
+ value specified by the user, but it's the easiest way to make
+ the code use a compatible enctype */
+ Ticket ticket;
+ krb5_keytype ticket_keytype;
+
+ ret = decode_Ticket(in_creds->ticket.data,
+ in_creds->ticket.length,
+ &ticket,
+ NULL);
+ krb5_enctype_to_keytype (context,
+ ticket.enc_part.etype,
+ &ticket_keytype);
+
+ if (ticket_keytype == in_creds->session.keytype)
+ krb5_auth_setenctype(context,
+ ac,
+ ticket.enc_part.etype);
+ free_Ticket(&ticket);
+ }
+#endif
+
+ krb5_free_keyblock(context, ac->keyblock);
+ krb5_copy_keyblock(context, &in_creds->session, &ac->keyblock);
+
+ if (in_data) {
+ if(ac->keyblock->keytype == ETYPE_DES_CBC_CRC) {
+ /* this is to make DCE secd (and older MIT kdcs?) happy */
+ ret = krb5_create_checksum(context,
+ NULL,
+ CKSUMTYPE_RSA_MD4,
+ in_data->data,
+ in_data->length,
+ &c);
+ } else {
+ krb5_crypto crypto;
+ krb5_crypto_init(context, ac->keyblock, 0, &crypto);
+ ret = krb5_create_checksum(context,
+ crypto,
+ usage,
+ in_data->data,
+ in_data->length,
+ &c);
+
+ krb5_crypto_destroy(context, crypto);
+ }
+ c_opt = &c;
+ } else {
+ c_opt = NULL;
+ }
+
+ ret = krb5_build_authenticator (context,
+ ac,
+ ac->keyblock->keytype,
+ in_creds,
+ c_opt,
+ NULL,
+ &authenticator);
+ if (c_opt)
+ free_Checksum (c_opt);
+ if (ret)
+ return ret;
+
+ ret = krb5_build_ap_req (context, ac->keyblock->keytype,
+ in_creds, ap_req_options, authenticator, outbuf);
+ if(auth_context == NULL)
+ krb5_auth_con_free(context, ac);
+ return ret;
+}
+
+krb5_error_code
+krb5_mk_req_extended(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_data *outbuf)
+{
+ return krb5_mk_req_internal (context,
+ auth_context,
+ ap_req_options,
+ in_data,
+ in_creds,
+ outbuf,
+ KRB5_KU_AP_REQ_AUTH_CKSUM);
+}
diff --git a/crypto/heimdal/lib/krb5/mk_safe.c b/crypto/heimdal/lib/krb5/mk_safe.c
new file mode 100644
index 000000000000..4d848a6d783c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_safe.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: mk_safe.c,v 1.20 1999/12/02 17:05:11 joda Exp $");
+
+krb5_error_code
+krb5_mk_safe(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *userdata,
+ krb5_data *outbuf,
+ /*krb5_replay_data*/ void *outdata)
+{
+ krb5_error_code ret;
+ KRB_SAFE s;
+ int32_t sec, usec;
+ KerberosTime sec2;
+ int usec2;
+ u_char *buf = NULL;
+ size_t buf_size;
+ size_t len;
+ int tmp_seq;
+ krb5_crypto crypto;
+
+ s.pvno = 5;
+ s.msg_type = krb_safe;
+
+ s.safe_body.user_data = *userdata;
+ krb5_us_timeofday (context, &sec, &usec);
+
+ sec2 = sec;
+ s.safe_body.timestamp = &sec2;
+ usec2 = usec2;
+ s.safe_body.usec = &usec2;
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ tmp_seq = ++auth_context->local_seqnumber;
+ s.safe_body.seq_number = &tmp_seq;
+ } else
+ s.safe_body.seq_number = NULL;
+
+ s.safe_body.s_address = auth_context->local_address;
+ s.safe_body.r_address = auth_context->remote_address;
+
+ s.cksum.cksumtype = 0;
+ s.cksum.checksum.data = NULL;
+ s.cksum.checksum.length = 0;
+
+
+ buf_size = length_KRB_SAFE(&s);
+ buf = malloc(buf_size + 128); /* add some for checksum */
+ if(buf == NULL)
+ return ENOMEM;
+ ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
+ ret = krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
+ ret = krb5_create_checksum(context,
+ crypto,
+ KRB5_KU_KRB_SAFE_CKSUM,
+ buf + buf_size - len,
+ len,
+ &s.cksum);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ free (buf);
+ return ret;
+ }
+
+ buf_size = length_KRB_SAFE(&s);
+ buf = realloc(buf, buf_size);
+ if(buf == NULL)
+ return ENOMEM;
+
+ ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
+ free_Checksum (&s.cksum);
+
+ outbuf->length = len;
+ outbuf->data = malloc (len);
+ if (outbuf->data == NULL) {
+ free (buf);
+ return ENOMEM;
+ }
+ memcpy (outbuf->data, buf + buf_size - len, len);
+ free (buf);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/n-fold-test.c b/crypto/heimdal/lib/krb5/n-fold-test.c
new file mode 100644
index 000000000000..814dc6fb694c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/n-fold-test.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: n-fold-test.c,v 1.3 1999/07/22 11:45:33 assar Exp $");
+
+enum { MAXSIZE = 24 };
+
+static struct testcase {
+ const char *str;
+ unsigned n;
+ unsigned char res[MAXSIZE];
+} tests[] = {
+ {"012345", 8,
+ {0xbe, 0x07, 0x26, 0x31, 0x27, 0x6b, 0x19, 0x55}
+ },
+ {"basch", 24,
+ {0x1a, 0xab, 0x6b, 0x42, 0x96, 0x4b, 0x98, 0xb2, 0x1f, 0x8c, 0xde,
+ 0x2d, 0x24, 0x48, 0xba, 0x34, 0x55, 0xd7, 0x86, 0x2c, 0x97, 0x31,
+ 0x64, 0x3f}
+ },
+ {"eichin", 24,
+ {0x65, 0x69, 0x63, 0x68, 0x69, 0x6e, 0x4b, 0x73, 0x2b, 0x4b,
+ 0x1b, 0x43, 0xda, 0x1a, 0x5b, 0x99, 0x5a, 0x58, 0xd2, 0xc6, 0xd0,
+ 0xd2, 0xdc, 0xca}
+ },
+ {"sommerfeld", 24,
+ {0x2f, 0x7a, 0x98, 0x55, 0x7c, 0x6e, 0xe4, 0xab, 0xad, 0xf4,
+ 0xe7, 0x11, 0x92, 0xdd, 0x44, 0x2b, 0xd4, 0xff, 0x53, 0x25, 0xa5,
+ 0xde, 0xf7, 0x5c}
+ },
+ {"MASSACHVSETTS INSTITVTE OF TECHNOLOGY", 24,
+ {0xdb, 0x3b, 0x0d, 0x8f, 0x0b, 0x06, 0x1e, 0x60, 0x32, 0x82,
+ 0xb3, 0x08, 0xa5, 0x08, 0x41, 0x22, 0x9a, 0xd7, 0x98, 0xfa, 0xb9,
+ 0x54, 0x0c, 0x1b}
+ },
+ {"assar@NADA.KTH.SE", 24,
+ {0x5c, 0x06, 0xc3, 0x4d, 0x2c, 0x89, 0x05, 0xbe, 0x7a, 0x51,
+ 0x83, 0x6c, 0xd6, 0xf8, 0x1c, 0x4b, 0x7a, 0x93, 0x49, 0x16, 0x5a,
+ 0xb3, 0xfa, 0xa9}
+ },
+ {"testKRBTEST.MIT.EDUtestkey", 24,
+ {0x50, 0x2c, 0xf8, 0x29, 0x78, 0xe5, 0xfb, 0x1a, 0x29, 0x06,
+ 0xbd, 0x22, 0x28, 0x91, 0x56, 0xc0, 0x06, 0xa0, 0xdc, 0xf5, 0xb6,
+ 0xc2, 0xda, 0x6c}
+ },
+ {NULL, 0}
+};
+
+int
+main(int argc, char **argv)
+{
+ unsigned char data[MAXSIZE];
+ struct testcase *t;
+ int ret = 0;
+
+ for (t = tests; t->str; ++t) {
+ int i;
+
+ _krb5_n_fold (t->str, strlen(t->str), data, t->n);
+ if (memcmp (data, t->res, t->n) != 0) {
+ printf ("n-fold(\"%s\", %d) failed\n", t->str, t->n);
+ printf ("should be: ");
+ for (i = 0; i < t->n; ++i)
+ printf ("%02x", t->res[i]);
+ printf ("\nresult was: ");
+ for (i = 0; i < t->n; ++i)
+ printf ("%02x", data[i]);
+ printf ("\n");
+ ret = 1;
+ }
+ }
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/n-fold.c b/crypto/heimdal/lib/krb5/n-fold.c
new file mode 100644
index 000000000000..d0db5e81cbaa
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/n-fold.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: n-fold.c,v 1.6 1999/08/27 09:03:41 joda Exp $");
+
+static void
+rr13(unsigned char *buf, size_t len)
+{
+ unsigned char *tmp;
+ int bytes = (len + 7) / 8;
+ int i;
+ if(len == 0)
+ return;
+ {
+ const int bits = 13 % len;
+ const int lbit = len % 8;
+
+ tmp = malloc(bytes);
+ memcpy(tmp, buf, bytes);
+ if(lbit) {
+ /* pad final byte with inital bits */
+ tmp[bytes - 1] &= 0xff << (8 - lbit);
+ for(i = lbit; i < 8; i += len)
+ tmp[bytes - 1] |= buf[0] >> i;
+ }
+ for(i = 0; i < bytes; i++) {
+ int bb;
+ int b1, s1, b2, s2;
+ /* calculate first bit position of this byte */
+ bb = 8 * i - bits;
+ while(bb < 0)
+ bb += len;
+ /* byte offset and shift count */
+ b1 = bb / 8;
+ s1 = bb % 8;
+
+ if(bb + 8 > bytes * 8)
+ /* watch for wraparound */
+ s2 = (len + 8 - s1) % 8;
+ else
+ s2 = 8 - s1;
+ b2 = (b1 + 1) % bytes;
+ buf[i] = (tmp[b1] << s1) | (tmp[b2] >> s2);
+ }
+ free(tmp);
+ }
+}
+
+/* Add `b' to `a', both beeing one's complement numbers. */
+static void
+add1(unsigned char *a, unsigned char *b, size_t len)
+{
+ int i;
+ int carry = 0;
+ for(i = len - 1; i >= 0; i--){
+ int x = a[i] + b[i] + carry;
+ carry = x > 0xff;
+ a[i] = x & 0xff;
+ }
+ for(i = len - 1; carry && i >= 0; i--){
+ int x = a[i] + carry;
+ carry = x > 0xff;
+ a[i] = x & 0xff;
+ }
+}
+
+void
+_krb5_n_fold(const void *str, size_t len, void *key, size_t size)
+{
+ /* if len < size we need at most N * len bytes, ie < 2 * size;
+ if len > size we need at most 2 * len */
+ size_t maxlen = 2 * max(size, len);
+ size_t l = 0;
+ unsigned char *tmp = malloc(maxlen);
+ unsigned char *buf = malloc(len);
+
+ memcpy(buf, str, len);
+ memset(key, 0, size);
+ do {
+ memcpy(tmp + l, buf, len);
+ l += len;
+ rr13(buf, len * 8);
+ while(l >= size) {
+ add1(key, tmp, size);
+ l -= size;
+ if(l == 0)
+ break;
+ memmove(tmp, tmp + size, l);
+ }
+ } while(l != 0);
+ memset(buf, 0, len);
+ free(buf);
+ memset(tmp, 0, maxlen);
+ free(tmp);
+}
diff --git a/crypto/heimdal/lib/krb5/net_read.c b/crypto/heimdal/lib/krb5/net_read.c
new file mode 100644
index 000000000000..8cb1dc4af331
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/net_read.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: net_read.c,v 1.5 1999/12/02 17:05:11 joda Exp $");
+
+ssize_t
+krb5_net_read (krb5_context context,
+ void *p_fd,
+ void *buf,
+ size_t len)
+{
+ int fd = *((int *)p_fd);
+
+ return net_read (fd, buf, len);
+}
diff --git a/crypto/heimdal/lib/krb5/net_write.c b/crypto/heimdal/lib/krb5/net_write.c
new file mode 100644
index 000000000000..5cc719ba8def
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/net_write.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: net_write.c,v 1.6 1999/12/02 17:05:11 joda Exp $");
+
+ssize_t
+krb5_net_write (krb5_context context,
+ void *p_fd,
+ const void *buf,
+ size_t len)
+{
+ int fd = *((int *)p_fd);
+
+ return net_write (fd, buf, len);
+}
diff --git a/crypto/heimdal/lib/krb5/padata.c b/crypto/heimdal/lib/krb5/padata.c
new file mode 100644
index 000000000000..bcf795255a34
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/padata.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: padata.c,v 1.2 1999/12/02 17:05:11 joda Exp $");
+
+PA_DATA *
+krb5_find_padata(PA_DATA *val, unsigned len, int type, int *index)
+{
+ for(; *index < len; (*index)++)
+ if(val[*index].padata_type == type)
+ return val + *index;
+ return NULL;
+}
diff --git a/crypto/heimdal/lib/krb5/principal.c b/crypto/heimdal/lib/krb5/principal.c
new file mode 100644
index 000000000000..3fd022d17603
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/principal.c
@@ -0,0 +1,898 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+#ifdef HAVE_RES_SEARCH
+#define USE_RESOLVER
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#include "resolve.h"
+
+RCSID("$Id: principal.c,v 1.57 2000/01/08 08:08:03 assar Exp $");
+
+#define princ_num_comp(P) ((P)->name.name_string.len)
+#define princ_type(P) ((P)->name.name_type)
+#define princ_comp(P) ((P)->name.name_string.val)
+#define princ_ncomp(P, N) ((P)->name.name_string.val[(N)])
+#define princ_realm(P) ((P)->realm)
+
+void
+krb5_free_principal(krb5_context context,
+ krb5_principal p)
+{
+ if(p){
+ free_Principal(p);
+ free(p);
+ }
+}
+
+krb5_error_code
+krb5_parse_name(krb5_context context,
+ const char *name,
+ krb5_principal *principal)
+{
+ krb5_error_code ret;
+ general_string *comp;
+ general_string realm;
+ int ncomp;
+
+ char *p;
+ char *q;
+ char *s;
+ char *start;
+
+ int n;
+ char c;
+ int got_realm = 0;
+
+ /* count number of component */
+ ncomp = 1;
+ for(p = (char*)name; *p; p++){
+ if(*p=='\\'){
+ if(!p[1])
+ return KRB5_PARSE_MALFORMED;
+ p++;
+ } else if(*p == '/')
+ ncomp++;
+ }
+ comp = calloc(ncomp, sizeof(*comp));
+ if (comp == NULL)
+ return ENOMEM;
+
+ n = 0;
+ start = q = p = s = strdup(name);
+ if (start == NULL) {
+ free (comp);
+ return ENOMEM;
+ }
+ while(*p){
+ c = *p++;
+ if(c == '\\'){
+ c = *p++;
+ if(c == 'n')
+ c = '\n';
+ else if(c == 't')
+ c = '\t';
+ else if(c == 'b')
+ c = '\b';
+ else if(c == '0')
+ c = '\0';
+ }else if(c == '/' || c == '@'){
+ if(got_realm){
+ ret = KRB5_PARSE_MALFORMED;
+ goto exit;
+ }else{
+ comp[n] = malloc(q - start + 1);
+ if (comp[n] == NULL) {
+ ret = ENOMEM;
+ goto exit;
+ }
+ strncpy(comp[n], start, q - start);
+ comp[n][q - start] = 0;
+ n++;
+ }
+ if(c == '@')
+ got_realm = 1;
+ start = q;
+ continue;
+ }
+ if(got_realm && (c == ':' || c == '/' || c == '\0')) {
+ ret = KRB5_PARSE_MALFORMED;
+ goto exit;
+ }
+ *q++ = c;
+ }
+ if(got_realm){
+ realm = malloc(q - start + 1);
+ if (realm == NULL) {
+ ret = ENOMEM;
+ goto exit;
+ }
+ strncpy(realm, start, q - start);
+ realm[q - start] = 0;
+ }else{
+ ret = krb5_get_default_realm (context, &realm);
+ if (ret)
+ goto exit;
+
+ comp[n] = malloc(q - start + 1);
+ if (comp[n] == NULL) {
+ ret = ENOMEM;
+ goto exit;
+ }
+ strncpy(comp[n], start, q - start);
+ comp[n][q - start] = 0;
+ n++;
+ }
+ *principal = malloc(sizeof(**principal));
+ if (*principal == NULL) {
+ ret = ENOMEM;
+ goto exit;
+ }
+ (*principal)->name.name_type = KRB5_NT_PRINCIPAL;
+ (*principal)->name.name_string.val = comp;
+ princ_num_comp(*principal) = n;
+ (*principal)->realm = realm;
+ free(s);
+ return 0;
+exit:
+ while(n>0){
+ free(comp[--n]);
+ }
+ free(comp);
+ free(s);
+ return ret;
+}
+
+static const char quotable_chars[] = "\n\t\b\\/@";
+static const char replace_chars[] = "ntb\\/@";
+
+#define add_char(BASE, INDEX, LEN, C) do { if((INDEX) < (LEN)) (BASE)[(INDEX)++] = (C); }while(0);
+
+static size_t
+quote_string(const char *s, char *out, size_t index, size_t len)
+{
+ const char *p, *q;
+ for(p = s; *p && index < len; p++){
+ if((q = strchr(quotable_chars, *p))){
+ add_char(out, index, len, '\\');
+ add_char(out, index, len, replace_chars[q - quotable_chars]);
+ }else
+ add_char(out, index, len, *p);
+ }
+ if(index < len)
+ out[index] = '\0';
+ return index;
+}
+
+
+static krb5_error_code
+unparse_name_fixed(krb5_context context,
+ krb5_const_principal principal,
+ char *name,
+ size_t len,
+ krb5_boolean short_form)
+{
+ size_t index = 0;
+ int i;
+ for(i = 0; i < princ_num_comp(principal); i++){
+ if(i)
+ add_char(name, index, len, '/');
+ index = quote_string(princ_ncomp(principal, i), name, index, len);
+ if(index == len)
+ return ERANGE;
+ }
+ /* add realm if different from default realm */
+ if(short_form) {
+ krb5_realm r;
+ krb5_error_code ret;
+ ret = krb5_get_default_realm(context, &r);
+ if(ret)
+ return ret;
+ if(strcmp(princ_realm(principal), r) != 0)
+ short_form = 0;
+ free(r);
+ }
+ if(!short_form) {
+ add_char(name, index, len, '@');
+ index = quote_string(princ_realm(principal), name, index, len);
+ if(index == len)
+ return ERANGE;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_unparse_name_fixed(krb5_context context,
+ krb5_const_principal principal,
+ char *name,
+ size_t len)
+{
+ return unparse_name_fixed(context, principal, name, len, FALSE);
+}
+
+krb5_error_code
+krb5_unparse_name_fixed_short(krb5_context context,
+ krb5_const_principal principal,
+ char *name,
+ size_t len)
+{
+ return unparse_name_fixed(context, principal, name, len, TRUE);
+}
+
+static krb5_error_code
+unparse_name(krb5_context context,
+ krb5_const_principal principal,
+ char **name,
+ krb5_boolean short_flag)
+{
+ size_t len = 0, plen;
+ int i;
+ krb5_error_code ret;
+ /* count length */
+ plen = strlen(princ_realm(principal));
+ if(strcspn(princ_realm(principal), quotable_chars) == plen)
+ len += plen;
+ else
+ len += 2*plen;
+ len++;
+ for(i = 0; i < princ_num_comp(principal); i++){
+ plen = strlen(princ_ncomp(principal, i));
+ if(strcspn(princ_ncomp(principal, i), quotable_chars) == plen)
+ len += plen;
+ else
+ len += 2*plen;
+ len++;
+ }
+ *name = malloc(len);
+ if(len != 0 && *name == NULL)
+ return ENOMEM;
+ ret = unparse_name_fixed(context, principal, *name, len, short_flag);
+ if(ret)
+ free(*name);
+ return ret;
+}
+
+krb5_error_code
+krb5_unparse_name(krb5_context context,
+ krb5_const_principal principal,
+ char **name)
+{
+ return unparse_name(context, principal, name, FALSE);
+}
+
+krb5_error_code
+krb5_unparse_name_short(krb5_context context,
+ krb5_const_principal principal,
+ char **name)
+{
+ return unparse_name(context, principal, name, TRUE);
+}
+
+#if 0 /* not implemented */
+
+krb5_error_code
+krb5_unparse_name_ext(krb5_context context,
+ krb5_const_principal principal,
+ char **name,
+ size_t *size)
+{
+ krb5_abortx(context, "unimplemented krb5_unparse_name_ext called");
+}
+
+#endif
+
+krb5_realm*
+krb5_princ_realm(krb5_context context,
+ krb5_principal principal)
+{
+ return &princ_realm(principal);
+}
+
+
+void
+krb5_princ_set_realm(krb5_context context,
+ krb5_principal principal,
+ krb5_realm *realm)
+{
+ princ_realm(principal) = *realm;
+}
+
+
+krb5_error_code
+krb5_build_principal(krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ ...)
+{
+ krb5_error_code ret;
+ va_list ap;
+ va_start(ap, realm);
+ ret = krb5_build_principal_va(context, principal, rlen, realm, ap);
+ va_end(ap);
+ return ret;
+}
+
+static krb5_error_code
+append_component(krb5_context context, krb5_principal p,
+ general_string comp,
+ size_t comp_len)
+{
+ general_string *tmp;
+ size_t len = princ_num_comp(p);
+ tmp = realloc(princ_comp(p), (len + 1) * sizeof(*tmp));
+ if(tmp == NULL)
+ return ENOMEM;
+ princ_comp(p) = tmp;
+ princ_ncomp(p, len) = malloc(comp_len + 1);
+ memcpy (princ_ncomp(p, len), comp, comp_len);
+ princ_ncomp(p, len)[comp_len] = '\0';
+ princ_num_comp(p)++;
+ return 0;
+}
+
+static void
+va_ext_princ(krb5_context context, krb5_principal p, va_list ap)
+{
+ while(1){
+ char *s;
+ int len;
+ len = va_arg(ap, int);
+ if(len == 0)
+ break;
+ s = va_arg(ap, char*);
+ append_component(context, p, s, len);
+ }
+}
+
+static void
+va_princ(krb5_context context, krb5_principal p, va_list ap)
+{
+ while(1){
+ char *s;
+ s = va_arg(ap, char*);
+ if(s == NULL)
+ break;
+ append_component(context, p, s, strlen(s));
+ }
+}
+
+
+static krb5_error_code
+build_principal(krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ void (*func)(krb5_context, krb5_principal, va_list),
+ va_list ap)
+{
+ krb5_principal p;
+
+ p = calloc(1, sizeof(*p));
+ if (p == NULL)
+ return ENOMEM;
+ princ_type(p) = KRB5_NT_PRINCIPAL;
+
+ princ_realm(p) = strdup(realm);
+ if(p->realm == NULL){
+ free(p);
+ return ENOMEM;
+ }
+
+ (*func)(context, p, ap);
+ *principal = p;
+ return 0;
+}
+
+krb5_error_code
+krb5_make_principal(krb5_context context,
+ krb5_principal *principal,
+ krb5_const_realm realm,
+ ...)
+{
+ krb5_error_code ret;
+ krb5_realm r = NULL;
+ va_list ap;
+ if(realm == NULL) {
+ ret = krb5_get_default_realm(context, &r);
+ if(ret)
+ return ret;
+ realm = r;
+ }
+ va_start(ap, realm);
+ ret = krb5_build_principal_va(context, principal, strlen(realm), realm, ap);
+ va_end(ap);
+ if(r)
+ free(r);
+ return ret;
+}
+
+krb5_error_code
+krb5_build_principal_va(krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ va_list ap)
+{
+ return build_principal(context, principal, rlen, realm, va_princ, ap);
+}
+
+krb5_error_code
+krb5_build_principal_va_ext(krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ va_list ap)
+{
+ return build_principal(context, principal, rlen, realm, va_ext_princ, ap);
+}
+
+
+krb5_error_code
+krb5_build_principal_ext(krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ ...)
+{
+ krb5_error_code ret;
+ va_list ap;
+ va_start(ap, realm);
+ ret = krb5_build_principal_va_ext(context, principal, rlen, realm, ap);
+ va_end(ap);
+ return ret;
+}
+
+
+krb5_error_code
+krb5_copy_principal(krb5_context context,
+ krb5_const_principal inprinc,
+ krb5_principal *outprinc)
+{
+ krb5_principal p = malloc(sizeof(*p));
+ if (p == NULL)
+ return ENOMEM;
+ if(copy_Principal(inprinc, p))
+ return ENOMEM;
+ *outprinc = p;
+ return 0;
+}
+
+
+krb5_boolean
+krb5_principal_compare_any_realm(krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2)
+{
+ int i;
+ if(princ_num_comp(princ1) != princ_num_comp(princ2))
+ return FALSE;
+ for(i = 0; i < princ_num_comp(princ1); i++){
+ if(strcmp(princ_ncomp(princ1, i), princ_ncomp(princ2, i)) != 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+krb5_boolean
+krb5_principal_compare(krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2)
+{
+ if(!krb5_realm_compare(context, princ1, princ2))
+ return FALSE;
+ return krb5_principal_compare_any_realm(context, princ1, princ2);
+}
+
+
+krb5_boolean
+krb5_realm_compare(krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2)
+{
+ return strcmp(princ_realm(princ1), princ_realm(princ2)) == 0;
+}
+
+struct v4_name_convert {
+ const char *from;
+ const char *to;
+} default_v4_name_convert[] = {
+ { "ftp", "ftp" },
+ { "hprop", "hprop" },
+ { "pop", "pop" },
+ { "rcmd", "host" },
+ { NULL, NULL }
+};
+
+static const char*
+get_name_conversion(krb5_context context, const char *realm, const char *name)
+{
+ struct v4_name_convert *q;
+ const char *p;
+ p = krb5_config_get_string(context, NULL, "realms", realm,
+ "v4_name_convert", "host", name, NULL);
+ if(p == NULL)
+ p = krb5_config_get_string(context, NULL, "libdefaults",
+ "v4_name_convert", "host", name, NULL);
+ if(p)
+ return p;
+
+ /* XXX should be possible to override default list */
+ p = krb5_config_get_string(context, NULL,
+ "realms",
+ realm,
+ "v4_name_convert",
+ "plain",
+ name,
+ NULL);
+ if(p)
+ return NULL;
+ p = krb5_config_get_string(context, NULL,
+ "libdefaults",
+ "v4_name_convert",
+ "plain",
+ name,
+ NULL);
+ if(p)
+ return NULL;
+ for(q = default_v4_name_convert; q->from; q++)
+ if(strcmp(q->from, name) == 0)
+ return q->to;
+ return NULL;
+}
+
+krb5_error_code
+krb5_425_conv_principal_ext(krb5_context context,
+ const char *name,
+ const char *instance,
+ const char *realm,
+ krb5_boolean (*func)(krb5_context, krb5_principal),
+ krb5_boolean resolve,
+ krb5_principal *princ)
+{
+ const char *p;
+ krb5_error_code ret;
+ krb5_principal pr;
+ char host[128];
+
+ /* do the following: if the name is found in the
+ `v4_name_convert:host' part, is is assumed to be a `host' type
+ principal, and the instance is looked up in the
+ `v4_instance_convert' part. if not found there the name is
+ (optionally) looked up as a hostname, and if that doesn't yield
+ anything, the `default_domain' is appended to the instance
+ */
+
+ if(instance == NULL)
+ goto no_host;
+ if(instance[0] == 0){
+ instance = NULL;
+ goto no_host;
+ }
+ p = get_name_conversion(context, realm, name);
+ if(p == NULL)
+ goto no_host;
+ name = p;
+ p = krb5_config_get_string(context, NULL, "realms", realm,
+ "v4_instance_convert", instance, NULL);
+ if(p){
+ instance = p;
+ ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
+ if(func == NULL || (*func)(context, pr)){
+ *princ = pr;
+ return 0;
+ }
+ krb5_free_principal(context, pr);
+ *princ = NULL;
+ return HEIM_ERR_V4_PRINC_NO_CONV;
+ }
+ if(resolve){
+ const char *inst = NULL;
+#ifdef USE_RESOLVER
+ struct dns_reply *r;
+ r = dns_lookup(instance, "a");
+ if(r && r->head && r->head->type == T_A)
+ inst = r->head->domain;
+#else
+ struct hostent *hp = roken_gethostbyname(instance);
+ if(hp)
+ inst = hp->h_name;
+#endif
+ if(inst) {
+ ret = krb5_make_principal(context, &pr, realm, name, inst, NULL);
+ if(ret == 0) {
+ if(func == NULL || (*func)(context, pr)){
+ *princ = pr;
+#ifdef USE_RESOLVER
+ dns_free_data(r);
+#endif
+ return 0;
+ }
+ krb5_free_principal(context, pr);
+ }
+ }
+#ifdef USE_RESOLVER
+ if(r)
+ dns_free_data(r);
+#endif
+ }
+ {
+ char **domains, **d;
+ domains = krb5_config_get_strings(context, NULL, "realms", realm,
+ "v4_domains", NULL);
+ for(d = domains; d && *d; d++){
+ snprintf(host, sizeof(host), "%s.%s", instance, *d);
+ ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
+ if(func == NULL || (*func)(context, pr)){
+ *princ = pr;
+ krb5_config_free_strings(domains);
+ return 0;
+ }
+ krb5_free_principal(context, pr);
+ }
+ krb5_config_free_strings(domains);
+ }
+
+
+ p = krb5_config_get_string(context, NULL, "realms", realm,
+ "default_domain", NULL);
+ if(p == NULL){
+ /* should this be an error or should it silently
+ succeed? */
+ return HEIM_ERR_V4_PRINC_NO_CONV;
+ }
+
+ if (*p == '.')
+ ++p;
+ snprintf(host, sizeof(host), "%s.%s", instance, p);
+ ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
+ if(func == NULL || (*func)(context, pr)){
+ *princ = pr;
+ return 0;
+ }
+ krb5_free_principal(context, pr);
+ return HEIM_ERR_V4_PRINC_NO_CONV;
+no_host:
+ p = krb5_config_get_string(context, NULL,
+ "realms",
+ realm,
+ "v4_name_convert",
+ "plain",
+ name,
+ NULL);
+ if(p == NULL)
+ p = krb5_config_get_string(context, NULL,
+ "libdefaults",
+ "v4_name_convert",
+ "plain",
+ name,
+ NULL);
+ if(p)
+ name = p;
+
+ ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
+ if(func == NULL || (*func)(context, pr)){
+ *princ = pr;
+ return 0;
+ }
+ krb5_free_principal(context, pr);
+ return HEIM_ERR_V4_PRINC_NO_CONV;
+}
+
+krb5_error_code
+krb5_425_conv_principal(krb5_context context,
+ const char *name,
+ const char *instance,
+ const char *realm,
+ krb5_principal *princ)
+{
+ krb5_boolean resolve = krb5_config_get_bool(context,
+ NULL,
+ "libdefaults",
+ "v4_instance_resolve",
+ NULL);
+
+ return krb5_425_conv_principal_ext(context, name, instance, realm,
+ NULL, resolve, princ);
+}
+
+
+static int
+check_list(const krb5_config_binding *l, const char *name, const char **out)
+{
+ while(l){
+ if (l->type != krb5_config_string)
+ continue;
+ if(strcmp(name, l->u.string) == 0) {
+ *out = l->name;
+ return 1;
+ }
+ l = l->next;
+ }
+ return 0;
+}
+
+static int
+name_convert(krb5_context context, const char *name, const char *realm,
+ const char **out)
+{
+ const krb5_config_binding *l;
+ l = krb5_config_get_list (context,
+ NULL,
+ "realms",
+ realm,
+ "v4_name_convert",
+ "host",
+ NULL);
+ if(l && check_list(l, name, out))
+ return KRB5_NT_SRV_HST;
+ l = krb5_config_get_list (context,
+ NULL,
+ "libdefaults",
+ "v4_name_convert",
+ "host",
+ NULL);
+ if(l && check_list(l, name, out))
+ return KRB5_NT_SRV_HST;
+ l = krb5_config_get_list (context,
+ NULL,
+ "realms",
+ realm,
+ "v4_name_convert",
+ "plain",
+ NULL);
+ if(l && check_list(l, name, out))
+ return KRB5_NT_UNKNOWN;
+ l = krb5_config_get_list (context,
+ NULL,
+ "libdefaults",
+ "v4_name_convert",
+ "host",
+ NULL);
+ if(l && check_list(l, name, out))
+ return KRB5_NT_UNKNOWN;
+
+ /* didn't find it in config file, try built-in list */
+ {
+ struct v4_name_convert *q;
+ for(q = default_v4_name_convert; q->from; q++) {
+ if(strcmp(name, q->to) == 0) {
+ *out = q->from;
+ return KRB5_NT_SRV_HST;
+ }
+ }
+ }
+ return -1;
+}
+
+krb5_error_code
+krb5_524_conv_principal(krb5_context context,
+ const krb5_principal principal,
+ char *name,
+ char *instance,
+ char *realm)
+{
+ const char *n, *i, *r;
+ char tmpinst[40];
+ int type = princ_type(principal);
+
+ r = principal->realm;
+
+ switch(principal->name.name_string.len){
+ case 1:
+ n = principal->name.name_string.val[0];
+ i = "";
+ break;
+ case 2:
+ n = principal->name.name_string.val[0];
+ i = principal->name.name_string.val[1];
+ break;
+ default:
+ return KRB5_PARSE_MALFORMED;
+ }
+
+ {
+ const char *tmp;
+ int t = name_convert(context, n, r, &tmp);
+ if(t >= 0) {
+ type = t;
+ n = tmp;
+ }
+ }
+
+ if(type == KRB5_NT_SRV_HST){
+ char *p;
+ strncpy(tmpinst, i, sizeof(tmpinst));
+ tmpinst[sizeof(tmpinst) - 1] = 0;
+ p = strchr(tmpinst, '.');
+ if(p) *p = 0;
+ i = tmpinst;
+ }
+
+ if(strlen(r) >= 40)
+ return KRB5_PARSE_MALFORMED;
+ if(strlen(n) >= 40)
+ return KRB5_PARSE_MALFORMED;
+ if(strlen(i) >= 40)
+ return KRB5_PARSE_MALFORMED;
+ strcpy(realm, r);
+ strcpy(name, n);
+ strcpy(instance, i);
+ return 0;
+}
+
+/*
+ * Create a principal in `ret_princ' for the service `sname' running
+ * on host `hostname'.
+ */
+
+krb5_error_code
+krb5_sname_to_principal (krb5_context context,
+ const char *hostname,
+ const char *sname,
+ int32_t type,
+ krb5_principal *ret_princ)
+{
+ krb5_error_code ret;
+ char localhost[128];
+ char **realms, *host = NULL;
+
+ if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN)
+ return KRB5_SNAME_UNSUPP_NAMETYPE;
+ if(hostname == NULL) {
+ gethostname(localhost, sizeof(localhost));
+ hostname = localhost;
+ }
+ if(sname == NULL)
+ sname = "host";
+ if(type == KRB5_NT_SRV_HST) {
+ ret = krb5_expand_hostname (context, hostname, &host);
+ if (ret)
+ return ret;
+ strlwr(host);
+ hostname = host;
+ }
+ ret = krb5_get_host_realm(context, hostname, &realms);
+ if(ret)
+ return ret;
+
+ ret = krb5_make_principal(context, ret_princ, realms[0], sname,
+ hostname, NULL);
+ if(host)
+ free(host);
+ krb5_free_host_realm(context, realms);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/prog_setup.c b/crypto/heimdal/lib/krb5/prog_setup.c
new file mode 100644
index 000000000000..4693d08a5e61
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/prog_setup.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+#include <getarg.h>
+
+RCSID("$Id: prog_setup.c,v 1.6 1999/12/02 17:05:11 joda Exp $");
+
+void
+krb5_std_usage(int code, struct getargs *args, int num_args)
+{
+ arg_printusage(args, num_args, NULL, "");
+ exit(code);
+}
+
+int
+krb5_program_setup(krb5_context *context, int argc, char **argv,
+ struct getargs *args, int num_args,
+ void (*usage)(int, struct getargs*, int))
+{
+ int optind = 0;
+
+ if(usage == NULL)
+ usage = krb5_std_usage;
+
+ set_progname(argv[0]);
+ krb5_init_context(context);
+
+ if(getarg(args, num_args, argc, argv, &optind))
+ (*usage)(1, args, num_args);
+ return optind;
+}
diff --git a/crypto/heimdal/lib/krb5/prompter_posix.c b/crypto/heimdal/lib/krb5/prompter_posix.c
new file mode 100644
index 000000000000..a8492541e30c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/prompter_posix.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: prompter_posix.c,v 1.5 1999/12/02 17:05:11 joda Exp $");
+
+int
+krb5_prompter_posix (krb5_context context,
+ void *data,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[])
+{
+ int i;
+
+ if (banner)
+ fprintf (stderr, "%s\n", banner);
+ for (i = 0; i < num_prompts; ++i) {
+ if (prompts[i].hidden) {
+ if(des_read_pw_string(prompts[i].reply->data,
+ prompts[i].reply->length,
+ prompts[i].prompt,
+ 0))
+ return 1;
+ } else {
+ char *s = prompts[i].reply->data;
+
+ fputs (prompts[i].prompt, stdout);
+ fflush (stdout);
+ if(fgets(prompts[i].reply->data,
+ prompts[i].reply->length,
+ stdin) == NULL)
+ return 1;
+ if(s[strlen(s) - 1] == '\n')
+ s[strlen(s) - 1] = '\0';
+ }
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/rd_cred.c b/crypto/heimdal/lib/krb5/rd_cred.c
new file mode 100644
index 000000000000..c33079167b66
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_cred.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: rd_cred.c,v 1.8 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_rd_cred (krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_ccache ccache,
+ krb5_data *in_data)
+{
+ krb5_error_code ret;
+ size_t len;
+ KRB_CRED cred;
+ EncKrbCredPart enc_krb_cred_part;
+ krb5_data enc_krb_cred_part_data;
+ krb5_crypto crypto;
+ int i;
+
+ ret = decode_KRB_CRED (in_data->data, in_data->length,
+ &cred, &len);
+ if (ret)
+ return ret;
+
+ if (cred.pvno != 5) {
+ ret = KRB5KRB_AP_ERR_BADVERSION;
+ goto out;
+ }
+
+ if (cred.msg_type != krb_cred) {
+ ret = KRB5KRB_AP_ERR_MSG_TYPE;
+ goto out;
+ }
+
+ krb5_crypto_init(context, auth_context->remote_subkey, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_KRB_CRED,
+ &cred.enc_part,
+ &enc_krb_cred_part_data);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ goto out;
+
+
+ ret = krb5_decode_EncKrbCredPart (context,
+ enc_krb_cred_part_data.data,
+ enc_krb_cred_part_data.length,
+ &enc_krb_cred_part,
+ &len);
+ if (ret)
+ goto out;
+
+ /* check sender address */
+
+ if (enc_krb_cred_part.s_address
+ && auth_context->remote_address) {
+ krb5_address *a;
+ int cmp;
+
+ ret = krb5_make_addrport (&a,
+ auth_context->remote_address,
+ auth_context->remote_port);
+ if (ret)
+ goto out;
+
+
+ cmp = krb5_address_compare (context,
+ a,
+ enc_krb_cred_part.s_address);
+
+ krb5_free_address (context, a);
+ free (a);
+
+ if (cmp == 0) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto out;
+ }
+ }
+
+ /* check receiver address */
+
+ if (enc_krb_cred_part.r_address
+ && !krb5_address_compare (context,
+ auth_context->local_address,
+ enc_krb_cred_part.r_address)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto out;
+ }
+
+ /* check timestamp */
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
+ int32_t sec;
+
+ krb5_timeofday (context, &sec);
+
+ if (enc_krb_cred_part.timestamp == NULL ||
+ enc_krb_cred_part.usec == NULL ||
+ abs(*enc_krb_cred_part.timestamp - sec)
+ > context->max_skew) {
+ ret = KRB5KRB_AP_ERR_SKEW;
+ goto out;
+ }
+ }
+
+ /* XXX - check replay cache */
+
+ /* Store the creds in the ccache */
+
+ for (i = 0; i < enc_krb_cred_part.ticket_info.len; ++i) {
+ KrbCredInfo *kci = &enc_krb_cred_part.ticket_info.val[i];
+ krb5_creds creds;
+ u_char buf[1024];
+ size_t len;
+
+ memset (&creds, 0, sizeof(creds));
+
+ ret = encode_Ticket (buf + sizeof(buf) - 1, sizeof(buf),
+ &cred.tickets.val[i],
+ &len);
+ if (ret)
+ goto out;
+ krb5_data_copy (&creds.ticket, buf + sizeof(buf) - len, len);
+ copy_EncryptionKey (&kci->key, &creds.session);
+ if (kci->prealm && kci->pname)
+ principalname2krb5_principal (&creds.client,
+ *kci->pname,
+ *kci->prealm);
+ if (kci->flags)
+ creds.flags.b = *kci->flags;
+ if (kci->authtime)
+ creds.times.authtime = *kci->authtime;
+ if (kci->starttime)
+ creds.times.starttime = *kci->starttime;
+ if (kci->endtime)
+ creds.times.endtime = *kci->endtime;
+ if (kci->renew_till)
+ creds.times.renew_till = *kci->renew_till;
+ if (kci->srealm && kci->sname)
+ principalname2krb5_principal (&creds.server,
+ *kci->sname,
+ *kci->srealm);
+ if (kci->caddr)
+ krb5_copy_addresses (context,
+ kci->caddr,
+ &creds.addresses);
+ krb5_cc_store_cred (context, ccache, &creds);
+ }
+
+out:
+ free_KRB_CRED (&cred);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/rd_error.c b/crypto/heimdal/lib/krb5/rd_error.c
new file mode 100644
index 000000000000..df9b45e264d8
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_error.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: rd_error.c,v 1.4 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_rd_error(krb5_context context,
+ krb5_data *msg,
+ KRB_ERROR *result)
+{
+
+ size_t len;
+ krb5_error_code ret;
+ ret = decode_KRB_ERROR(msg->data, msg->length, result, &len);
+ if(ret)
+ return ret;
+ result->error_code += KRB5KDC_ERR_NONE;
+ return 0;
+}
+
+void
+krb5_free_error_contents (krb5_context context,
+ krb5_error *error)
+{
+ free_KRB_ERROR(error);
+}
+
+void
+krb5_free_error (krb5_context context,
+ krb5_error *error)
+{
+ krb5_free_error_contents (context, error);
+ free (error);
+}
diff --git a/crypto/heimdal/lib/krb5/rd_priv.c b/crypto/heimdal/lib/krb5/rd_priv.c
new file mode 100644
index 000000000000..0bc85642bde2
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_priv.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: rd_priv.c,v 1.22 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_rd_priv(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_data *outbuf,
+ /*krb5_replay_data*/ void *outdata)
+{
+ krb5_error_code ret;
+ KRB_PRIV priv;
+ EncKrbPrivPart part;
+ size_t len;
+ krb5_data plain;
+ krb5_keyblock *key;
+ krb5_crypto crypto;
+
+ memset(&priv, 0, sizeof(priv));
+ ret = decode_KRB_PRIV (inbuf->data, inbuf->length, &priv, &len);
+ if (ret)
+ goto failure;
+ if (priv.pvno != 5) {
+ ret = KRB5KRB_AP_ERR_BADVERSION;
+ goto failure;
+ }
+ if (priv.msg_type != krb_priv) {
+ ret = KRB5KRB_AP_ERR_MSG_TYPE;
+ goto failure;
+ }
+
+ /* XXX - Is this right? */
+
+ if (auth_context->local_subkey)
+ key = auth_context->local_subkey;
+ else if (auth_context->remote_subkey)
+ key = auth_context->remote_subkey;
+ else
+ key = auth_context->keyblock;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_KRB_PRIV,
+ &priv.enc_part,
+ &plain);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ goto failure;
+
+ ret = decode_EncKrbPrivPart (plain.data, plain.length, &part, &len);
+ krb5_data_free (&plain);
+ if (ret)
+ goto failure;
+
+ /* check sender address */
+
+ if (part.s_address
+ && auth_context->remote_address
+ && !krb5_address_compare (context,
+ auth_context->remote_address,
+ part.s_address)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto failure_part;
+ }
+
+ /* check receiver address */
+
+ if (part.r_address
+ && auth_context->local_address
+ && !krb5_address_compare (context,
+ auth_context->local_address,
+ part.r_address)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto failure_part;
+ }
+
+ /* check timestamp */
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
+ int32_t sec;
+
+ krb5_timeofday (context, &sec);
+ if (part.timestamp == NULL ||
+ part.usec == NULL ||
+ abs(*part.timestamp - sec) > context->max_skew) {
+ ret = KRB5KRB_AP_ERR_SKEW;
+ goto failure_part;
+ }
+ }
+
+ /* XXX - check replay cache */
+
+ /* check sequence number */
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ if (part.seq_number == NULL ||
+ *part.seq_number != ++auth_context->remote_seqnumber) {
+ ret = KRB5KRB_AP_ERR_BADORDER;
+ goto failure_part;
+ }
+ }
+
+ ret = krb5_data_copy (outbuf, part.user_data.data, part.user_data.length);
+ if (ret)
+ goto failure_part;
+
+ free_EncKrbPrivPart (&part);
+ free_KRB_PRIV (&priv);
+ return 0;
+
+failure_part:
+ free_EncKrbPrivPart (&part);
+
+failure:
+ free_KRB_PRIV (&priv);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/rd_rep.c b/crypto/heimdal/lib/krb5/rd_rep.c
new file mode 100644
index 000000000000..e2c401c33919
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_rep.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: rd_rep.c,v 1.19 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_rd_rep(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_ap_rep_enc_part **repl)
+{
+ krb5_error_code ret;
+ AP_REP ap_rep;
+ size_t len;
+ krb5_data data;
+ krb5_crypto crypto;
+
+ krb5_data_zero (&data);
+ ret = 0;
+
+ ret = decode_AP_REP(inbuf->data, inbuf->length, &ap_rep, &len);
+ if (ret)
+ return ret;
+ if (ap_rep.pvno != 5) {
+ ret = KRB5KRB_AP_ERR_BADVERSION;
+ goto out;
+ }
+ if (ap_rep.msg_type != krb_ap_rep) {
+ ret = KRB5KRB_AP_ERR_MSG_TYPE;
+ goto out;
+ }
+
+ krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_AP_REQ_ENC_PART,
+ &ap_rep.enc_part,
+ &data);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ goto out;
+
+ *repl = malloc(sizeof(**repl));
+ if (*repl == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret = krb5_decode_EncAPRepPart(context,
+ data.data,
+ data.length,
+ *repl,
+ &len);
+ if (ret)
+ return ret;
+
+ if ((*repl)->ctime != auth_context->authenticator->ctime ||
+ (*repl)->cusec != auth_context->authenticator->cusec) {
+ ret = KRB5KRB_AP_ERR_MUT_FAIL;
+ goto out;
+ }
+ if ((*repl)->seq_number)
+ auth_context->remote_seqnumber = *((*repl)->seq_number);
+
+out:
+ krb5_data_free (&data);
+ free_AP_REP (&ap_rep);
+ return ret;
+}
+
+void
+krb5_free_ap_rep_enc_part (krb5_context context,
+ krb5_ap_rep_enc_part *val)
+{
+ free_EncAPRepPart (val);
+ free (val);
+}
diff --git a/crypto/heimdal/lib/krb5/rd_req.c b/crypto/heimdal/lib/krb5/rd_req.c
new file mode 100644
index 000000000000..9f8df1d6f327
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_req.c
@@ -0,0 +1,441 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: rd_req.c,v 1.38 1999/12/02 17:05:12 joda Exp $");
+
+static krb5_error_code
+decrypt_tkt_enc_part (krb5_context context,
+ krb5_keyblock *key,
+ EncryptedData *enc_part,
+ EncTicketPart *decr_part)
+{
+ krb5_error_code ret;
+ krb5_data plain;
+ size_t len;
+ krb5_crypto crypto;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_TICKET,
+ enc_part,
+ &plain);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ return ret;
+
+ ret = krb5_decode_EncTicketPart(context, plain.data, plain.length,
+ decr_part, &len);
+ krb5_data_free (&plain);
+ return ret;
+}
+
+static krb5_error_code
+decrypt_authenticator (krb5_context context,
+ EncryptionKey *key,
+ EncryptedData *enc_part,
+ Authenticator *authenticator)
+{
+ krb5_error_code ret;
+ krb5_data plain;
+ size_t len;
+ krb5_crypto crypto;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_AP_REQ_AUTH,
+ enc_part,
+ &plain);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ return ret;
+
+ ret = krb5_decode_Authenticator(context, plain.data, plain.length,
+ authenticator, &len);
+ krb5_data_free (&plain);
+ return ret;
+}
+
+krb5_error_code
+krb5_decode_ap_req(krb5_context context,
+ const krb5_data *inbuf,
+ krb5_ap_req *ap_req)
+{
+ krb5_error_code ret;
+ size_t len;
+ ret = decode_AP_REQ(inbuf->data, inbuf->length, ap_req, &len);
+ if (ret)
+ return ret;
+ if (ap_req->pvno != 5){
+ free_AP_REQ(ap_req);
+ return KRB5KRB_AP_ERR_BADVERSION;
+ }
+ if (ap_req->msg_type != krb_ap_req){
+ free_AP_REQ(ap_req);
+ return KRB5KRB_AP_ERR_MSG_TYPE;
+ }
+ if (ap_req->ticket.tkt_vno != 5){
+ free_AP_REQ(ap_req);
+ return KRB5KRB_AP_ERR_BADVERSION;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_decrypt_ticket(krb5_context context,
+ Ticket *ticket,
+ krb5_keyblock *key,
+ EncTicketPart *out,
+ krb5_flags flags)
+{
+ EncTicketPart t;
+ krb5_error_code ret;
+ ret = decrypt_tkt_enc_part (context, key, &ticket->enc_part, &t);
+ if (ret)
+ return ret;
+
+ {
+ int32_t now;
+ time_t start = t.authtime;
+
+ krb5_timeofday (context, &now);
+ if(t.starttime)
+ start = *t.starttime;
+ if(start - now > context->max_skew
+ || (t.flags.invalid
+ && !(flags & KRB5_VERIFY_AP_REQ_IGNORE_INVALID)))
+ return KRB5KRB_AP_ERR_TKT_NYV;
+ if(now - t.endtime > context->max_skew)
+ return KRB5KRB_AP_ERR_TKT_EXPIRED;
+ }
+
+ if(out)
+ *out = t;
+ else
+ free_EncTicketPart(&t);
+ return 0;
+}
+
+krb5_error_code
+krb5_verify_authenticator_checksum(krb5_context context,
+ krb5_auth_context ac,
+ void *data,
+ size_t len)
+{
+ krb5_error_code ret;
+ krb5_keyblock *key;
+ krb5_authenticator authenticator;
+ krb5_crypto crypto;
+
+ ret = krb5_auth_getauthenticator (context,
+ ac,
+ &authenticator);
+ if(ret)
+ return ret;
+ if(authenticator->cksum == NULL)
+ return -17;
+ ret = krb5_auth_con_getkey(context, ac, &key);
+ if(ret) {
+ krb5_free_authenticator(context, &authenticator);
+ return ret;
+ }
+ ret = krb5_crypto_init(context, key, 0, &crypto);
+ if(ret)
+ goto out;
+ ret = krb5_verify_checksum (context,
+ crypto,
+ KRB5_KU_AP_REQ_AUTH_CKSUM,
+ data,
+ len,
+ authenticator->cksum);
+ krb5_crypto_destroy(context, crypto);
+out:
+ krb5_free_authenticator(context, &authenticator);
+ krb5_free_keyblock(context, key);
+ return ret;
+}
+
+krb5_error_code
+krb5_verify_ap_req(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_ap_req *ap_req,
+ krb5_const_principal server,
+ krb5_keyblock *keyblock,
+ krb5_flags flags,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket)
+{
+ krb5_ticket t;
+ krb5_auth_context ac;
+ krb5_error_code ret;
+
+ if(auth_context){
+ if(*auth_context == NULL){
+ krb5_auth_con_init(context, &ac);
+ *auth_context = ac;
+ }else
+ ac = *auth_context;
+ }else
+ krb5_auth_con_init(context, &ac);
+
+ if (ap_req->ap_options.use_session_key && ac->keyblock){
+ ret = krb5_decrypt_ticket(context, &ap_req->ticket,
+ ac->keyblock,
+ &t.ticket,
+ flags);
+ krb5_free_keyblock(context, ac->keyblock);
+ ac->keyblock = NULL;
+ }else
+ ret = krb5_decrypt_ticket(context, &ap_req->ticket,
+ keyblock,
+ &t.ticket,
+ flags);
+
+ if(ret)
+ return ret;
+
+ principalname2krb5_principal(&t.server, ap_req->ticket.sname,
+ ap_req->ticket.realm);
+ principalname2krb5_principal(&t.client, t.ticket.cname,
+ t.ticket.crealm);
+
+ /* save key */
+
+ krb5_copy_keyblock(context, &t.ticket.key, &ac->keyblock);
+
+ ret = decrypt_authenticator (context,
+ &t.ticket.key,
+ &ap_req->authenticator,
+ ac->authenticator);
+ if (ret){
+ /* XXX free data */
+ return ret;
+ }
+
+ {
+ krb5_principal p1, p2;
+ krb5_boolean res;
+
+ principalname2krb5_principal(&p1,
+ ac->authenticator->cname,
+ ac->authenticator->crealm);
+ principalname2krb5_principal(&p2,
+ t.ticket.cname,
+ t.ticket.crealm);
+ res = krb5_principal_compare (context, p1, p2);
+ krb5_free_principal (context, p1);
+ krb5_free_principal (context, p2);
+ if (!res)
+ return KRB5KRB_AP_ERR_BADMATCH;
+ }
+
+ /* check addresses */
+
+ if (t.ticket.caddr
+ && ac->remote_address
+ && !krb5_address_search (context,
+ ac->remote_address,
+ t.ticket.caddr))
+ return KRB5KRB_AP_ERR_BADADDR;
+
+ if (ac->authenticator->seq_number)
+ ac->remote_seqnumber = *ac->authenticator->seq_number;
+
+ /* XXX - Xor sequence numbers */
+
+ /* XXX - subkeys? */
+ /* And where should it be stored? */
+
+ if (ac->authenticator->subkey) {
+ krb5_copy_keyblock(context,
+ ac->authenticator->subkey,
+ &ac->remote_subkey);
+ }
+
+ if (ap_req_options) {
+ *ap_req_options = 0;
+ if (ap_req->ap_options.use_session_key)
+ *ap_req_options |= AP_OPTS_USE_SESSION_KEY;
+ if (ap_req->ap_options.mutual_required)
+ *ap_req_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+
+ if(ticket){
+ *ticket = malloc(sizeof(**ticket));
+ **ticket = t;
+ } else
+ krb5_free_ticket (context, &t);
+ return 0;
+}
+
+
+krb5_error_code
+krb5_rd_req_with_keyblock(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_data *inbuf,
+ krb5_const_principal server,
+ krb5_keyblock *keyblock,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket)
+{
+ krb5_error_code ret;
+ krb5_ap_req ap_req;
+
+ if (*auth_context == NULL) {
+ ret = krb5_auth_con_init(context, auth_context);
+ if (ret)
+ return ret;
+ }
+
+ ret = krb5_decode_ap_req(context, inbuf, &ap_req);
+ if(ret)
+ return ret;
+
+ ret = krb5_verify_ap_req(context,
+ auth_context,
+ &ap_req,
+ server,
+ keyblock,
+ 0,
+ ap_req_options,
+ ticket);
+
+ free_AP_REQ(&ap_req);
+ return ret;
+}
+
+static krb5_error_code
+get_key_from_keytab(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_ap_req *ap_req,
+ krb5_const_principal server,
+ krb5_keytab keytab,
+ krb5_keyblock **out)
+{
+ krb5_keytab_entry entry;
+ krb5_error_code ret;
+ int kvno;
+ krb5_keytab real_keytab;
+
+ if(keytab == NULL)
+ krb5_kt_default(context, &real_keytab);
+ else
+ real_keytab = keytab;
+
+ if (ap_req->ticket.enc_part.kvno)
+ kvno = *ap_req->ticket.enc_part.kvno;
+ else
+ kvno = 0;
+
+ ret = krb5_kt_get_entry (context,
+ real_keytab,
+ server,
+ kvno,
+ ap_req->ticket.enc_part.etype,
+ &entry);
+ if(ret)
+ goto out;
+ ret = krb5_copy_keyblock(context, &entry.keyblock, out);
+ krb5_kt_free_entry (context, &entry);
+out:
+ if(keytab == NULL)
+ krb5_kt_close(context, real_keytab);
+
+ return ret;
+}
+
+krb5_error_code
+krb5_rd_req(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_data *inbuf,
+ krb5_const_principal server,
+ krb5_keytab keytab,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket)
+{
+ krb5_error_code ret;
+ krb5_ap_req ap_req;
+ krb5_keyblock *keyblock = NULL;
+ krb5_principal service = NULL;
+
+ if (*auth_context == NULL) {
+ ret = krb5_auth_con_init(context, auth_context);
+ if (ret)
+ return ret;
+ }
+
+ ret = krb5_decode_ap_req(context, inbuf, &ap_req);
+ if(ret)
+ return ret;
+
+ if(server == NULL){
+ principalname2krb5_principal(&service,
+ ap_req.ticket.sname,
+ ap_req.ticket.realm);
+ server = service;
+ }
+
+ if(ap_req.ap_options.use_session_key == 0 ||
+ (*auth_context)->keyblock == NULL){
+ ret = get_key_from_keytab(context,
+ auth_context,
+ &ap_req,
+ server,
+ keytab,
+ &keyblock);
+ if(ret)
+ goto out;
+ }
+
+
+ ret = krb5_verify_ap_req(context,
+ auth_context,
+ &ap_req,
+ server,
+ keyblock,
+ 0,
+ ap_req_options,
+ ticket);
+
+ if(keyblock != NULL)
+ krb5_free_keyblock(context, keyblock);
+
+out:
+ free_AP_REQ(&ap_req);
+ if(service)
+ krb5_free_principal(context, service);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/rd_safe.c b/crypto/heimdal/lib/krb5/rd_safe.c
new file mode 100644
index 000000000000..aebf215b266b
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_safe.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: rd_safe.c,v 1.18 1999/12/02 17:05:12 joda Exp $");
+
+static krb5_error_code
+verify_checksum(krb5_context context,
+ krb5_auth_context auth_context,
+ KRB_SAFE *safe)
+{
+ krb5_error_code ret;
+ u_char *buf;
+ size_t buf_size;
+ size_t len;
+ Checksum c;
+ krb5_crypto crypto;
+
+ c = safe->cksum;
+ safe->cksum.cksumtype = 0;
+ safe->cksum.checksum.data = NULL;
+ safe->cksum.checksum.length = 0;
+
+
+ buf_size = length_KRB_SAFE(safe);
+ buf = malloc(buf_size);
+
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = encode_KRB_SAFE (buf + buf_size - 1,
+ buf_size,
+ safe,
+ &len);
+ krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
+ ret = krb5_verify_checksum (context,
+ crypto,
+ KRB5_KU_KRB_SAFE_CKSUM,
+ buf + buf_size - len,
+ len,
+ &c);
+ krb5_crypto_destroy(context, crypto);
+out:
+ safe->cksum = c;
+ free (buf);
+ return ret;
+}
+
+krb5_error_code
+krb5_rd_safe(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_data *outbuf,
+ /*krb5_replay_data*/ void *outdata)
+{
+ krb5_error_code ret;
+ KRB_SAFE safe;
+ size_t len;
+
+ ret = decode_KRB_SAFE (inbuf->data, inbuf->length, &safe, &len);
+ if (ret)
+ return ret;
+ if (safe.pvno != 5) {
+ ret = KRB5KRB_AP_ERR_BADVERSION;
+ goto failure;
+ }
+ if (safe.msg_type != krb_safe) {
+ ret = KRB5KRB_AP_ERR_MSG_TYPE;
+ goto failure;
+ }
+ if (!krb5_checksum_is_keyed(context, safe.cksum.cksumtype)
+ || !krb5_checksum_is_collision_proof(context, safe.cksum.cksumtype)) {
+ ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
+ goto failure;
+ }
+
+ /* check sender address */
+
+ if (safe.safe_body.s_address
+ && auth_context->remote_address
+ && !krb5_address_compare (context,
+ auth_context->remote_address,
+ safe.safe_body.s_address)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto failure;
+ }
+
+ /* check receiver address */
+
+ if (safe.safe_body.r_address
+ && auth_context->local_address
+ && !krb5_address_compare (context,
+ auth_context->local_address,
+ safe.safe_body.r_address)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto failure;
+ }
+
+ /* check timestamp */
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
+ int32_t sec;
+
+ krb5_timeofday (context, &sec);
+
+ if (safe.safe_body.timestamp == NULL ||
+ safe.safe_body.usec == NULL ||
+ abs(*safe.safe_body.timestamp - sec) > context->max_skew) {
+ ret = KRB5KRB_AP_ERR_SKEW;
+ goto failure;
+ }
+ }
+ /* XXX - check replay cache */
+
+ /* check sequence number */
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ if (safe.safe_body.seq_number == NULL ||
+ *safe.safe_body.seq_number != ++auth_context->remote_seqnumber) {
+ ret = KRB5KRB_AP_ERR_BADORDER;
+ goto failure;
+ }
+ }
+
+ ret = verify_checksum (context, auth_context, &safe);
+ if (ret)
+ goto failure;
+
+ outbuf->length = safe.safe_body.user_data.length;
+ outbuf->data = malloc(outbuf->length);
+ if (outbuf->data == NULL) {
+ ret = ENOMEM;
+ goto failure;
+ }
+ memcpy (outbuf->data, safe.safe_body.user_data.data, outbuf->length);
+ free_KRB_SAFE (&safe);
+ return 0;
+failure:
+ free_KRB_SAFE (&safe);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/read_message.c b/crypto/heimdal/lib/krb5/read_message.c
new file mode 100644
index 000000000000..f2cae03d06bb
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/read_message.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: read_message.c,v 1.5 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_read_message (krb5_context context,
+ krb5_pointer p_fd,
+ krb5_data *data)
+{
+ krb5_error_code ret;
+ u_int32_t len;
+ u_int8_t buf[4];
+
+ ret = krb5_net_read (context, p_fd, buf, 4);
+ if(ret == -1)
+ return errno;
+ if(ret < 4) {
+ data->length = 0;
+ return 0;
+ }
+ len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+ ret = krb5_data_alloc (data, len);
+ if (ret)
+ return ret;
+ if (krb5_net_read (context, p_fd, data->data, len) != len) {
+ krb5_data_free (data);
+ return errno;
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/recvauth.c b/crypto/heimdal/lib/krb5/recvauth.c
new file mode 100644
index 000000000000..49fe7b66f9f1
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/recvauth.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: recvauth.c,v 1.12 1999/12/02 17:05:12 joda Exp $");
+
+/*
+ * See `sendauth.c' for the format.
+ */
+
+static krb5_boolean
+match_exact(void *data, const char *appl_version)
+{
+ return strcmp(data, appl_version) == 0;
+}
+
+krb5_error_code
+krb5_recvauth(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ char *appl_version,
+ krb5_principal server,
+ int32_t flags,
+ krb5_keytab keytab,
+ krb5_ticket **ticket)
+{
+ return krb5_recvauth_match_version(context, auth_context, p_fd,
+ match_exact, appl_version,
+ server, flags,
+ keytab, ticket);
+}
+
+krb5_error_code
+krb5_recvauth_match_version(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ krb5_boolean (*match_appl_version)(void *,
+ const char*),
+ void *match_data,
+ krb5_principal server,
+ int32_t flags,
+ krb5_keytab keytab,
+ krb5_ticket **ticket)
+{
+ krb5_error_code ret;
+ const char *version = KRB5_SENDAUTH_VERSION;
+ char her_version[sizeof(KRB5_SENDAUTH_VERSION)];
+ char *her_appl_version;
+ u_int32_t len;
+ u_char repl;
+ krb5_data data;
+ krb5_flags ap_options;
+ ssize_t n;
+
+ /*
+ * If there are no addresses in auth_context, get them from `fd'.
+ */
+
+ if (*auth_context == NULL) {
+ ret = krb5_auth_con_init (context, auth_context);
+ if (ret)
+ return ret;
+ }
+
+ ret = krb5_auth_con_setaddrs_from_fd (context,
+ *auth_context,
+ p_fd);
+ if (ret)
+ return ret;
+
+ if(!(flags & KRB5_RECVAUTH_IGNORE_VERSION)) {
+ n = krb5_net_read (context, p_fd, &len, 4);
+ if (n < 0)
+ return errno;
+ if (n == 0)
+ return KRB5_SENDAUTH_BADAUTHVERS;
+ len = ntohl(len);
+ if (len != sizeof(her_version)
+ || krb5_net_read (context, p_fd, her_version, len) != len
+ || strncmp (version, her_version, len)) {
+ repl = 1;
+ krb5_net_write (context, p_fd, &repl, 1);
+ return KRB5_SENDAUTH_BADAUTHVERS;
+ }
+ }
+
+ n = krb5_net_read (context, p_fd, &len, 4);
+ if (n < 0)
+ return errno;
+ if (n == 0)
+ return KRB5_SENDAUTH_BADAPPLVERS;
+ len = ntohl(len);
+ her_appl_version = malloc (len);
+ if (her_appl_version == NULL) {
+ repl = 2;
+ krb5_net_write (context, p_fd, &repl, 1);
+ return ENOMEM;
+ }
+ if (krb5_net_read (context, p_fd, her_appl_version, len) != len
+ || !(*match_appl_version)(match_data, her_appl_version)) {
+ repl = 2;
+ krb5_net_write (context, p_fd, &repl, 1);
+ free (her_appl_version);
+ return KRB5_SENDAUTH_BADAPPLVERS;
+ }
+ free (her_appl_version);
+
+ repl = 0;
+ if (krb5_net_write (context, p_fd, &repl, 1) != 1)
+ return errno;
+
+ krb5_data_zero (&data);
+ ret = krb5_read_message (context, p_fd, &data);
+ if (ret)
+ return ret;
+
+ ret = krb5_rd_req (context,
+ auth_context,
+ &data,
+ server,
+ keytab,
+ &ap_options,
+ ticket);
+ krb5_data_free (&data);
+ if (ret) {
+ krb5_data error_data;
+ krb5_error_code ret2;
+
+ ret2 = krb5_mk_error (context,
+ ret,
+ NULL,
+ NULL,
+ NULL,
+ server,
+ 0,
+ &error_data);
+ if (ret2 == 0) {
+ krb5_write_message (context, p_fd, &error_data);
+ krb5_data_free (&error_data);
+ }
+ return ret;
+ }
+
+ len = 0;
+ if (krb5_net_write (context, p_fd, &len, 4) != 4)
+ return errno;
+
+ if (ap_options & AP_OPTS_MUTUAL_REQUIRED) {
+ ret = krb5_mk_rep (context, auth_context, &data);
+ if (ret)
+ return ret;
+
+ ret = krb5_write_message (context, p_fd, &data);
+ if (ret)
+ return ret;
+ krb5_data_free (&data);
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/replay.c b/crypto/heimdal/lib/krb5/replay.c
new file mode 100644
index 000000000000..5adc3db159b4
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/replay.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+struct krb5_rcache_data {
+ char *name;
+};
+
+krb5_error_code
+krb5_rc_resolve(krb5_context context,
+ krb5_rcache id,
+ const char *name)
+{
+ id->name = strdup(name);
+ if(id->name == NULL)
+ return KRB5_RC_MALLOC;
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_resolve_type(krb5_context context,
+ krb5_rcache *id,
+ const char *type)
+{
+ if(strcmp(type, "FILE"))
+ return KRB5_RC_TYPE_NOTFOUND;
+ *id = calloc(1, sizeof(**id));
+ if(*id == NULL)
+ return KRB5_RC_MALLOC;
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_resolve_full(krb5_context context,
+ krb5_rcache *id,
+ const char *string_name)
+{
+ krb5_error_code ret;
+ if(strncmp(string_name, "FILE:", 5))
+ return KRB5_RC_TYPE_NOTFOUND;
+ ret = krb5_rc_resolve_type(context, id, "FILE");
+ if(ret)
+ return ret;
+ ret = krb5_rc_resolve(context, *id, string_name + 5);
+ return ret;
+}
+
+const char *
+krb5_rc_default_name(krb5_context context)
+{
+ return "FILE:/var/run/default_rcache";
+}
+
+krb5_error_code
+krb5_rc_default(krb5_context context,
+ krb5_rcache *id)
+{
+ return krb5_rc_resolve_full(context, id, krb5_rc_default_name(context));
+}
+
+struct rc_entry{
+ time_t stamp;
+ unsigned char data[16];
+};
+
+krb5_error_code
+krb5_rc_initialize(krb5_context context,
+ krb5_rcache id,
+ krb5_deltat auth_lifespan)
+{
+ FILE *f = fopen(id->name, "w");
+ struct rc_entry tmp;
+ if(f == NULL)
+ return errno;
+ tmp.stamp = auth_lifespan;
+ fwrite(&tmp, 1, sizeof(tmp), f);
+ fclose(f);
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_recover(krb5_context context,
+ krb5_rcache id)
+{
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_destroy(krb5_context context,
+ krb5_rcache id)
+{
+ if(remove(id->name) < 0)
+ return errno;
+ return krb5_rc_close(context, id);
+}
+
+krb5_error_code
+krb5_rc_close(krb5_context context,
+ krb5_rcache id)
+{
+ free(id->name);
+ free(id);
+ return 0;
+}
+
+static void
+checksum_authenticator(Authenticator *auth, void *data)
+{
+ struct md5 md5;
+ int i;
+ md5_init(&md5);
+ md5_update(&md5, auth->crealm, strlen(auth->crealm));
+ for(i = 0; i < auth->cname.name_string.len; i++)
+ md5_update(&md5, auth->cname.name_string.val[i],
+ strlen(auth->cname.name_string.val[i]));
+ md5_update(&md5, &auth->ctime, sizeof(auth->ctime));
+ md5_update(&md5, &auth->cusec, sizeof(auth->cusec));
+ md5_finito(&md5, data);
+}
+
+krb5_error_code
+krb5_rc_store(krb5_context context,
+ krb5_rcache id,
+ krb5_donot_reply *rep)
+{
+ struct rc_entry ent, tmp;
+ time_t t;
+ FILE *f;
+ ent.stamp = time(NULL);
+ checksum_authenticator(rep, ent.data);
+ f = fopen(id->name, "r");
+ if(f == NULL)
+ return errno;
+ fread(&tmp, sizeof(ent), 1, f);
+ t = ent.stamp - tmp.stamp;
+ while(fread(&tmp, sizeof(ent), 1, f)){
+ if(tmp.stamp < t)
+ continue;
+ if(memcmp(tmp.data, ent.data, sizeof(ent.data)) == 0){
+ fclose(f);
+ return KRB5_RC_REPLAY;
+ }
+ }
+ if(ferror(f)){
+ fclose(f);
+ return errno;
+ }
+ fclose(f);
+ f = fopen(id->name, "a");
+ if(f == NULL)
+ return KRB5_RC_IO_UNKNOWN;
+ fwrite(&ent, 1, sizeof(ent), f);
+ fclose(f);
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_expunge(krb5_context context,
+ krb5_rcache id)
+{
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_get_lifespan(krb5_context context,
+ krb5_rcache id,
+ krb5_deltat *auth_lifespan)
+{
+ FILE *f = fopen(id->name, "r");
+ int r;
+ struct rc_entry ent;
+ r = fread(&ent, sizeof(ent), 1, f);
+ fclose(f);
+ if(r){
+ *auth_lifespan = ent.stamp;
+ return 0;
+ }
+ return KRB5_RC_IO_UNKNOWN;
+}
+const char*
+krb5_rc_get_name(krb5_context context,
+ krb5_rcache id)
+{
+ return id->name;
+}
+
+const char*
+krb5_rc_get_type(krb5_context context,
+ krb5_rcache id)
+{
+ return "FILE";
+}
+
diff --git a/crypto/heimdal/lib/krb5/send_to_kdc.c b/crypto/heimdal/lib/krb5/send_to_kdc.c
new file mode 100644
index 000000000000..2872322bafc8
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/send_to_kdc.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: send_to_kdc.c,v 1.36 2000/01/06 07:59:11 assar Exp $");
+
+/*
+ * send the data in `req' on the socket `fd' (which is datagram iff udp)
+ * waiting `tmout' for a reply and returning the reply in `rep'.
+ * iff limit read up to this many bytes
+ * returns 0 and data in `rep' if succesful, otherwise -1
+ */
+
+static int
+recv_loop (int fd,
+ time_t tmout,
+ int udp,
+ size_t limit,
+ krb5_data *rep)
+{
+ fd_set fdset;
+ struct timeval timeout;
+ int ret;
+ int nbytes;
+
+ krb5_data_zero(rep);
+ do {
+ FD_ZERO(&fdset);
+ FD_SET(fd, &fdset);
+ timeout.tv_sec = tmout;
+ timeout.tv_usec = 0;
+ ret = select (fd + 1, &fdset, NULL, NULL, &timeout);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ return -1;
+ } else if (ret == 0) {
+ return 0;
+ } else {
+ void *tmp;
+
+ if (ioctl (fd, FIONREAD, &nbytes) < 0) {
+ krb5_data_free (rep);
+ return -1;
+ }
+ if(nbytes == 0)
+ return 0;
+
+ if (limit)
+ nbytes = min(nbytes, limit - rep->length);
+
+ tmp = realloc (rep->data, rep->length + nbytes);
+ if (tmp == NULL) {
+ krb5_data_free (rep);
+ return -1;
+ }
+ rep->data = tmp;
+ ret = recv (fd, (char*)tmp + rep->length, nbytes, 0);
+ if (ret < 0) {
+ krb5_data_free (rep);
+ return -1;
+ }
+ rep->length += ret;
+ }
+ } while(!udp && (limit == 0 || rep->length < limit));
+ return 0;
+}
+
+/*
+ * Send kerberos requests and receive a reply on a udp or any other kind
+ * of a datagram socket. See `recv_loop'.
+ */
+
+static int
+send_and_recv_udp(int fd,
+ time_t tmout,
+ const krb5_data *req,
+ krb5_data *rep)
+{
+ if (send (fd, req->data, req->length, 0) < 0)
+ return -1;
+
+ return recv_loop(fd, tmout, 1, 0, rep);
+}
+
+/*
+ * `send_and_recv' for a TCP (or any other stream) socket.
+ * Since there are no record limits on a stream socket the protocol here
+ * is to prepend the request with 4 bytes of its length and the reply
+ * is similarly encoded.
+ */
+
+static int
+send_and_recv_tcp(int fd,
+ time_t tmout,
+ const krb5_data *req,
+ krb5_data *rep)
+{
+ unsigned char len[4];
+ unsigned long rep_len;
+ krb5_data len_data;
+
+ _krb5_put_int(len, req->length, 4);
+ if(net_write(fd, len, sizeof(len)) < 0)
+ return -1;
+ if(net_write(fd, req->data, req->length) < 0)
+ return -1;
+ if (recv_loop (fd, tmout, 0, 4, &len_data) < 0)
+ return -1;
+ if (len_data.length != 4) {
+ krb5_data_free (&len_data);
+ return -1;
+ }
+ _krb5_get_int(len_data.data, &rep_len, 4);
+ krb5_data_free (&len_data);
+ if (recv_loop (fd, tmout, 0, rep_len, rep) < 0)
+ return -1;
+ if(rep->length != rep_len) {
+ krb5_data_free (rep);
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * `send_and_recv' tailored for the HTTP protocol.
+ */
+
+static int
+send_and_recv_http(int fd,
+ time_t tmout,
+ const char *prefix,
+ const krb5_data *req,
+ krb5_data *rep)
+{
+ char *request;
+ char *str;
+ int ret;
+ int len = base64_encode(req->data, req->length, &str);
+
+ if(len < 0)
+ return -1;
+ asprintf(&request, "GET %s%s HTTP/1.0\r\n\r\n", prefix, str);
+ free(str);
+ if (request == NULL)
+ return -1;
+ ret = net_write (fd, request, strlen(request));
+ free (request);
+ if (ret < 0)
+ return ret;
+ ret = recv_loop(fd, tmout, 0, 0, rep);
+ if(ret)
+ return ret;
+ {
+ unsigned long rep_len;
+ char *s, *p;
+
+ s = realloc(rep->data, rep->length + 1);
+ if (s == NULL) {
+ krb5_data_free (rep);
+ return -1;
+ }
+ s[rep->length] = 0;
+ p = strstr(s, "\r\n\r\n");
+ if(p == NULL) {
+ free(s);
+ return -1;
+ }
+ p += 4;
+ rep->data = s;
+ rep->length -= p - s;
+ if(rep->length < 4) { /* remove length */
+ free(s);
+ return -1;
+ }
+ rep->length -= 4;
+ _krb5_get_int(p, &rep_len, 4);
+ if (rep_len != rep->length) {
+ free(s);
+ return -1;
+ }
+ memmove(rep->data, p + 4, rep->length);
+ }
+ return 0;
+}
+
+static int
+init_port(const char *s, int fallback)
+{
+ if (s) {
+ int tmp;
+
+ sscanf (s, "%d", &tmp);
+ return htons(tmp);
+ } else
+ return fallback;
+}
+
+/*
+ * Return 0 if succesful, otherwise 1
+ */
+
+static int
+send_via_proxy (krb5_context context,
+ const char *hostname,
+ const krb5_data *send,
+ krb5_data *receive)
+{
+ char *proxy = strdup(context->http_proxy);
+ char *prefix;
+ char *colon;
+ struct addrinfo hints;
+ struct addrinfo *ai, *a;
+ int ret;
+ int s;
+ char portstr[NI_MAXSERV];
+
+ colon = strchr(proxy, ':');
+ if(colon != NULL)
+ *colon++ = '\0';
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ snprintf (portstr, sizeof(portstr), "%d",
+ ntohs(init_port (colon, htons(80))));
+ ret = getaddrinfo (proxy, portstr, NULL, &ai);
+ free (proxy);
+ if (ret)
+ return ret;
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0)
+ continue;
+ if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
+ close (s);
+ continue;
+ }
+ break;
+ }
+ if (a == NULL) {
+ freeaddrinfo (ai);
+ return 1;
+ }
+ freeaddrinfo (ai);
+
+ asprintf(&prefix, "http://%s/", hostname);
+ if(prefix == NULL) {
+ close(s);
+ return 1;
+ }
+ ret = send_and_recv_http(s, context->kdc_timeout,
+ prefix, send, receive);
+ close (s);
+ free(prefix);
+ if(ret == 0 && receive->length != 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * Send the data `send' to one KDC in `realm' and get back the reply
+ * in `receive'.
+ */
+
+krb5_error_code
+krb5_sendto_kdc (krb5_context context,
+ const krb5_data *send,
+ const krb5_realm *realm,
+ krb5_data *receive)
+{
+ krb5_error_code ret;
+ char **hostlist, **hp, *p;
+ int fd;
+ int port;
+ int i;
+
+ port = krb5_getportbyname (context, "kerberos", "udp", 88);
+
+ if (context->use_admin_kdc)
+ ret = krb5_get_krb_admin_hst (context, realm, &hostlist);
+ else
+ ret = krb5_get_krbhst (context, realm, &hostlist);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < context->max_retries; ++i)
+ for (hp = hostlist; (p = *hp); ++hp) {
+ char *colon;
+ int http_flag = 0;
+ int tcp_flag = 0;
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ char portstr[NI_MAXSERV];
+
+ if(strncmp(p, "http://", 7) == 0){
+ p += 7;
+ http_flag = 1;
+ port = htons(80);
+ } else if(strncmp(p, "http/", 5) == 0) {
+ p += 5;
+ http_flag = 1;
+ port = htons(80);
+ }else if(strncmp(p, "tcp/", 4) == 0){
+ p += 4;
+ tcp_flag = 1;
+ } else if(strncmp(p, "udp/", 4) == 0) {
+ p += 4;
+ }
+ if(http_flag && context->http_proxy) {
+ if (send_via_proxy (context, p, send, receive))
+ continue;
+ else
+ goto out;
+ }
+ colon = strchr (p, ':');
+ if (colon)
+ *colon++ = '\0';
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ if (tcp_flag || http_flag)
+ hints.ai_socktype = SOCK_STREAM;
+ else
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf (portstr, sizeof(portstr), "%d",
+ ntohs(init_port (colon, port)));
+ ret = getaddrinfo (p, portstr, &hints, &ai);
+ if (ret)
+ continue;
+ for (a = ai; a != NULL; a = a->ai_next) {
+ fd = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (fd < 0)
+ continue;
+ if (connect (fd, a->ai_addr, a->ai_addrlen) < 0) {
+ close (fd);
+ continue;
+ }
+ break;
+ }
+ if (a == NULL) {
+ freeaddrinfo (ai);
+ continue;
+ }
+ freeaddrinfo (ai);
+
+ if(http_flag)
+ ret = send_and_recv_http(fd, context->kdc_timeout,
+ "", send, receive);
+ else if(tcp_flag)
+ ret = send_and_recv_tcp (fd, context->kdc_timeout,
+ send, receive);
+ else
+ ret = send_and_recv_udp (fd, context->kdc_timeout,
+ send, receive);
+ close (fd);
+ if(ret == 0 && receive->length != 0)
+ goto out;
+ }
+ ret = KRB5_KDC_UNREACH;
+out:
+ krb5_free_krbhst (context, hostlist);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/sendauth.c b/crypto/heimdal/lib/krb5/sendauth.c
new file mode 100644
index 000000000000..b9e8dd01ef30
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/sendauth.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: sendauth.c,v 1.17 1999/12/02 17:05:12 joda Exp $");
+
+/*
+ * The format seems to be:
+ * client -> server
+ *
+ * 4 bytes - length
+ * KRB5_SENDAUTH_V1.0 (including zero)
+ * 4 bytes - length
+ * protocol string (with terminating zero)
+ *
+ * server -> client
+ * 1 byte - (0 = OK, else some kind of error)
+ *
+ * client -> server
+ * 4 bytes - length
+ * AP-REQ
+ *
+ * server -> client
+ * 4 bytes - length (0 = OK, else length of error)
+ * (error)
+ *
+ * if(mutual) {
+ * server -> client
+ * 4 bytes - length
+ * AP-REP
+ * }
+ */
+
+krb5_error_code
+krb5_sendauth(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ const char *appl_version,
+ krb5_principal client,
+ krb5_principal server,
+ krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_ccache ccache,
+ krb5_error **ret_error,
+ krb5_ap_rep_enc_part **rep_result,
+ krb5_creds **out_creds)
+{
+ krb5_error_code ret;
+ u_int32_t len, net_len;
+ const char *version = KRB5_SENDAUTH_VERSION;
+ u_char repl;
+ krb5_data ap_req, error_data;
+ krb5_creds this_cred;
+ krb5_principal this_client = NULL;
+ krb5_creds *creds;
+ ssize_t sret;
+
+ len = strlen(version) + 1;
+ net_len = htonl(len);
+ if (krb5_net_write (context, p_fd, &net_len, 4) != 4
+ || krb5_net_write (context, p_fd, version, len) != len)
+ return errno;
+
+ len = strlen(appl_version) + 1;
+ net_len = htonl(len);
+ if (krb5_net_write (context, p_fd, &net_len, 4) != 4
+ || krb5_net_write (context, p_fd, appl_version, len) != len)
+ return errno;
+
+ sret = krb5_net_read (context, p_fd, &repl, sizeof(repl));
+ if (sret < 0)
+ return errno;
+ else if (sret != sizeof(repl))
+ return KRB5_SENDAUTH_BADRESPONSE;
+
+ if (repl != 0)
+ return KRB5_SENDAUTH_REJECTED;
+
+ if (in_creds == NULL) {
+ if (ccache == NULL) {
+ ret = krb5_cc_default (context, &ccache);
+ if (ret)
+ return ret;
+ }
+
+ if (client == NULL) {
+ ret = krb5_cc_get_principal (context, ccache, &this_client);
+ if (ret)
+ return ret;
+ client = this_client;
+ }
+ memset(&this_cred, 0, sizeof(this_cred));
+ this_cred.client = client;
+ this_cred.server = server;
+ this_cred.times.endtime = 0;
+ this_cred.ticket.length = 0;
+ in_creds = &this_cred;
+ }
+ if (in_creds->ticket.length == 0) {
+ ret = krb5_get_credentials (context, 0, ccache, in_creds, &creds);
+ if (ret)
+ return ret;
+ } else {
+ creds = in_creds;
+ }
+ ret = krb5_mk_req_extended (context,
+ auth_context,
+ ap_req_options,
+ in_data,
+ creds,
+ &ap_req);
+
+ if (out_creds)
+ *out_creds = creds;
+ else
+ krb5_free_creds(context, creds);
+ if(this_client)
+ krb5_free_principal(context, this_client);
+
+ if (ret)
+ return ret;
+
+ ret = krb5_write_message (context,
+ p_fd,
+ &ap_req);
+ if (ret)
+ return ret;
+
+ krb5_data_free (&ap_req);
+
+ ret = krb5_read_message (context, p_fd, &error_data);
+ if (ret)
+ return ret;
+
+ if (error_data.length != 0) {
+ KRB_ERROR error;
+
+ ret = krb5_rd_error (context, &error_data, &error);
+ krb5_data_free (&error_data);
+ if (ret == 0) {
+ if (ret_error != NULL) {
+ *ret_error = malloc (sizeof(krb5_error));
+ if (*ret_error == NULL) {
+ free_KRB_ERROR(&error);
+ } else {
+ **ret_error = error;
+ }
+ } else {
+ free_KRB_ERROR(&error);
+ }
+ return error.error_code;
+ } else
+ return ret;
+ }
+
+ if (ap_req_options & AP_OPTS_MUTUAL_REQUIRED) {
+ krb5_data ap_rep;
+ krb5_ap_rep_enc_part *ignore;
+
+ krb5_data_zero (&ap_rep);
+ ret = krb5_read_message (context,
+ p_fd,
+ &ap_rep);
+ if (ret)
+ return ret;
+
+ ret = krb5_rd_rep (context, *auth_context, &ap_rep,
+ rep_result ? rep_result : &ignore);
+ if (ret)
+ return ret;
+ if (rep_result == NULL)
+ krb5_free_ap_rep_enc_part (context, ignore);
+ krb5_data_free (&ap_rep);
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/set_default_realm.c b/crypto/heimdal/lib/krb5/set_default_realm.c
new file mode 100644
index 000000000000..b917a923250b
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/set_default_realm.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: set_default_realm.c,v 1.11 1999/12/02 17:05:12 joda Exp $");
+
+/*
+ * Convert the simple string `s' into a NULL-terminated and freshly allocated
+ * list in `list'. Return an error code.
+ */
+
+static krb5_error_code
+string_to_list (const char *s, krb5_realm **list)
+{
+
+ *list = malloc (2 * sizeof(**list));
+ if (*list == NULL)
+ return ENOMEM;
+ (*list)[0] = strdup (s);
+ if ((*list)[0] == NULL) {
+ free (*list);
+ return ENOMEM;
+ }
+ (*list)[1] = NULL;
+ return 0;
+}
+
+/*
+ * Set the knowledge of the default realm(s) in `context'.
+ * If realm != NULL, that's the new default realm.
+ * Otherwise, the realm(s) are figured out from configuration or DNS.
+ */
+
+krb5_error_code
+krb5_set_default_realm(krb5_context context,
+ char *realm)
+{
+ krb5_error_code ret = 0;
+ krb5_realm *realms = NULL;
+
+ if (realm == NULL) {
+ realms = krb5_config_get_strings (context, NULL,
+ "libdefaults",
+ "default_realm",
+ NULL);
+ if (realms == NULL)
+ ret = krb5_get_host_realm(context, NULL, &realms);
+ } else {
+ ret = string_to_list (realm, &realms);
+ }
+ if (ret)
+ return ret;
+ krb5_free_host_realm (context, context->default_realms);
+ context->default_realms = realms;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/sock_principal.c b/crypto/heimdal/lib/krb5/sock_principal.c
new file mode 100644
index 000000000000..bfd4eb4e2a91
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/sock_principal.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: sock_principal.c,v 1.9 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_sock_to_principal (krb5_context context,
+ int sock,
+ const char *sname,
+ int32_t type,
+ krb5_principal *ret_princ)
+{
+ krb5_error_code ret;
+ krb5_address address;
+ struct sockaddr_storage __ss;
+ struct sockaddr *sa = (struct sockaddr *)&__ss;
+ int len = sizeof(__ss);
+ struct hostent *hostent;
+ int family;
+ char hname[256];
+
+ if (getsockname (sock, sa, &len) < 0)
+ return errno;
+ family = sa->sa_family;
+
+ ret = krb5_sockaddr2address (sa, &address);
+ if (ret)
+ return ret;
+
+ hostent = roken_gethostbyaddr (address.address.data,
+ address.address.length,
+ family);
+
+ if (hostent == NULL)
+ return h_errno;
+ strlcpy(hname, hostent->h_name, sizeof(hname));
+ return krb5_sname_to_principal (context,
+ hname,
+ sname,
+ type,
+ ret_princ);
+}
diff --git a/crypto/heimdal/lib/krb5/store.c b/crypto/heimdal/lib/krb5/store.c
new file mode 100644
index 000000000000..17b154747b8c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/store.c
@@ -0,0 +1,609 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: store.c,v 1.32 1999/12/02 17:05:12 joda Exp $");
+
+void
+krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
+{
+ sp->flags |= flags;
+}
+
+void
+krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
+{
+ sp->flags &= ~flags;
+}
+
+krb5_boolean
+krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
+{
+ return (sp->flags & flags) == flags;
+}
+
+ssize_t
+_krb5_put_int(void *buffer, unsigned long value, size_t size)
+{
+ unsigned char *p = buffer;
+ int i;
+ for (i = size - 1; i >= 0; i--) {
+ p[i] = value & 0xff;
+ value >>= 8;
+ }
+ return size;
+}
+
+ssize_t
+_krb5_get_int(void *buffer, unsigned long *value, size_t size)
+{
+ unsigned char *p = buffer;
+ unsigned long v = 0;
+ int i;
+ for (i = 0; i < size; i++)
+ v = (v << 8) + p[i];
+ *value = v;
+ return size;
+}
+
+krb5_error_code
+krb5_storage_free(krb5_storage *sp)
+{
+ if(sp->free)
+ (*sp->free)(sp);
+ free(sp->data);
+ free(sp);
+ return 0;
+}
+
+krb5_error_code
+krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
+{
+ off_t pos;
+ size_t size;
+ krb5_error_code ret;
+
+ pos = sp->seek(sp, 0, SEEK_CUR);
+ size = (size_t)sp->seek(sp, 0, SEEK_END);
+ ret = krb5_data_alloc (data, size);
+ if (ret) {
+ sp->seek(sp, pos, SEEK_SET);
+ return ret;
+ }
+ if (size) {
+ sp->seek(sp, 0, SEEK_SET);
+ sp->fetch(sp, data->data, data->length);
+ sp->seek(sp, pos, SEEK_SET);
+ }
+ return 0;
+}
+
+static krb5_error_code
+krb5_store_int(krb5_storage *sp,
+ int32_t value,
+ size_t len)
+{
+ int ret;
+ unsigned char v[4];
+
+ _krb5_put_int(v, value, len);
+ ret = sp->store(sp, v, len);
+ if (ret != len)
+ return (ret<0)?errno:KRB5_CC_END;
+ return 0;
+}
+
+krb5_error_code
+krb5_store_int32(krb5_storage *sp,
+ int32_t value)
+{
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER))
+ value = htonl(value);
+ return krb5_store_int(sp, value, 4);
+}
+
+static krb5_error_code
+krb5_ret_int(krb5_storage *sp,
+ int32_t *value,
+ size_t len)
+{
+ int ret;
+ unsigned char v[4];
+ unsigned long w;
+ ret = sp->fetch(sp, v, len);
+ if(ret != len)
+ return (ret<0)?errno:KRB5_CC_END;
+ _krb5_get_int(v, &w, len);
+ *value = w;
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_int32(krb5_storage *sp,
+ int32_t *value)
+{
+ krb5_error_code ret = krb5_ret_int(sp, value, 4);
+ if(ret)
+ return ret;
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER))
+ *value = ntohl(*value);
+ return 0;
+}
+
+krb5_error_code
+krb5_store_int16(krb5_storage *sp,
+ int16_t value)
+{
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER))
+ value = htons(value);
+ return krb5_store_int(sp, value, 2);
+}
+
+krb5_error_code
+krb5_ret_int16(krb5_storage *sp,
+ int16_t *value)
+{
+ int32_t v;
+ int ret;
+ ret = krb5_ret_int(sp, &v, 2);
+ if(ret)
+ return ret;
+ *value = v;
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER))
+ *value = ntohs(*value);
+ return 0;
+}
+
+krb5_error_code
+krb5_store_int8(krb5_storage *sp,
+ int8_t value)
+{
+ int ret;
+
+ ret = sp->store(sp, &value, sizeof(value));
+ if (ret != sizeof(value))
+ return (ret<0)?errno:KRB5_CC_END;
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_int8(krb5_storage *sp,
+ int8_t *value)
+{
+ int ret;
+
+ ret = sp->fetch(sp, value, sizeof(*value));
+ if (ret != sizeof(*value))
+ return (ret<0)?errno:KRB5_CC_END;
+ return 0;
+}
+
+krb5_error_code
+krb5_store_data(krb5_storage *sp,
+ krb5_data data)
+{
+ int ret;
+ ret = krb5_store_int32(sp, data.length);
+ if(ret < 0)
+ return ret;
+ ret = sp->store(sp, data.data, data.length);
+ if(ret != data.length){
+ if(ret < 0)
+ return errno;
+ return KRB5_CC_END;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_data(krb5_storage *sp,
+ krb5_data *data)
+{
+ int ret;
+ int32_t size;
+
+ ret = krb5_ret_int32(sp, &size);
+ if(ret)
+ return ret;
+ ret = krb5_data_alloc (data, size);
+ if (ret)
+ return ret;
+ if (size) {
+ ret = sp->fetch(sp, data->data, size);
+ if(ret != size)
+ return (ret < 0)? errno : KRB5_CC_END;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_store_string(krb5_storage *sp, const char *s)
+{
+ krb5_data data;
+ data.length = strlen(s);
+ data.data = (void*)s;
+ return krb5_store_data(sp, data);
+}
+
+krb5_error_code
+krb5_ret_string(krb5_storage *sp,
+ char **string)
+{
+ int ret;
+ krb5_data data;
+ ret = krb5_ret_data(sp, &data);
+ if(ret)
+ return ret;
+ *string = realloc(data.data, data.length + 1);
+ if(*string == NULL){
+ free(data.data);
+ return ENOMEM;
+ }
+ (*string)[data.length] = 0;
+ return 0;
+}
+
+krb5_error_code
+krb5_store_stringz(krb5_storage *sp,
+ char *s)
+{
+ size_t len = strlen(s) + 1;
+ ssize_t ret;
+
+ ret = sp->store(sp, s, len);
+ if(ret != len) {
+ if(ret < 0)
+ return ret;
+ else
+ return KRB5_CC_END;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_stringz(krb5_storage *sp,
+ char **string)
+{
+ char c;
+ char *s = NULL;
+ size_t len = 0;
+ ssize_t ret;
+
+ while((ret = sp->fetch(sp, &c, 1)) == 1){
+ char *tmp;
+
+ len++;
+ tmp = realloc (s, len);
+ if (tmp == NULL) {
+ free (s);
+ return ENOMEM;
+ }
+ s = tmp;
+ s[len - 1] = c;
+ if(c == 0)
+ break;
+ }
+ if(ret != 1){
+ free(s);
+ if(ret == 0)
+ return KRB5_CC_END;
+ return ret;
+ }
+ *string = s;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_store_principal(krb5_storage *sp,
+ krb5_principal p)
+{
+ int i;
+ int ret;
+
+ if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
+ ret = krb5_store_int32(sp, p->name.name_type);
+ if(ret) return ret;
+ }
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
+ ret = krb5_store_int32(sp, p->name.name_string.len + 1);
+ else
+ ret = krb5_store_int32(sp, p->name.name_string.len);
+
+ if(ret) return ret;
+ ret = krb5_store_string(sp, p->realm);
+ if(ret) return ret;
+ for(i = 0; i < p->name.name_string.len; i++){
+ ret = krb5_store_string(sp, p->name.name_string.val[i]);
+ if(ret) return ret;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_principal(krb5_storage *sp,
+ krb5_principal *princ)
+{
+ int i;
+ int ret;
+ krb5_principal p;
+ int32_t type;
+ int32_t ncomp;
+
+ p = calloc(1, sizeof(*p));
+ if(p == NULL)
+ return ENOMEM;
+
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
+ type = KRB5_NT_UNKNOWN;
+ else if((ret = krb5_ret_int32(sp, &type))){
+ free(p);
+ return ret;
+ }
+ if((ret = krb5_ret_int32(sp, &ncomp))){
+ free(p);
+ return ret;
+ }
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
+ ncomp--;
+ p->name.name_type = type;
+ p->name.name_string.len = ncomp;
+ ret = krb5_ret_string(sp, &p->realm);
+ if(ret) return ret;
+ p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val));
+ if(p->name.name_string.val == NULL){
+ free(p->realm);
+ return ENOMEM;
+ }
+ for(i = 0; i < ncomp; i++){
+ ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
+ if(ret) return ret; /* XXX */
+ }
+ *princ = p;
+ return 0;
+}
+
+krb5_error_code
+krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
+{
+ int ret;
+ ret = krb5_store_int16(sp, p.keytype);
+ if(ret) return ret;
+
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
+ /* this should really be enctype, but it is the same as
+ keytype nowadays */
+ ret = krb5_store_int16(sp, p.keytype);
+ if(ret) return ret;
+ }
+
+ ret = krb5_store_data(sp, p.keyvalue);
+ return ret;
+}
+
+krb5_error_code
+krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
+{
+ int ret;
+ int16_t tmp;
+
+ ret = krb5_ret_int16(sp, &tmp);
+ if(ret) return ret;
+ p->keytype = tmp;
+
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
+ ret = krb5_ret_int16(sp, &tmp);
+ if(ret) return ret;
+ }
+
+ ret = krb5_ret_data(sp, &p->keyvalue);
+ return ret;
+}
+
+krb5_error_code
+krb5_store_times(krb5_storage *sp, krb5_times times)
+{
+ int ret;
+ ret = krb5_store_int32(sp, times.authtime);
+ if(ret) return ret;
+ ret = krb5_store_int32(sp, times.starttime);
+ if(ret) return ret;
+ ret = krb5_store_int32(sp, times.endtime);
+ if(ret) return ret;
+ ret = krb5_store_int32(sp, times.renew_till);
+ return ret;
+}
+
+krb5_error_code
+krb5_ret_times(krb5_storage *sp, krb5_times *times)
+{
+ int ret;
+ int32_t tmp;
+ ret = krb5_ret_int32(sp, &tmp);
+ times->authtime = tmp;
+ if(ret) return ret;
+ ret = krb5_ret_int32(sp, &tmp);
+ times->starttime = tmp;
+ if(ret) return ret;
+ ret = krb5_ret_int32(sp, &tmp);
+ times->endtime = tmp;
+ if(ret) return ret;
+ ret = krb5_ret_int32(sp, &tmp);
+ times->renew_till = tmp;
+ return ret;
+}
+
+krb5_error_code
+krb5_store_address(krb5_storage *sp, krb5_address p)
+{
+ int ret;
+ ret = krb5_store_int16(sp, p.addr_type);
+ if(ret) return ret;
+ ret = krb5_store_data(sp, p.address);
+ return ret;
+}
+
+krb5_error_code
+krb5_ret_address(krb5_storage *sp, krb5_address *adr)
+{
+ int16_t t;
+ int ret;
+ ret = krb5_ret_int16(sp, &t);
+ if(ret) return ret;
+ adr->addr_type = t;
+ ret = krb5_ret_data(sp, &adr->address);
+ return ret;
+}
+
+krb5_error_code
+krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
+{
+ int i;
+ int ret;
+ ret = krb5_store_int32(sp, p.len);
+ if(ret) return ret;
+ for(i = 0; i<p.len; i++){
+ ret = krb5_store_address(sp, p.val[i]);
+ if(ret) break;
+ }
+ return ret;
+}
+
+krb5_error_code
+krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
+{
+ int i;
+ int ret;
+ int32_t tmp;
+
+ ret = krb5_ret_int32(sp, &tmp);
+ if(ret) return ret;
+ adr->len = tmp;
+ ALLOC(adr->val, adr->len);
+ for(i = 0; i < adr->len; i++){
+ ret = krb5_ret_address(sp, &adr->val[i]);
+ if(ret) break;
+ }
+ return ret;
+}
+
+krb5_error_code
+krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
+{
+ krb5_error_code ret;
+ int i;
+ ret = krb5_store_int32(sp, auth.len);
+ if(ret) return ret;
+ for(i = 0; i < auth.len; i++){
+ ret = krb5_store_int16(sp, auth.val[i].ad_type);
+ if(ret) break;
+ ret = krb5_store_data(sp, auth.val[i].ad_data);
+ if(ret) break;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
+{
+ krb5_error_code ret;
+ int32_t tmp;
+ int16_t tmp2;
+ int i;
+ ret = krb5_ret_int32(sp, &tmp);
+ if(ret) return ret;
+ ALLOC_SEQ(auth, tmp);
+ for(i = 0; i < tmp; i++){
+ ret = krb5_ret_int16(sp, &tmp2);
+ if(ret) break;
+ auth->val[i].ad_type = tmp2;
+ ret = krb5_ret_data(sp, &auth->val[i].ad_data);
+ if(ret) break;
+ }
+ return ret;
+}
+
+krb5_error_code
+krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
+{
+ krb5_store_principal(sp, creds->client);
+ krb5_store_principal(sp, creds->server);
+ krb5_store_keyblock(sp, creds->session);
+ krb5_store_times(sp, creds->times);
+ krb5_store_int8(sp, 0); /* this is probably the
+ enc-tkt-in-skey bit from KDCOptions */
+ krb5_store_int32(sp, creds->flags.i);
+ krb5_store_addrs(sp, creds->addresses);
+ krb5_store_authdata(sp, creds->authdata);
+ krb5_store_data(sp, creds->ticket);
+ krb5_store_data(sp, creds->second_ticket);
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
+{
+ krb5_error_code ret;
+ int8_t dummy8;
+ int32_t dummy32;
+
+ memset(creds, 0, sizeof(*creds));
+ ret = krb5_ret_principal (sp, &creds->client);
+ if(ret) goto cleanup;
+ ret = krb5_ret_principal (sp, &creds->server);
+ if(ret) goto cleanup;
+ ret = krb5_ret_keyblock (sp, &creds->session);
+ if(ret) goto cleanup;
+ ret = krb5_ret_times (sp, &creds->times);
+ if(ret) goto cleanup;
+ ret = krb5_ret_int8 (sp, &dummy8);
+ if(ret) goto cleanup;
+ ret = krb5_ret_int32 (sp, &dummy32);
+ if(ret) goto cleanup;
+ creds->flags.i = dummy32;
+ ret = krb5_ret_addrs (sp, &creds->addresses);
+ if(ret) goto cleanup;
+ ret = krb5_ret_authdata (sp, &creds->authdata);
+ if(ret) goto cleanup;
+ ret = krb5_ret_data (sp, &creds->ticket);
+ if(ret) goto cleanup;
+ ret = krb5_ret_data (sp, &creds->second_ticket);
+cleanup:
+ if(ret)
+#if 0
+ krb5_free_creds_contents(context, creds) /* XXX */
+#endif
+ ;
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/store_emem.c b/crypto/heimdal/lib/krb5/store_emem.c
new file mode 100644
index 000000000000..d2497efd5826
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/store_emem.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: store_emem.c,v 1.9 1999/12/02 17:05:12 joda Exp $");
+
+typedef struct emem_storage{
+ unsigned char *base;
+ size_t size;
+ size_t len;
+ unsigned char *ptr;
+}emem_storage;
+
+static ssize_t
+emem_fetch(krb5_storage *sp, void *data, size_t size)
+{
+ emem_storage *s = (emem_storage*)sp->data;
+ if(s->base + s->len - s->ptr < size)
+ size = s->base + s->len - s->ptr;
+ memmove(data, s->ptr, size);
+ sp->seek(sp, size, SEEK_CUR);
+ return size;
+}
+
+static ssize_t
+emem_store(krb5_storage *sp, void *data, size_t size)
+{
+ emem_storage *s = (emem_storage*)sp->data;
+ if(size > s->base + s->size - s->ptr){
+ void *base;
+ size_t sz, off;
+ sz = 2 * (size + (s->ptr - s->base)); /* XXX */
+ off = s->ptr - s->base;
+ base = realloc(s->base, sz);
+ if(base == NULL)
+ return 0;
+ s->size = sz;
+ s->base = base;
+ s->ptr = (unsigned char*)base + off;
+ }
+ memmove(s->ptr, data, size);
+ sp->seek(sp, size, SEEK_CUR);
+ return size;
+}
+
+static off_t
+emem_seek(krb5_storage *sp, off_t offset, int whence)
+{
+ emem_storage *s = (emem_storage*)sp->data;
+ switch(whence){
+ case SEEK_SET:
+ if(offset > s->size)
+ offset = s->size;
+ if(offset < 0)
+ offset = 0;
+ s->ptr = s->base + offset;
+ if(offset > s->len)
+ s->len = offset;
+ break;
+ case SEEK_CUR:
+ sp->seek(sp,s->ptr - s->base + offset, SEEK_SET);
+ break;
+ case SEEK_END:
+ sp->seek(sp, s->len + offset, SEEK_SET);
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ return s->ptr - s->base;
+}
+
+static void
+emem_free(krb5_storage *sp)
+{
+ free(((emem_storage*)sp->data)->base);
+}
+
+krb5_storage *
+krb5_storage_emem(void)
+{
+ krb5_storage *sp = malloc(sizeof(krb5_storage));
+ emem_storage *s = malloc(sizeof(*s));
+ sp->data = s;
+ sp->flags = 0;
+ s->size = 1024;
+ s->base = malloc(s->size);
+ s->len = 0;
+ s->ptr = s->base;
+ sp->fetch = emem_fetch;
+ sp->store = emem_store;
+ sp->seek = emem_seek;
+ sp->free = emem_free;
+ return sp;
+}
diff --git a/crypto/heimdal/lib/krb5/store_fd.c b/crypto/heimdal/lib/krb5/store_fd.c
new file mode 100644
index 000000000000..e4c507c2c54b
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/store_fd.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: store_fd.c,v 1.6 1999/12/02 17:05:13 joda Exp $");
+
+typedef struct fd_storage{
+ int fd;
+}fd_storage;
+
+#define FD(S) (((fd_storage*)(S)->data)->fd)
+
+static ssize_t
+fd_fetch(krb5_storage *sp, void *data, size_t size)
+{
+ return read(FD(sp), data, size);
+}
+
+static ssize_t
+fd_store(krb5_storage *sp, void *data, size_t size)
+{
+ return write(FD(sp), data, size);
+}
+
+static off_t
+fd_seek(krb5_storage *sp, off_t offset, int whence)
+{
+ return lseek(FD(sp), offset, whence);
+}
+
+krb5_storage *
+krb5_storage_from_fd(int fd)
+{
+ krb5_storage *sp = malloc(sizeof(krb5_storage));
+ sp->data = malloc(sizeof(fd_storage));
+ sp->flags = 0;
+ FD(sp) = fd;
+ sp->fetch = fd_fetch;
+ sp->store = fd_store;
+ sp->seek = fd_seek;
+ sp->free = NULL;
+ return sp;
+}
diff --git a/crypto/heimdal/lib/krb5/store_mem.c b/crypto/heimdal/lib/krb5/store_mem.c
new file mode 100644
index 000000000000..a8019e635dfd
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/store_mem.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: store_mem.c,v 1.9 1999/12/02 17:05:13 joda Exp $");
+
+typedef struct mem_storage{
+ unsigned char *base;
+ size_t size;
+ unsigned char *ptr;
+}mem_storage;
+
+static ssize_t
+mem_fetch(krb5_storage *sp, void *data, size_t size)
+{
+ mem_storage *s = (mem_storage*)sp->data;
+ if(size > s->base + s->size - s->ptr)
+ size = s->base + s->size - s->ptr;
+ memmove(data, s->ptr, size);
+ sp->seek(sp, size, SEEK_CUR);
+ return size;
+}
+
+static ssize_t
+mem_store(krb5_storage *sp, void *data, size_t size)
+{
+ mem_storage *s = (mem_storage*)sp->data;
+ if(size > s->base + s->size - s->ptr)
+ size = s->base + s->size - s->ptr;
+ memmove(s->ptr, data, size);
+ sp->seek(sp, size, SEEK_CUR);
+ return size;
+}
+
+static off_t
+mem_seek(krb5_storage *sp, off_t offset, int whence)
+{
+ mem_storage *s = (mem_storage*)sp->data;
+ switch(whence){
+ case SEEK_SET:
+ if(offset > s->size)
+ offset = s->size;
+ if(offset < 0)
+ offset = 0;
+ s->ptr = s->base + offset;
+ break;
+ case SEEK_CUR:
+ return sp->seek(sp, s->ptr - s->base + offset, SEEK_SET);
+ case SEEK_END:
+ return sp->seek(sp, s->size + offset, SEEK_SET);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ return s->ptr - s->base;
+}
+
+krb5_storage *
+krb5_storage_from_mem(void *buf, size_t len)
+{
+ krb5_storage *sp = malloc(sizeof(krb5_storage));
+ mem_storage *s;
+ if(sp == NULL)
+ return NULL;
+ s = malloc(sizeof(*s));
+ if(s == NULL) {
+ free(sp);
+ return NULL;
+ }
+ sp->data = s;
+ sp->flags = 0;
+ s->base = buf;
+ s->size = len;
+ s->ptr = buf;
+ sp->fetch = mem_fetch;
+ sp->store = mem_store;
+ sp->seek = mem_seek;
+ sp->free = NULL;
+ return sp;
+}
+
+krb5_storage *
+krb5_storage_from_data(krb5_data *data)
+{
+ return krb5_storage_from_mem(data->data, data->length);
+}
diff --git a/crypto/heimdal/lib/krb5/string-to-key-test.c b/crypto/heimdal/lib/krb5/string-to-key-test.c
new file mode 100644
index 000000000000..0e884d0e810f
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/string-to-key-test.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: string-to-key-test.c,v 1.2 1999/10/28 23:10:38 assar Exp $");
+
+enum { MAXSIZE = 24 };
+
+static struct testcase {
+ const char *principal_name;
+ const char *password;
+ krb5_enctype enctype;
+ unsigned char res[MAXSIZE];
+} tests[] = {
+ {"@", "", ETYPE_DES_CBC_MD5,
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}},
+ {"nisse@FOO.SE", "hej", ETYPE_DES_CBC_MD5,
+ {0xfe, 0x67, 0xbf, 0x9e, 0x57, 0x6b, 0xfe, 0x52}},
+ {"assar/liten@FOO.SE", "hemligt", ETYPE_DES_CBC_MD5,
+ {0x5b, 0x9b, 0xcb, 0xf2, 0x97, 0x43, 0xc8, 0x40}},
+ {"@", "", ETYPE_DES3_CBC_SHA1,
+ {0xce, 0xa2, 0x2f, 0x9b, 0x52, 0x2c, 0xb0, 0x15, 0x6e, 0x6b, 0x64,
+ 0x73, 0x62, 0x64, 0x73, 0x4f, 0x6e, 0x73, 0xce, 0xa2, 0x2f, 0x9b,
+ 0x52, 0x57}},
+ {"nisse@FOO.SE", "hej", ETYPE_DES3_CBC_SHA1,
+ {0x0e, 0xbc, 0x23, 0x9d, 0x68, 0x46, 0xf2, 0xd5, 0x51, 0x98, 0x5b,
+ 0x57, 0xc1, 0x57, 0x01, 0x79, 0x04, 0xc4, 0xe9, 0xfe, 0xc1, 0x0e,
+ 0x13, 0xd0}},
+ {"assar/liten@FOO.SE", "hemligt", ETYPE_DES3_CBC_SHA1,
+ {0x7f, 0x40, 0x67, 0xb9, 0xbc, 0xc4, 0x40, 0xfb, 0x43, 0x73, 0xd9,
+ 0xd3, 0xcd, 0x7c, 0xc7, 0x67, 0xe6, 0x79, 0x94, 0xd0, 0xa8, 0x34,
+ 0xdf, 0x62}},
+ {NULL}
+};
+
+int
+main(int argc, char **argv)
+{
+ struct testcase *t;
+ krb5_context context;
+ krb5_error_code ret;
+ int val = 0;
+
+ krb5_init_context (&context);
+
+ for (t = tests; t->principal_name; ++t) {
+ krb5_keyblock key;
+ krb5_principal principal;
+ int i;
+
+ ret = krb5_parse_name (context, t->principal_name, &principal);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name %s",
+ t->principal_name);
+ ret = krb5_string_to_key (context, t->enctype, t->password,
+ principal, &key);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_string_to_key");
+ krb5_free_principal (context, principal);
+ if (memcmp (key.keyvalue.data, t->res, key.keyvalue.length) != 0) {
+ const unsigned char *p = key.keyvalue.data;
+
+ printf ("string_to_key(%s, %s) failed\n",
+ t->principal_name, t->password);
+ printf ("should be: ");
+ for (i = 0; i < key.keyvalue.length; ++i)
+ printf ("%02x", t->res[i]);
+ printf ("\nresult was: ");
+ for (i = 0; i < key.keyvalue.length; ++i)
+ printf ("%02x", p[i]);
+ printf ("\n");
+ val = 1;
+ }
+ }
+ return val;
+}
diff --git a/crypto/heimdal/lib/krb5/ticket.c b/crypto/heimdal/lib/krb5/ticket.c
new file mode 100644
index 000000000000..ecb58218990a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/ticket.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: ticket.c,v 1.4 1999/12/02 17:05:13 joda Exp $");
+
+krb5_error_code
+krb5_free_ticket(krb5_context context,
+ krb5_ticket *ticket)
+{
+ free_EncTicketPart(&ticket->ticket);
+ krb5_free_principal(context, ticket->client);
+ krb5_free_principal(context, ticket->server);
+ return 0;
+}
+
+krb5_error_code
+krb5_copy_ticket(krb5_context context,
+ const krb5_ticket *from,
+ krb5_ticket **to)
+{
+ krb5_error_code ret;
+ krb5_ticket *tmp = malloc(sizeof(*tmp));
+ if(tmp == NULL)
+ return ENOMEM;
+ if((ret = copy_EncTicketPart(&from->ticket, &tmp->ticket))){
+ free(tmp);
+ return ret;
+ }
+ ret = krb5_copy_principal(context, from->client, &tmp->client);
+ if(ret){
+ free_EncTicketPart(&tmp->ticket);
+ return ret;
+ }
+ ret = krb5_copy_principal(context, from->server, &(*to)->server);
+ if(ret){
+ krb5_free_principal(context, tmp->client);
+ free_EncTicketPart(&tmp->ticket);
+ return ret;
+ }
+ *to = tmp;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/time.c b/crypto/heimdal/lib/krb5/time.c
new file mode 100644
index 000000000000..47a5f0b3ae0a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/time.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: time.c,v 1.2 1999/12/02 17:05:13 joda Exp $");
+
+krb5_error_code
+krb5_timeofday (krb5_context context,
+ int32_t *timeret)
+{
+ *timeret = time(NULL) + context->kdc_sec_offset;
+ return 0;
+}
+
+krb5_error_code
+krb5_us_timeofday (krb5_context context,
+ int32_t *sec,
+ int32_t *usec)
+{
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+
+ *sec = tv.tv_sec + context->kdc_sec_offset;
+ *usec = tv.tv_usec; /* XXX */
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/transited.c b/crypto/heimdal/lib/krb5/transited.c
new file mode 100644
index 000000000000..ed5a5b5b7965
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/transited.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: transited.c,v 1.5 1999/12/02 17:05:13 joda Exp $");
+
+/* this is an attempt at one of the most horrible `compression'
+ schemes that has ever been invented; it's so amazingly brain-dead
+ that words can not describe it, and all this just to save a few
+ silly bytes */
+
+struct tr_realm {
+ char *realm;
+ unsigned leading_space:1;
+ unsigned leading_slash:1;
+ unsigned trailing_dot:1;
+ struct tr_realm *next;
+};
+
+static void
+free_realms(struct tr_realm *r)
+{
+ struct tr_realm *p;
+ while(r){
+ p = r;
+ r = r->next;
+ free(p->realm);
+ free(p);
+ }
+}
+
+static int
+make_path(struct tr_realm *r, const char *from, const char *to)
+{
+ const char *p;
+ struct tr_realm *path = r->next;
+ struct tr_realm *tmp;
+
+ if(strlen(from) < strlen(to)){
+ const char *tmp;
+ tmp = from;
+ from = to;
+ to = tmp;
+ }
+
+ if(strcmp(from + strlen(from) - strlen(to), to) == 0){
+ p = from;
+ while(1){
+ p = strchr(p, '.');
+ if(p == NULL)
+ return KRB5KDC_ERR_POLICY;
+ p++;
+ if(strcmp(p, to) == 0)
+ break;
+ tmp = calloc(1, sizeof(*tmp));
+ tmp->next = path;
+ path = tmp;
+ path->realm = strdup(p);
+ if(path->realm == NULL){
+ r->next = path; /* XXX */
+ return ENOMEM;;
+ }
+ }
+ }else if(strncmp(from, to, strlen(to)) == 0){
+ p = from + strlen(from);
+ while(1){
+ while(p >= from && *p != '/') p--;
+ if(p == from)
+ return KRB5KDC_ERR_POLICY;
+ if(strncmp(to, from, p - from) == 0)
+ break;
+ tmp = calloc(1, sizeof(*tmp));
+ tmp->next = path;
+ path = tmp;
+ path->realm = malloc(p - from + 1);
+ if(path->realm == NULL){
+ r->next = path; /* XXX */
+ return ENOMEM;
+ }
+ strncpy(path->realm, from, p - from);
+ path->realm[p - from] = '\0';
+ p--;
+ }
+ }else
+ return KRB5KDC_ERR_POLICY;
+ r->next = path;
+
+ return 0;
+}
+
+static int
+make_paths(struct tr_realm *realms, const char *client_realm,
+ const char *server_realm)
+{
+ struct tr_realm *r;
+ int ret;
+ const char *prev_realm = client_realm;
+ const char *next_realm = NULL;
+ for(r = realms; r; r = r->next){
+ /* it *might* be that you can have more than one empty
+ component in a row, at least that's how I interpret the
+ "," exception in 1510 */
+ if(r->realm[0] == '\0'){
+ while(r->next && r->next->realm[0] == '\0')
+ r = r->next;
+ if(r->next)
+ next_realm = r->next->realm;
+ else
+ next_realm = server_realm;
+ ret = make_path(r, prev_realm, next_realm);
+ if(ret){
+ free_realms(realms);
+ return ret;
+ }
+ }
+ prev_realm = r->realm;
+ }
+ return 0;
+}
+
+static int
+expand_realms(struct tr_realm *realms, const char *client_realm)
+{
+ struct tr_realm *r;
+ const char *prev_realm = NULL;
+ for(r = realms; r; r = r->next){
+ if(r->trailing_dot){
+ char *tmp;
+ if(prev_realm == NULL)
+ prev_realm = client_realm;
+ tmp = realloc(r->realm, strlen(r->realm) + strlen(prev_realm) + 1);
+ if(tmp == NULL){
+ free_realms(realms);
+ return ENOMEM;
+ }
+ r->realm = tmp;
+ strcat(r->realm, prev_realm);
+ }else if(r->leading_slash && !r->leading_space && prev_realm){
+ /* yet another exception: if you use x500-names, the
+ leading realm doesn't have to be "quoted" with a space */
+ char *tmp;
+ tmp = malloc(strlen(r->realm) + strlen(prev_realm) + 1);
+ if(tmp == NULL){
+ free_realms(realms);
+ return ENOMEM;
+ }
+ strcpy(tmp, prev_realm);
+ strcat(tmp, r->realm);
+ free(r->realm);
+ r->realm = tmp;
+ }
+ prev_realm = r->realm;
+ }
+ return 0;
+}
+
+static struct tr_realm *
+make_realm(char *realm)
+{
+ struct tr_realm *r;
+ char *p, *q;
+ int quote = 0;
+ r = calloc(1, sizeof(*r));
+ if(r == NULL){
+ free(realm);
+ return NULL;
+ }
+ r->realm = realm;
+ for(p = q = r->realm; *p; p++){
+ if(p == r->realm && *p == ' '){
+ r->leading_space = 1;
+ continue;
+ }
+ if(q == r->realm && *p == '/')
+ r->leading_slash = 1;
+ if(quote){
+ *q++ = *p;
+ quote = 0;
+ continue;
+ }
+ if(*p == '\\'){
+ quote = 1;
+ continue;
+ }
+ if(p[0] == '.' && p[1] == '\0')
+ r->trailing_dot = 1;
+ *q++ = *p;
+ }
+ *q = '\0';
+ return r;
+}
+
+static struct tr_realm*
+append_realm(struct tr_realm *head, struct tr_realm *r)
+{
+ struct tr_realm *p;
+ if(head == NULL){
+ r->next = NULL;
+ return r;
+ }
+ p = head;
+ while(p->next) p = p->next;
+ p->next = r;
+ return head;
+}
+
+static int
+decode_realms(const char *tr, int length, struct tr_realm **realms)
+{
+ struct tr_realm *r = NULL;
+
+ char *tmp;
+ int quote = 0;
+ const char *start = tr;
+ int i;
+
+ for(i = 0; i < length; i++){
+ if(quote){
+ quote = 0;
+ continue;
+ }
+ if(tr[i] == '\\'){
+ quote = 1;
+ continue;
+ }
+ if(tr[i] == ','){
+ tmp = malloc(tr + i - start + 1);
+ strncpy(tmp, start, tr + i - start);
+ tmp[tr + i - start] = '\0';
+ r = make_realm(tmp);
+ if(r == NULL){
+ free_realms(*realms);
+ return ENOMEM;
+ }
+ *realms = append_realm(*realms, r);
+ start = tr + i + 1;
+ }
+ }
+ tmp = malloc(tr + i - start + 1);
+ strncpy(tmp, start, tr + i - start);
+ tmp[tr + i - start] = '\0';
+ r = make_realm(tmp);
+ if(r == NULL){
+ free_realms(*realms);
+ return ENOMEM;
+ }
+ *realms = append_realm(*realms, r);
+
+ return 0;
+}
+
+
+krb5_error_code
+krb5_domain_x500_decode(krb5_data tr, char ***realms, int *num_realms,
+ const char *client_realm, const char *server_realm)
+{
+ struct tr_realm *r = NULL;
+ struct tr_realm *p, **q;
+ int ret;
+
+ /* split string in components */
+ ret = decode_realms(tr.data, tr.length, &r);
+ if(ret)
+ return ret;
+
+ /* apply prefix rule */
+ ret = expand_realms(r, client_realm);
+ if(ret)
+ return ret;
+
+ ret = make_paths(r, client_realm, server_realm);
+ if(ret)
+ return ret;
+
+ /* remove empty components */
+ q = &r;
+ for(p = r; p; ){
+ if(p->realm[0] == '\0'){
+ free(p->realm);
+ *q = p->next;
+ free(p);
+ p = *q;
+ }else{
+ q = &p->next;
+ p = p->next;
+ }
+ }
+ {
+ char **R;
+ *realms = NULL;
+ *num_realms = 0;
+ while(r){
+ R = realloc(*realms, (*num_realms + 1) * sizeof(**realms));
+ if(R == NULL) {
+ free(*realms);
+ return ENOMEM;
+ }
+ R[*num_realms] = r->realm;
+ (*num_realms)++;
+ *realms = R;
+ p = r->next;
+ free(r);
+ r = p;
+ }
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding)
+{
+ char *s = NULL;
+ int len = 0;
+ int i;
+ for(i = 0; i < num_realms; i++){
+ len += strlen(realms[i]);
+ if(realms[i][0] == '/')
+ len++;
+ }
+ len += num_realms - 1;
+ s = malloc(len + 1);
+ *s = '\0';
+ for(i = 0; i < num_realms; i++){
+ if(i && i < num_realms - 1)
+ strcat(s, ",");
+ if(realms[i][0] == '/')
+ strcat(s, " ");
+ strcat(s, realms[i]);
+ }
+ encoding->data = s;
+ encoding->length = strlen(s);
+ return 0;
+}
+
+#if 0
+int
+main(int argc, char **argv)
+{
+ krb5_data x;
+ char **r;
+ int num, i;
+ x.data = argv[1];
+ x.length = strlen(x.data);
+ if(domain_expand(x, &r, &num, argv[2], argv[3]))
+ exit(1);
+ for(i = 0; i < num; i++)
+ printf("%s\n", r[i]);
+ return 0;
+}
+#endif
+
diff --git a/crypto/heimdal/lib/krb5/verify_init.c b/crypto/heimdal/lib/krb5/verify_init.c
new file mode 100644
index 000000000000..0f080ee331af
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/verify_init.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: verify_init.c,v 1.11 1999/12/02 17:05:13 joda Exp $");
+
+void
+krb5_verify_init_creds_opt_init(krb5_verify_init_creds_opt *options)
+{
+ memset (options, 0, sizeof(*options));
+}
+
+void
+krb5_verify_init_creds_opt_set_ap_req_nofail(krb5_verify_init_creds_opt *options,
+ int ap_req_nofail)
+{
+ options->flags |= KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL;
+ options->ap_req_nofail = ap_req_nofail;
+}
+
+/*
+ *
+ */
+
+static krb5_boolean
+fail_verify_is_ok (krb5_context context,
+ krb5_verify_init_creds_opt *options)
+{
+ if ((options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL
+ && options->ap_req_nofail == 1)
+ || krb5_config_get_bool (context,
+ NULL,
+ "libdefaults",
+ "verify_ap_req_nofail",
+ NULL))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+krb5_error_code
+krb5_verify_init_creds(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal ap_req_server,
+ krb5_keytab ap_req_keytab,
+ krb5_ccache *ccache,
+ krb5_verify_init_creds_opt *options)
+{
+ krb5_error_code ret;
+ krb5_data req;
+ krb5_ccache local_ccache;
+ krb5_keytab_entry entry;
+ krb5_creds *new_creds = NULL;
+ krb5_auth_context auth_context = NULL;
+ krb5_principal server = NULL;
+ krb5_keytab keytab = NULL;
+
+ krb5_data_zero (&req);
+ memset (&entry, 0, sizeof(entry));
+
+ if (ap_req_server == NULL) {
+ char local_hostname[MAXHOSTNAMELEN];
+
+ if (gethostname (local_hostname, sizeof(local_hostname)) < 0)
+ return errno;
+
+ ret = krb5_sname_to_principal (context,
+ local_hostname,
+ "host",
+ KRB5_NT_SRV_HST,
+ &server);
+ if (ret)
+ goto cleanup;
+ } else
+ server = ap_req_server;
+
+ if (ap_req_keytab == NULL) {
+ ret = krb5_kt_default (context, &keytab);
+ if (ret)
+ goto cleanup;
+ } else
+ keytab = ap_req_keytab;
+
+ if (ccache && *ccache)
+ local_ccache = *ccache;
+ else {
+ ret = krb5_cc_gen_new (context, &krb5_mcc_ops, &local_ccache);
+ if (ret)
+ goto cleanup;
+ ret = krb5_cc_initialize (context,
+ local_ccache,
+ creds->client);
+ if (ret)
+ goto cleanup;
+ ret = krb5_cc_store_cred (context,
+ local_ccache,
+ creds);
+ if (ret)
+ goto cleanup;
+ }
+
+ if (!krb5_principal_compare (context, server, creds->server)) {
+ krb5_creds match_cred;
+
+ memset (&match_cred, 0, sizeof(match_cred));
+
+ match_cred.client = creds->client;
+ match_cred.server = server;
+
+ ret = krb5_get_credentials (context,
+ 0,
+ local_ccache,
+ &match_cred,
+ &new_creds);
+ if (ret) {
+ if (fail_verify_is_ok (context, options))
+ ret = 0;
+ goto cleanup;
+ }
+ } else
+ new_creds = creds;
+
+ ret = krb5_mk_req_extended (context,
+ &auth_context,
+ 0,
+ NULL,
+ new_creds,
+ &req);
+
+ krb5_auth_con_free (context, auth_context);
+ auth_context = NULL;
+
+ if (ret)
+ goto cleanup;
+
+ ret = krb5_rd_req (context,
+ &auth_context,
+ &req,
+ server,
+ keytab,
+ 0,
+ NULL);
+
+ if (ret == KRB5_KT_NOTFOUND && fail_verify_is_ok (context, options))
+ ret = 0;
+cleanup:
+ if (auth_context)
+ krb5_auth_con_free (context, auth_context);
+ krb5_data_free (&req);
+ krb5_kt_free_entry (context, &entry);
+ if (new_creds)
+ krb5_free_creds (context, new_creds);
+ if (ap_req_server == NULL && server)
+ krb5_free_principal (context, server);
+ if (ap_req_keytab == NULL && keytab)
+ krb5_kt_close (context, keytab);
+ if (ccache == NULL
+ || (ret != 0 && *ccache == NULL))
+ krb5_cc_destroy (context, local_ccache);
+
+ if (ret == 0 && ccache != NULL && *ccache == NULL)
+ *ccache = local_ccache;
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/verify_krb5_conf.c b/crypto/heimdal/lib/krb5/verify_krb5_conf.c
new file mode 100644
index 000000000000..2b9ce28a38de
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/verify_krb5_conf.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+#include <getarg.h>
+RCSID("$Id: verify_krb5_conf.c,v 1.3 1999/12/02 17:05:13 joda Exp $");
+
+/* verify krb5.conf */
+
+static int version_flag = 0;
+static int help_flag = 0;
+
+static struct getargs args[] = {
+ {"version", 0, arg_flag, &version_flag,
+ "print version", NULL },
+ {"help", 0, arg_flag, &help_flag,
+ NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "[config-file]");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *config_file = NULL;
+ krb5_error_code ret;
+ krb5_config_section *tmp_cf;
+ unsigned lineno;
+ char *error_message;
+ int optind = 0;
+
+ set_progname (argv[0]);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0) {
+ config_file = getenv("KRB5_CONFIG");
+ if (config_file == NULL)
+ config_file = krb5_config_file;
+ } else if (argc == 1) {
+ config_file = argv[0];
+ } else {
+ usage (1);
+ }
+
+ ret = krb5_config_parse_file_debug (config_file, &tmp_cf, &lineno,
+ &error_message);
+ if (ret == 0)
+ return 0;
+ fprintf (stderr, "%s:%u: %s\n", config_file, lineno, error_message);
+ return 1;
+}
diff --git a/crypto/heimdal/lib/krb5/verify_user.c b/crypto/heimdal/lib/krb5/verify_user.c
new file mode 100644
index 000000000000..10c22cb7e72c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/verify_user.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: verify_user.c,v 1.11 1999/12/02 17:05:13 joda Exp $");
+
+static krb5_error_code
+verify_common (krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ krb5_boolean secure,
+ const char *service,
+ krb5_creds cred)
+{
+ krb5_error_code ret;
+ krb5_principal server;
+ krb5_verify_init_creds_opt vopt;
+ krb5_ccache id;
+
+ ret = krb5_sname_to_principal (context, NULL, service, KRB5_NT_SRV_HST,
+ &server);
+ if(ret) return ret;
+
+ krb5_verify_init_creds_opt_init(&vopt);
+ krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, secure);
+
+ ret = krb5_verify_init_creds(context,
+ &cred,
+ server,
+ NULL,
+ NULL,
+ &vopt);
+ krb5_free_principal(context, server);
+ if(ret) return ret;
+ if(ccache == NULL)
+ ret = krb5_cc_default (context, &id);
+ else
+ id = ccache;
+ if(ret == 0){
+ ret = krb5_cc_initialize(context, id, principal);
+ if(ret == 0){
+ ret = krb5_cc_store_cred(context, id, &cred);
+ }
+ if(ccache == NULL)
+ krb5_cc_close(context, id);
+ }
+ krb5_free_creds_contents(context, &cred);
+ return ret;
+}
+
+/*
+ * Verify user `principal' with `password'.
+ *
+ * If `secure', also verify against local service key for `service'.
+ *
+ * As a side effect, fresh tickets are obtained and stored in `ccache'.
+ */
+
+krb5_error_code
+krb5_verify_user(krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ const char *password,
+ krb5_boolean secure,
+ const char *service)
+{
+
+ krb5_error_code ret;
+ krb5_get_init_creds_opt opt;
+ krb5_creds cred;
+
+ krb5_get_init_creds_opt_init (&opt);
+
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ principal,
+ (char*)password,
+ krb5_prompter_posix,
+ NULL,
+ 0,
+ NULL,
+ &opt);
+
+ if(ret)
+ return ret;
+ return verify_common (context, principal, ccache, secure, service, cred);
+}
+
+/*
+ * A variant of `krb5_verify_user'. The realm of `principal' is
+ * ignored and all the local realms are tried.
+ */
+
+krb5_error_code
+krb5_verify_user_lrealm(krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ const char *password,
+ krb5_boolean secure,
+ const char *service)
+{
+ krb5_error_code ret;
+ krb5_get_init_creds_opt opt;
+ krb5_realm *realms, *r;
+ krb5_creds cred;
+
+ krb5_get_init_creds_opt_init (&opt);
+
+ ret = krb5_get_default_realms (context, &realms);
+ if (ret)
+ return ret;
+ ret = KRB5_CONFIG_NODEFREALM;
+
+ for (r = realms; *r != NULL && ret != 0; ++r) {
+ char *tmp = strdup (*r);
+
+ if (tmp == NULL) {
+ krb5_free_host_realm (context, realms);
+ return ENOMEM;
+ }
+ free (*krb5_princ_realm (context, principal));
+ krb5_princ_set_realm (context, principal, &tmp);
+
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ principal,
+ (char*)password,
+ krb5_prompter_posix,
+ NULL,
+ 0,
+ NULL,
+ &opt);
+ }
+ krb5_free_host_realm (context, realms);
+ if(ret)
+ return ret;
+
+ return verify_common (context, principal, ccache, secure, service, cred);
+}
diff --git a/crypto/heimdal/lib/krb5/version.c b/crypto/heimdal/lib/krb5/version.c
new file mode 100644
index 000000000000..5f0fd6680bf5
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/version.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: version.c,v 1.3 1999/12/02 17:05:13 joda Exp $");
+
+/* this is just to get a version stamp in the library file */
+
+#define heimdal_version __heimdal_version
+#define heimdal_long_version __heimdal_long_version
+#include "version.h"
+
diff --git a/crypto/heimdal/lib/krb5/warn.c b/crypto/heimdal/lib/krb5/warn.c
new file mode 100644
index 000000000000..b202f7dc4b9a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/warn.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+#include <err.h>
+
+RCSID("$Id: warn.c,v 1.10 1999/12/02 17:05:13 joda Exp $");
+
+static krb5_error_code
+_warnerr(krb5_context context, int do_errtext,
+ krb5_error_code code, int level, const char *fmt, va_list ap)
+{
+ char xfmt[7] = "";
+ const char *args[2], **arg;
+ char *msg = NULL;
+
+ arg = args;
+ if(fmt){
+ strcat(xfmt, "%s");
+ if(do_errtext)
+ strcat(xfmt, ": ");
+ vasprintf(&msg, fmt, ap);
+ if(msg == NULL)
+ return ENOMEM;
+ *arg++ = msg;
+ }
+ if(context && do_errtext){
+ const char *err_msg;
+
+ strcat(xfmt, "%s");
+
+ err_msg = krb5_get_err_text(context, code);
+ if (err_msg)
+ *arg++ = err_msg;
+ else
+ *arg++ = "<unknown error>";
+ }
+
+ if(context && context->warn_dest)
+ krb5_log(context, context->warn_dest, level, xfmt, args[0], args[1]);
+ else
+ warnx(xfmt, args[0], args[1]);
+ free(msg);
+ return 0;
+}
+
+#define FUNC(ETEXT, CODE, LEVEL) \
+ krb5_error_code ret; \
+ va_list ap; \
+ va_start(ap, fmt); \
+ ret = _warnerr(context, ETEXT, CODE, LEVEL, fmt, ap); \
+ va_end(ap);
+
+#undef __attribute__
+#define __attribute__(X)
+
+krb5_error_code
+krb5_vwarn(krb5_context context, krb5_error_code code,
+ const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 3, 0)))
+{
+ return _warnerr(context, 1, code, 1, fmt, ap);
+}
+
+
+krb5_error_code
+krb5_warn(krb5_context context, krb5_error_code code, const char *fmt, ...)
+ __attribute__ ((format (printf, 3, 4)))
+{
+ FUNC(1, code, 1);
+ return ret;
+}
+
+krb5_error_code
+krb5_vwarnx(krb5_context context, const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 2, 0)))
+{
+ return _warnerr(context, 0, 0, 1, fmt, ap);
+}
+
+krb5_error_code
+krb5_warnx(krb5_context context, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)))
+{
+ FUNC(0, 0, 1);
+ return ret;
+}
+
+krb5_error_code
+krb5_verr(krb5_context context, int eval, krb5_error_code code,
+ const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 4, 0)))
+{
+ _warnerr(context, 1, code, 0, fmt, ap);
+ exit(eval);
+}
+
+
+krb5_error_code
+krb5_err(krb5_context context, int eval, krb5_error_code code,
+ const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 4, 5)))
+{
+ FUNC(1, code, 0);
+ exit(eval);
+}
+
+krb5_error_code
+krb5_verrx(krb5_context context, int eval, const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 3, 0)))
+{
+ _warnerr(context, 0, 0, 0, fmt, ap);
+ exit(eval);
+}
+
+krb5_error_code
+krb5_errx(krb5_context context, int eval, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 3, 4)))
+{
+ FUNC(0, 0, 0);
+ exit(eval);
+}
+
+krb5_error_code
+krb5_vabort(krb5_context context, krb5_error_code code,
+ const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 3, 0)))
+{
+ _warnerr(context, 1, code, 0, fmt, ap);
+ abort();
+}
+
+
+krb5_error_code
+krb5_abort(krb5_context context, krb5_error_code code, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 3, 4)))
+{
+ FUNC(1, code, 0);
+ abort();
+}
+
+krb5_error_code
+krb5_vabortx(krb5_context context, const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 2, 0)))
+{
+ _warnerr(context, 0, 0, 0, fmt, ap);
+ abort();
+}
+
+krb5_error_code
+krb5_abortx(krb5_context context, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 2, 3)))
+{
+ FUNC(0, 0, 0);
+ abort();
+}
+
+krb5_error_code
+krb5_set_warn_dest(krb5_context context, krb5_log_facility *fac)
+{
+ context->warn_dest = fac;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/write_message.c b/crypto/heimdal/lib/krb5/write_message.c
new file mode 100644
index 000000000000..b7f2c2865ce6
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/write_message.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: write_message.c,v 1.4 1999/12/02 17:05:13 joda Exp $");
+
+krb5_error_code
+krb5_write_message (krb5_context context,
+ krb5_pointer p_fd,
+ krb5_data *data)
+{
+ u_int32_t len;
+ u_int8_t buf[4];
+
+ len = data->length;
+ buf[0] = (len >> 24) & 0xFF;
+ buf[1] = (len >> 16) & 0xFF;
+ buf[2] = (len >> 8) & 0xFF;
+ buf[3] = (len >> 0) & 0xFF;
+ if (krb5_net_write (context, p_fd, buf, 4) != 4
+ || krb5_net_write (context, p_fd, data->data, len) != len)
+ return errno;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/roken/ChangeLog b/crypto/heimdal/lib/roken/ChangeLog
new file mode 100644
index 000000000000..c7d816852e3d
--- /dev/null
+++ b/crypto/heimdal/lib/roken/ChangeLog
@@ -0,0 +1,715 @@
+2000-01-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 5:0:0
+
+1999-12-30 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (strpftime_test_SOURCES): correct source file name
+
+ * roken.h.in (sockaddr_storage): change padding so that we have
+ one char[] of pad and then an unsigned long[] (for alignment and
+ padding). this works much better in practice.
+
+1999-12-22 Assar Westerlund <assar@sics.se>
+
+ * roken.h.in (sockaddr_storage): drop leading underscore on
+ `public' fields. this was the consensus on the ipng mailing list
+
+1999-12-21 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (strpftime-test): define sources to avoid having
+ '.o'
+ * Makefile.am (print_version.h): use $(EXEEXT)
+ * Makefile.am (roken.h): add $(EXEEXT) to make this work on cygwin
+ et al
+
+1999-12-20 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libroken_la_LDFLAGS): bump version to 4:3:0
+
+ * getaddrinfo.c (get_nodes): use getipnodebyname instead of
+ gethostbyname(2)
+
+1999-12-16 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libroken_la_LDFLAGS): bump version to 4:2:0
+
+ * roken.h.in (struct sockaddr_storage): redefine with the example
+ code from rfc2553
+
+ * getaddrinfo.c (get_null): set loopback with correct endianess
+ for v4. dunno about v6.
+
+1999-12-13 Assar Westerlund <assar@sics.se>
+
+ * roken.h.in: add prototypes for str[pf]time
+
+ * signal.c: macosx = rhapsody ~= nextstep also can't handle
+ various definitions of the same symbol.
+
+1999-12-12 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 4:1:0
+
+1999-12-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 4:0:0
+
+1999-12-05 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: replace inaddr2str with getnameinfo_verified
+
+ * roken-common.h (INADDR_LOOPBACK): add fallback definition
+
+ * roken-common.h: move getnameinfo_verified to roken.h.in
+ * roken.h.in (inaddr2str): remove
+ * Makefile.am (libroken_la_SOURCES); removed inaddr2str
+ * roken-common.h (getnameinfo_verified): add prototype
+ * getnameinfo_verified.c: new file
+
+1999-12-04 Assar Westerlund <assar@sics.se>
+
+ * roken-common.h: add constants for getaddrinfo, getnameinfo
+ * roken.h.in (socklen_t): make independent of sockaddr_storage
+ (AI_*, NI_*, EAI_*): move to roken-common.h
+
+1999-12-03 Assar Westerlund <assar@sics.se>
+
+ * mini_inetd.c (mini_inted): rewrite to use `getaddrinfo'
+ * getaddrinfo.c (const_v*): no sizeof(sizeof())
+ * getaddrinfo.c (add_hostent): search for the canonical name among
+ all aliases
+ (getaddrinfo): handle AI_NUMERICHOST correctly
+ * Makefile.am (EXTRA_libroken_la_SOURCES): add freeaddinfo,
+ getaddrinfo, getnameinfo, gai_strerror
+ (getaddrinfo_test): add
+ * Makefile.in (SOURCES): add freeaddinfo, getaddrinfo,
+ getnameinfo, gai_strerror
+ (getaddrinfo_test): add
+ * roken.h.in: arpa/inet.h: include
+ (socklen_t): add
+ (struct addrinfo): add
+ (EAI_*): add
+ (NI_*): add
+ (AI_*): add
+ (getaddrinfo, getnameinfo, freeaddrinfo, gai_strerror): add
+ * getnameinfo.c: new file
+ * getaddrinfo-test.c: new file
+ * gai_strerror.c: new file
+ * getaddrinfo.c: new file
+ * freeaddrinfo.c: new file
+
+1999-11-25 Assar Westerlund <assar@sics.se>
+
+ * getopt.c (getopt): return -1 instead of EOF. From
+ <art@stacken.kth.se>
+
+1999-11-13 Assar Westerlund <assar@sics.se>
+
+ * strftime.c (strftime): handle `%z' and `%Z' in a tm_gmtoff-less
+ world
+
+ * getcap.c: make sure to use db only if we have both the library
+ and the header file
+
+1999-11-12 Assar Westerlund <assar@sics.se>
+
+ * getarg.h: add arg_counter
+ * getarg.c: add a new type of argument: `arg_counter' re-organize
+ the code somewhat
+
+ * Makefile.am: add strptime and strpftime-test
+
+ * snprintf.c (xyzprintf): try to do the right thing with an % at
+ the end of the format string
+
+ * strptime.c (strptime): implement '%U', '%V', '%W'
+ * strftime.c (strftime): implement '%U', '%V', '%W', '%z'
+
+ * strftime.c (strftime): correct %E and %O handling. do something
+ reasonable with "...%"
+
+ * strftime.c: replace the BSD implementation by one of our own
+ coding
+
+ * strptime.c : new file
+ * strpftime-test.c: new file
+
+1999-11-07 Assar Westerlund <assar@sics.se>
+
+ * parse_bytes-test.c: new file
+
+ * Makefile.am: add parse_bytes-test
+
+ * parse_units.c (parse_something): try to handle the case of no
+ value specified a little bit better
+
+1999-11-04 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 3:2:0
+
+1999-10-30 Assar Westerlund <assar@sics.se>
+
+ * snprintf.c (PARSE_INT_FORMAT): add redundant casts to work
+ around a gcc-bug that manifests itself on Linux-PPC. From Tom
+ Rini <trini@kernel.crashing.org>
+
+1999-10-28 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 3:1:0
+
+ * roken.h.in: use `unsigned char' instead of `u_int8_t' to avoid
+ having to have that definition. this is the easy way out instead
+ of getting the definition here where it's needed. flame me.
+
+Fri Oct 22 15:39:31 1999 Bjoern Groenvall <bg@sics.se>
+
+ * k_getpwuid.c (k_getpwuid): getspuid() does not exist (even
+ though it should), use getspnam().
+
+1999-10-20 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 3:0:0
+
+1999-10-18 Johan Danielsson <joda@pdc.kth.se>
+
+ * getarg.3: document arg_collect
+
+ * getarg.c: change the way arg_collect works; it's still quite
+ horrible though
+
+ * getarg.h: change type of the collect function
+
+1999-10-17 Assar Westerlund <assar@sics.se>
+
+ * xdbm.h: undo last commit
+
+ * xdbm.h: reorder db includes
+
+1999-10-10 Assar Westerlund <assar@sics.se>
+
+ * socket.c: const-ize and comment
+
+ * net_write.c: const-ize
+
+ * base64.c: const-ize
+
+1999-10-06 Assar Westerlund <assar@sics.se>
+
+ * getarg.c (getarg): also set optind when returning error
+
+1999-09-26 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: add parse_bytes.[ch]
+
+1999-09-24 Johan Danielsson <joda@pdc.kth.se>
+
+ * getarg.3: getarg manpage
+
+ * getarg.{c,h}: add a callback type to do more complicated processing
+
+ * getarg.{c,h}: add floating point support
+
+1999-09-16 Assar Westerlund <assar@sics.se>
+
+ * strlcat.c (strlcat): call strlcpy
+
+ * strlcpy.c: update name and prototype
+
+ * strlcat.c: update name and prototype
+
+ * roken.h.in: rename strc{py,at}_truncate to strlc{py,at}
+
+ * Makefile.am: rename strc{py,at}_truncate -> strlc{py,at}
+
+ * Makefile.in: rename strc{py,at}_truncate -> strlc{py,at}
+
+ * strcpy_truncate.c (strcpy_truncate): change return value to be
+ the length of `src'
+
+1999-08-16 Assar Westerlund <assar@sics.se>
+
+ * getcap.c: try to make this work on systems with DB
+
+1999-08-16 Johan Danielsson <joda@pdc.kth.se>
+
+ * getcap.c: protect from db-less systems
+
+1999-08-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * simple_exec.c: add simple_exec{ve,le}
+
+ * getcap.c: getcap from NetBSD
+
+1999-08-06 Assar Westerlund <assar@sics.se>
+
+ * roken.h.in (sockaddr_storage): cater for those that have
+ v6-support also
+
+1999-08-05 Assar Westerlund <assar@sics.se>
+
+ * inet_ntop.c (inet_ntop_v4): remember to call ntohl
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * roken-common.h: add shutdown constants
+
+ * mini_inetd.c (listen_v4, listen_v6): handle the case of the
+ protocol not being supported
+
+1999-08-01 Assar Westerlund <assar@sics.se>
+
+ * mini_inetd.c (socket_set_reuseaddr): remove duplicate
+
+1999-07-29 Assar Westerlund <assar@sics.se>
+
+ * mini_inetd.c (mini_inetd): fix my stupid bugs
+
+1999-07-28 Assar Westerlund <assar@sics.se>
+
+ * roken-common.h: add socket* functions
+
+ * Makefile.am (libroken_la_SOURCES): add socket.c
+
+ * socket.c: new file, originally from appl/ftp/common
+
+ * Makefile.am: set version to 2:0:2
+
+ * roken.h.in (inet_pton): add prototype
+
+ * Makefile.am (EXTRA_libroken_la_SOURCES): add inet_pton
+
+ * inet_pton.c: new file
+
+ * getipnodebyname.c (getipnodebyname): try gethostbyname2 if we
+ have it
+
+1999-07-27 Assar Westerlund <assar@sics.se>
+
+ * mini_inetd.c: support IPv6
+
+1999-07-26 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 1:0:1
+
+ * roken.h.in (inet_ntop): add prototype
+
+ * roken-common.h: (INET{,6}_ADDRSTRLEN): add
+
+ * inet_ntop.c: new file
+
+ * Makefile.am (EXTRA_libroken_la_SOURCES): add inet_ntop.c
+
+ * Makefile.am: move some files from libroken_la_SOURCES to
+ EXTRA_libroken_la_SOURCES
+
+ * snprintf.c: some signed vs unsigned casts
+
+1999-07-24 Assar Westerlund <assar@sics.se>
+
+ * roken.h.in (struct sockaddr_storage): define it needed
+
+1999-07-19 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libroken_la_SOURCES): add copyhostent.c,
+ freehostent.c, getipnodebyname.c, getipnodebyaddr.c
+
+ * roken.h.in: <netdb.h>: include
+ (copyhostent, freehostent, getipnodebyname, getipnodebyaddr): add
+ prototypes
+
+ * roken-common.h: new constants for getipnodeby*
+
+ * Makefile.in (SOURCES): add freehostent, copyhostent,
+ getipnodebyname, getipnodebyaddr
+
+ * freehostent.c: new file
+
+ * copyhostent.c: new file
+
+ * getipnodebyaddr.c: new file
+
+ * getipnodebyname.c: new file
+
+1999-07-13 Assar Westerlund <assar@sics.se>
+
+ * roken.h.in (k_getpwnam): update prototype
+
+ * k_getpwnam.c (k_getpwnam): const-ize
+
+ * get_default_username.c (get_default_username): a better way of
+ guessing when the user has su:ed
+
+1999-07-08 Johan Danielsson <joda@pdc.kth.se>
+
+ * roken.awk: use puts, as suggested by Jeffrey Hutzelman
+ <jhutz+@cmu.edu>
+
+1999-07-06 Assar Westerlund <assar@sics.se>
+
+ * readv.c (readv): typo
+
+1999-07-03 Assar Westerlund <assar@sics.se>
+
+ * writev.c (writev): error check malloc properly
+
+ * sendmsg.c (sendmsg): error check malloc properly
+
+ * resolve.c (parse_reply): error check malloc properly
+
+ * recvmsg.c (recvmsg): error check malloc properly
+
+ * readv.c (readv): error check malloc properly
+
+1999-06-23 Assar Westerlund <assar@sics.se>
+
+ * parse_units.c (acc_units): move the special case of 0 -> 1 to
+ parse_something to avoid having it happen at the end of the string
+
+1999-06-15 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: add get_default_username
+
+ * get_default_username.c: new file
+
+ * roken.h.in (get_default_username): add prototype
+
+ * Makefile.am: add get_default_username
+
+1999-05-08 Assar Westerlund <assar@sics.se>
+
+ * xdbm.h: also try <db.h> with DB_DBM_HSEARCH == 1
+
+ * strnlen.c (strnlen): update prototype
+
+ * Makefile.am: strndup.c: add
+
+ * Makefile.in: strndup.c: add
+
+ * roken.h.in (strndup): add
+ (strnlen): update prototype
+
+ * strndup.c: new file
+
+Fri Apr 16 17:59:30 1999 Assar Westerlund <assar@sics.se>
+
+ * roken.h.in: include strsep prototype if needed
+
+Thu Apr 15 14:04:03 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: make make-print-version.o depend on version.h
+
+Wed Apr 7 14:11:00 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: make it compile w/o krb4
+
+Sat Mar 27 17:33:03 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * snprintf.c (vasnprintf): correct check if realloc returns NULL
+
+Sat Mar 27 12:37:55 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: link print_version with -ldes to avoid unresolved
+ references if -lkrb is shared
+
+Sat Mar 20 03:42:30 1999 Assar Westerlund <assar@sics.se>
+
+ * roken-common.h (eread, ewrite): add
+
+ * simple_exec.c: add <roken.h>
+
+Fri Mar 19 21:29:58 1999 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: add eread, ewrite
+
+ * eread.c, ewrite.c: new files
+
+ * Makefile.am (libroken_la_SOURCES): add eread and ewrite
+
+Fri Mar 19 14:52:57 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: add version-info
+
+Thu Mar 18 12:53:32 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: remove include_dir hack
+
+ * Makefile.am: parse_units.h
+
+ * Makefile.am: include Makefile.am.common
+
+Sat Mar 13 23:31:35 1999 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (SOURCES): add glob.c
+
+Thu Mar 11 15:02:21 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * iruserok.c: move innetgr() to separate file
+
+ * innetgr.c: move innetgr() to separate file
+
+ * hstrerror.c (hstrerror): add const to return type
+
+ * erealloc.c: fix types in format string
+
+ * emalloc.c: fix types in format string
+
+Wed Mar 10 16:36:55 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * resolve.c: ugly fix for crays
+
+Mon Mar 8 11:52:20 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * roken.h.in: protos for {un,}setenv
+
+1999-02-16 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (SOURCES): add fnmatch
+
+ * roken-common.h (abs): add
+
+Sat Feb 13 17:12:53 1999 Assar Westerlund <assar@sics.se>
+
+ * emalloc.c, erealloc.c, estrup.c: new files
+
+ * roken.h.in (mkstemp, gethostname): also includes prototypes if
+ they are needed.
+
+1998-12-23 Assar Westerlund <assar@sics.se>
+
+ * roken.h.in: mkstemp: add prototype
+
+1998-12-20 Assar Westerlund <assar@sics.se>
+
+ * snprintf.c, iruserok.c, parse-units.c: unsigned char-correctness
+
+ * roken.h.in (inet_aton): also chedk NEED_INET_ATON_PROTO
+
+ * roken-common.h: __attribute__: check for autoconf'd
+ HAVE___ATTRIBUTE__ instead of GNUC
+
+Sun Dec 6 19:53:21 1998 Assar Westerlund <assar@sics.se>
+
+ * parse_units.c (parse_something): func is called with val == 0 if
+ no unit was given
+ (acc_flags, acc_units): update to new standard
+
+Fri Nov 27 03:09:42 1998 Assar Westerlund <assar@sics.se>
+
+ * resolve.c (stot): constify
+ (type_to_string): always declare
+ (dns_lookup_int): correct debug output
+
+Thu Nov 26 23:43:55 1998 Assar Westerlund <assar@sics.se>
+
+ * resolve.c (dns_lookup_int): send rr_class to res_search
+
+Thu Nov 26 17:09:47 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * resolve.c: some cleanup
+
+ * resolve.h: add T_NAPTR
+
+Sun Nov 22 10:23:07 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (WFLAGS): set
+
+ * k_getpwnam.c (k_getpwnam): check for `struct spwd'
+
+ * k_getpwuid.c (k_getpwuid): check for `struct spwd'
+
+Tue Sep 8 05:18:31 1998 Assar Westerlund <assar@sics.se>
+
+ * recvmsg.c (recvmsg): patch from bpreece@unity.ncsu.edu
+
+Fri Sep 4 16:29:27 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * vsyslog.c: asprintf -> vasprintf
+
+Tue Aug 18 22:25:52 1998 Assar Westerlund <assar@sics.se>
+
+ * getarg.h (arg_printusage): new signature
+
+ * getarg.c (arg_printusage): new parameter `progname'. NULL means
+ __progname.
+
+Sun Aug 9 14:53:44 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Makefile.am: net_{read,write}.c
+
+Fri Jul 24 21:56:02 1998 Assar Westerlund <assar@sics.se>
+
+ * simple_exec.c (simple_execvp): loop around waitpid when errno ==
+ EINTR
+
+Thu Jul 23 20:24:35 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Makefile.am: net_{read,write}.c
+
+Wed Jul 22 21:38:35 1998 Assar Westerlund <assar@sics.se>
+
+ * simple_exec.c (simple_execlp): initialize `argv'
+
+Mon Jul 13 23:01:22 1998 Assar Westerlund <assar@sics.se>
+
+ * inaddr2str.c (inaddr2str): don't advance hostent->h_addr_list,
+ use a copy instead
+
+Fri Jul 10 01:20:08 1998 Assar Westerlund <assar@sics.se>
+
+ * roken.h.in (net_write, net_read): add prototypes
+
+ * Makefile.in: net_{read,write}.c: add
+
+ * net_{read,write}.c: new files
+
+Tue Jun 30 17:29:09 1998 Assar Westerlund <assar@sics.se>
+
+ * roken.h.in (issuid): add
+
+ * get_window_size.c: fix misspelling of TIOCGWINSZ and bad use of
+ fields
+
+Sun May 31 03:24:34 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * getarg.c (mandoc_template): Put short and long options in
+ SYNOPSIS within the same [ ] pair.
+
+Sat May 30 00:13:01 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * getarg.c (arg_printusage): try to keep options shorter than
+ column width
+
+ * get_window_size.c (get_window_size): check COLUMNS and LINES
+
+Fri May 29 00:05:04 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * getarg.c (mandoc_template): Put short and long options in
+ DESCRIPTION on the same line.
+
+ * getarg.c (arg_match_long): make sure you only get an exact match
+ if the strings are the same length
+
+Thu May 14 02:23:40 1998 Assar Westerlund <assar@sics.se>
+
+ * roken.awk: stupid cray awk wants \#
+
+Fri May 1 01:29:36 1998 Assar Westerlund <assar@sics.se>
+
+ * print_version.c (print_version): according to ISO/ANSI C the
+ elements of `arg' are not constant and therefore not settable at
+ compile-time. Set the at run-time instead.
+
+Sun Apr 19 10:00:06 1998 Assar Westerlund <assar@sics.se>
+
+ * roken.h.in: include paths.h
+
+Sun Apr 5 12:30:49 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (SOURCES): add roken_gethostby.c to make solaris
+ make happy
+
+Thu Mar 19 20:41:25 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * simple_exec.c: Simple fork+exec system() replacement.
+
+Fri Mar 6 00:21:53 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * roken_gethostby.c: Make `roken_gethostby_setup' take url-like
+ specification instead of split up versions. Makes it easier for
+ calling applications.
+
+ * roken_gethostby.c: Another miracle of the 20th century:
+ gethostby* over HTTP.
+
+Sat Feb 21 15:18:36 1998 assar westerlund <assar@sics.se>
+
+ * parse_time.c (unparse_time_approx): new function that calls
+ `unparse_units_approx'
+
+ * parse_units.c (unparse_units_approx): new function that will
+ only print the first unit.
+
+ * Makefile.in: include parse_{time,units}
+
+Thu Feb 12 03:30:08 1998 Assar Westerlund <assar@sics.se>
+
+ * parse_time.c (print_time_table): don't return a void value.
+
+Tue Feb 3 11:06:24 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * getarg.c (mandoc_template): Change date format to full month
+ name, and day of month without leading zero.
+
+Thu Jan 22 21:23:23 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * getarg.c: Fix long form of negative flags.
+
+Mon Dec 29 23:31:10 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * roken.h.in: Include <err.h>, to get linux __progname.
+
+Sun Dec 21 09:45:18 1997 Assar Westerlund <assar@sics.se>
+
+ * parse_time.c (print_time_table): new function
+
+ * parse_units.c (print_flags_table, print_units_table): new
+ functions.
+
+Thu Dec 4 02:51:46 1997 Assar Westerlund <assar@sics.se>
+
+ * iruserok.c: moved here.
+
+ * snprintf.c (sn_append_char): don't write any terminating zero.
+ (as_reserve): don't loop. better heuristic for how much space to
+ realloc.
+ (vasnprintf): simplify initializing to one.
+
+Sun Nov 30 14:56:59 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * getarg.c: Add mandoc help back-end to getarg.
+
+Wed Nov 12 01:09:17 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * verr.c, verrx.c: Fix warnings by moving exit from.
+
+Tue Nov 11 21:12:09 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * parse_units.c: Change the list of separating characters (between
+ units) to comma, space, and tab, removing digits. Having digits in
+ this list makes a flag like `T42 generate a parse error. This
+ change makes `17m3s' an invalid time-spec (you need a space).
+
+Tue Nov 11 02:38:44 1997 Assar Westerlund <assar@sics.se>
+
+ * roken.h: add <sys/socket.h>
+
+Sun Nov 9 04:48:46 1997 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * fnmatch.c: Add fnmatch from NetBSD
+
+Sun Nov 9 02:00:08 1997 Assar Westerlund <assar@sics.se>
+
+ * parse_units.c (parse_something): ignore white-space and ','
+
+Mon Nov 3 22:38:32 1997 Assar Westerlund <assar@sics.se>
+
+ * roken.h: fclose prototype
+
+ * roken.h: add prototype for vsyslog
+
+ * Makefile.in: add some more source files to make soriasis make
+ happy
+
+Sat Nov 1 00:19:21 1997 Assar Westerlund <assar@sics.se>
+
+ * roken.h: include <sys/uio.h> and <errno.h>.
+ prototypes for readv and writev
+
+ * readv.c, writev.c: new files
+
+Wed Oct 29 02:21:38 1997 Assar Westerlund <assar@sics.se>
+
+ * roken.h: Add ugly macros for openlog, gethostbyname,
+ gethostbyaddr, and getservbyname for the benefit of Crays. Add
+ default definition of MAXPATHLEN
diff --git a/crypto/heimdal/lib/roken/Makefile.am b/crypto/heimdal/lib/roken/Makefile.am
new file mode 100644
index 000000000000..6499872b22ba
--- /dev/null
+++ b/crypto/heimdal/lib/roken/Makefile.am
@@ -0,0 +1,177 @@
+# $Id: Makefile.am,v 1.65 2000/01/06 22:24:36 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+CLEANFILES = roken.h make-roken.c print_version.h
+
+lib_LTLIBRARIES = libroken.la
+libroken_la_LDFLAGS = -version-info 5:0:0
+
+noinst_PROGRAMS = make-roken make-print-version
+
+check_PROGRAMS = parse_bytes-test strpftime-test getaddrinfo-test
+TESTS = $(check_PROGRAMS)
+
+getaddrinfo_test_LDADD = libroken.la
+parse_bytes_test_LDADD = libroken.la
+strpftime_test_SOURCES = strpftime-test.c strftime.c strptime.c snprintf.c
+
+if KRB4
+if KRB5
+## need to link with des here; otherwise, if krb4 is shared the link
+## will fail with unresolved references
+make_print_version_LDADD += $(LIB_krb4) -ldes
+endif
+endif
+
+libroken_la_SOURCES = \
+ base64.c \
+ concat.c \
+ emalloc.c \
+ eread.c \
+ erealloc.c \
+ estrdup.c \
+ ewrite.c \
+ get_default_username.c \
+ get_window_size.c \
+ getarg.c \
+ getnameinfo_verified.c \
+ issuid.c \
+ k_getpwnam.c \
+ k_getpwuid.c \
+ mini_inetd.c \
+ net_read.c \
+ net_write.c \
+ parse_bytes.c \
+ parse_time.c \
+ parse_units.c \
+ print_version.c \
+ resolve.c \
+ roken_gethostby.c \
+ signal.c \
+ simple_exec.c \
+ snprintf.c \
+ socket.c \
+ tm2time.c \
+ verify.c \
+ warnerr.c \
+ xdbm.h
+
+EXTRA_libroken_la_SOURCES = \
+ chown.c \
+ copyhostent.c \
+ daemon.c \
+ err.c \
+ err.h \
+ errx.c \
+ fchown.c \
+ flock.c \
+ fnmatch.c \
+ fnmatch.h \
+ freeaddrinfo.c \
+ freehostent.c \
+ gai_strerror.c \
+ getaddrinfo.c \
+ getdtablesize.c \
+ getegid.c \
+ geteuid.c \
+ getgid.c \
+ gethostname.c \
+ getipnodebyaddr.c \
+ getipnodebyname.c \
+ getnameinfo.c \
+ getopt.c \
+ gettimeofday.c \
+ getuid.c \
+ getusershell.c \
+ glob.h \
+ hstrerror.c \
+ inet_aton.c \
+ inet_ntop.c \
+ inet_pton.c \
+ initgroups.c \
+ innetgr.c \
+ iruserok.c \
+ lstat.c \
+ memmove.c \
+ mkstemp.c \
+ putenv.c \
+ rcmd.c \
+ readv.c \
+ recvmsg.c \
+ sendmsg.c \
+ setegid.c \
+ setenv.c \
+ seteuid.c \
+ strcasecmp.c \
+ strdup.c \
+ strerror.c \
+ strftime.c \
+ strlcat.c \
+ strlcpy.c \
+ strlwr.c \
+ strncasecmp.c \
+ strndup.c \
+ strnlen.c \
+ strptime.c \
+ strsep.c \
+ strtok_r.c \
+ strupr.c \
+ swab.c \
+ unsetenv.c \
+ verr.c \
+ verrx.c \
+ vsyslog.c \
+ vwarn.c \
+ vwarnx.c \
+ warn.c \
+ warnx.c \
+ writev.c
+
+EXTRA_DIST = resource.h roken.awk roken.def roken.dsp roken.h.in \
+ roken.mak roken.rc
+
+
+
+libroken_la_LIBADD = @LTLIBOBJS@
+
+$(LTLIBOBJS) $(libroken_la_OBJECTS): roken.h
+
+include_HEADERS = $(err_h) base64.h getarg.h \
+ parse_bytes.h parse_time.h parse_units.h \
+ resolve.h roken.h roken-common.h
+
+build_HEADERZ = $(err_h) $(fnmatch_h) $(glob_h) xdbm.h
+
+if have_err_h
+err_h =
+else
+err_h = err.h
+endif
+
+if have_fnmatch_h
+fnmatch_h =
+else
+fnmatch_h = fnmatch.h
+endif
+
+if have_glob_h
+glob_h =
+else
+glob_h = glob.h
+endif
+
+roken.h: make-roken$(EXEEXT)
+ @./make-roken$(EXEEXT) > tmp.h ;\
+ if [ -f roken.h ] && cmp -s tmp.h roken.h ; then rm -f tmp.h ; \
+ else rm -f roken.h; mv tmp.h roken.h; fi
+
+make-roken.c: roken.h.in roken.awk
+ $(AWK) -f $(srcdir)/roken.awk $(srcdir)/roken.h.in > make-roken.c
+
+print_version.lo: print_version.h
+
+print_version.h: make-print-version$(EXEEXT)
+ ./make-print-version$(EXEEXT) print_version.h
+
+make-print-version.o: $(top_builddir)/include/version.h
diff --git a/crypto/heimdal/lib/roken/Makefile.in b/crypto/heimdal/lib/roken/Makefile.in
new file mode 100644
index 000000000000..02d18cd48d09
--- /dev/null
+++ b/crypto/heimdal/lib/roken/Makefile.in
@@ -0,0 +1,800 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.65 2000/01/06 22:24:36 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+CLEANFILES = roken.h make-roken.c print_version.h
+
+lib_LTLIBRARIES = libroken.la
+libroken_la_LDFLAGS = -version-info 5:0:0
+
+noinst_PROGRAMS = make-roken make-print-version
+
+check_PROGRAMS = parse_bytes-test strpftime-test getaddrinfo-test
+TESTS = $(check_PROGRAMS)
+
+getaddrinfo_test_LDADD = libroken.la
+parse_bytes_test_LDADD = libroken.la
+strpftime_test_SOURCES = strpftime-test.c strftime.c strptime.c snprintf.c
+
+@KRB4_TRUE@@KRB5_TRUE@make_print_version_LDADD = $(LIB_krb4) -ldes
+
+libroken_la_SOURCES = base64.c concat.c emalloc.c eread.c erealloc.c estrdup.c ewrite.c get_default_username.c get_window_size.c getarg.c getnameinfo_verified.c issuid.c k_getpwnam.c k_getpwuid.c mini_inetd.c net_read.c net_write.c parse_bytes.c parse_time.c parse_units.c print_version.c resolve.c roken_gethostby.c signal.c simple_exec.c snprintf.c socket.c tm2time.c verify.c warnerr.c xdbm.h
+
+
+EXTRA_libroken_la_SOURCES = chown.c copyhostent.c daemon.c err.c err.h errx.c fchown.c flock.c fnmatch.c fnmatch.h freeaddrinfo.c freehostent.c gai_strerror.c getaddrinfo.c getdtablesize.c getegid.c geteuid.c getgid.c gethostname.c getipnodebyaddr.c getipnodebyname.c getnameinfo.c getopt.c gettimeofday.c getuid.c getusershell.c glob.h hstrerror.c inet_aton.c inet_ntop.c inet_pton.c initgroups.c innetgr.c iruserok.c lstat.c memmove.c mkstemp.c putenv.c rcmd.c readv.c recvmsg.c sendmsg.c setegid.c setenv.c seteuid.c strcasecmp.c strdup.c strerror.c strftime.c strlcat.c strlcpy.c strlwr.c strncasecmp.c strndup.c strnlen.c strptime.c strsep.c strtok_r.c strupr.c swab.c unsetenv.c verr.c verrx.c vsyslog.c vwarn.c vwarnx.c warn.c warnx.c writev.c
+
+
+EXTRA_DIST = resource.h roken.awk roken.def roken.dsp roken.h.in roken.mak roken.rc
+
+
+libroken_la_LIBADD = @LTLIBOBJS@
+
+include_HEADERS = $(err_h) base64.h getarg.h parse_bytes.h parse_time.h parse_units.h resolve.h roken.h roken-common.h
+
+
+build_HEADERZ = $(err_h) $(fnmatch_h) $(glob_h) xdbm.h
+@have_err_h_TRUE@err_h =
+@have_err_h_FALSE@err_h = err.h
+@have_fnmatch_h_TRUE@fnmatch_h =
+@have_fnmatch_h_FALSE@fnmatch_h = fnmatch.h
+@have_glob_h_TRUE@glob_h =
+@have_glob_h_FALSE@glob_h = glob.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libroken_la_DEPENDENCIES = @LTLIBOBJS@
+libroken_la_OBJECTS = base64.lo concat.lo emalloc.lo eread.lo \
+erealloc.lo estrdup.lo ewrite.lo get_default_username.lo \
+get_window_size.lo getarg.lo getnameinfo_verified.lo issuid.lo \
+k_getpwnam.lo k_getpwuid.lo mini_inetd.lo net_read.lo net_write.lo \
+parse_bytes.lo parse_time.lo parse_units.lo print_version.lo resolve.lo \
+roken_gethostby.lo signal.lo simple_exec.lo snprintf.lo socket.lo \
+tm2time.lo verify.lo warnerr.lo
+check_PROGRAMS = parse_bytes-test$(EXEEXT) strpftime-test$(EXEEXT) \
+getaddrinfo-test$(EXEEXT)
+noinst_PROGRAMS = make-roken$(EXEEXT) make-print-version$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+parse_bytes_test_SOURCES = parse_bytes-test.c
+parse_bytes_test_OBJECTS = parse_bytes-test.$(OBJEXT)
+parse_bytes_test_DEPENDENCIES = libroken.la
+parse_bytes_test_LDFLAGS =
+strpftime_test_OBJECTS = strpftime-test.$(OBJEXT) strftime.$(OBJEXT) \
+strptime.$(OBJEXT) snprintf.$(OBJEXT)
+strpftime_test_LDADD = $(LDADD)
+strpftime_test_DEPENDENCIES =
+strpftime_test_LDFLAGS =
+getaddrinfo_test_SOURCES = getaddrinfo-test.c
+getaddrinfo_test_OBJECTS = getaddrinfo-test.$(OBJEXT)
+getaddrinfo_test_DEPENDENCIES = libroken.la
+getaddrinfo_test_LDFLAGS =
+make_roken_SOURCES = make-roken.c
+make_roken_OBJECTS = make-roken.$(OBJEXT)
+make_roken_LDADD = $(LDADD)
+make_roken_DEPENDENCIES =
+make_roken_LDFLAGS =
+make_print_version_SOURCES = make-print-version.c
+make_print_version_OBJECTS = make-print-version.$(OBJEXT)
+@KRB4_TRUE@@KRB5_TRUE@make_print_version_DEPENDENCIES =
+make_print_version_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(include_HEADERS)
+
+DIST_COMMON = ChangeLog Makefile.am Makefile.in getcap.c glob.c \
+make-print-version.c
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libroken_la_SOURCES) $(EXTRA_libroken_la_SOURCES) parse_bytes-test.c $(strpftime_test_SOURCES) getaddrinfo-test.c make-roken.c make-print-version.c
+OBJECTS = $(libroken_la_OBJECTS) parse_bytes-test.$(OBJEXT) $(strpftime_test_OBJECTS) getaddrinfo-test.$(OBJEXT) make-roken.$(OBJEXT) make-print-version.$(OBJEXT)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/roken/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libroken.la: $(libroken_la_OBJECTS) $(libroken_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libroken_la_LDFLAGS) $(libroken_la_OBJECTS) $(libroken_la_LIBADD) $(LIBS)
+
+mostlyclean-checkPROGRAMS:
+
+clean-checkPROGRAMS:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+
+distclean-checkPROGRAMS:
+
+maintainer-clean-checkPROGRAMS:
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+parse_bytes-test$(EXEEXT): $(parse_bytes_test_OBJECTS) $(parse_bytes_test_DEPENDENCIES)
+ @rm -f parse_bytes-test$(EXEEXT)
+ $(LINK) $(parse_bytes_test_LDFLAGS) $(parse_bytes_test_OBJECTS) $(parse_bytes_test_LDADD) $(LIBS)
+
+strpftime-test$(EXEEXT): $(strpftime_test_OBJECTS) $(strpftime_test_DEPENDENCIES)
+ @rm -f strpftime-test$(EXEEXT)
+ $(LINK) $(strpftime_test_LDFLAGS) $(strpftime_test_OBJECTS) $(strpftime_test_LDADD) $(LIBS)
+
+getaddrinfo-test$(EXEEXT): $(getaddrinfo_test_OBJECTS) $(getaddrinfo_test_DEPENDENCIES)
+ @rm -f getaddrinfo-test$(EXEEXT)
+ $(LINK) $(getaddrinfo_test_LDFLAGS) $(getaddrinfo_test_OBJECTS) $(getaddrinfo_test_LDADD) $(LIBS)
+
+make-roken$(EXEEXT): $(make_roken_OBJECTS) $(make_roken_DEPENDENCIES)
+ @rm -f make-roken$(EXEEXT)
+ $(LINK) $(make_roken_LDFLAGS) $(make_roken_OBJECTS) $(make_roken_LDADD) $(LIBS)
+
+make-print-version$(EXEEXT): $(make_print_version_OBJECTS) $(make_print_version_DEPENDENCIES)
+ @rm -f make-print-version$(EXEEXT)
+ $(LINK) $(make_print_version_LDFLAGS) $(make_print_version_OBJECTS) $(make_print_version_LDADD) $(LIBS)
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/roken
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+check-TESTS: $(TESTS)
+ @failed=0; all=0; \
+ srcdir=$(srcdir); export srcdir; \
+ for tst in $(TESTS); do \
+ if test -f $$tst; then dir=.; \
+ else dir="$(srcdir)"; fi; \
+ if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \
+ all=`expr $$all + 1`; \
+ echo "PASS: $$tst"; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-includeHEADERS install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-checkPROGRAMS \
+ mostlyclean-noinstPROGRAMS mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \
+ clean-checkPROGRAMS clean-noinstPROGRAMS clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-checkPROGRAMS \
+ distclean-noinstPROGRAMS distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-checkPROGRAMS \
+ maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool mostlyclean-checkPROGRAMS \
+distclean-checkPROGRAMS clean-checkPROGRAMS \
+maintainer-clean-checkPROGRAMS mostlyclean-noinstPROGRAMS \
+distclean-noinstPROGRAMS clean-noinstPROGRAMS \
+maintainer-clean-noinstPROGRAMS uninstall-includeHEADERS \
+install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir check-TESTS info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-local install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+$(LTLIBOBJS) $(libroken_la_OBJECTS): roken.h
+
+roken.h: make-roken$(EXEEXT)
+ @./make-roken$(EXEEXT) > tmp.h ;\
+ if [ -f roken.h ] && cmp -s tmp.h roken.h ; then rm -f tmp.h ; \
+ else rm -f roken.h; mv tmp.h roken.h; fi
+
+make-roken.c: roken.h.in roken.awk
+ $(AWK) -f $(srcdir)/roken.awk $(srcdir)/roken.h.in > make-roken.c
+
+print_version.lo: print_version.h
+
+print_version.h: make-print-version$(EXEEXT)
+ ./make-print-version$(EXEEXT) print_version.h
+
+make-print-version.o: $(top_builddir)/include/version.h
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/roken/base64.c b/crypto/heimdal/lib/roken/base64.c
new file mode 100644
index 000000000000..daed8697ce26
--- /dev/null
+++ b/crypto/heimdal/lib/roken/base64.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: base64.c,v 1.4 1999/12/02 16:58:45 joda Exp $");
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include "base64.h"
+
+static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static int pos(char c)
+{
+ char *p;
+ for(p = base64; *p; p++)
+ if(*p == c)
+ return p - base64;
+ return -1;
+}
+
+int base64_encode(const void *data, int size, char **str)
+{
+ char *s, *p;
+ int i;
+ int c;
+ const unsigned char *q;
+
+ p = s = (char*)malloc(size*4/3+4);
+ if (p == NULL)
+ return -1;
+ q = (const unsigned char*)data;
+ i=0;
+ for(i = 0; i < size;){
+ c=q[i++];
+ c*=256;
+ if(i < size)
+ c+=q[i];
+ i++;
+ c*=256;
+ if(i < size)
+ c+=q[i];
+ i++;
+ p[0]=base64[(c&0x00fc0000) >> 18];
+ p[1]=base64[(c&0x0003f000) >> 12];
+ p[2]=base64[(c&0x00000fc0) >> 6];
+ p[3]=base64[(c&0x0000003f) >> 0];
+ if(i > size)
+ p[3]='=';
+ if(i > size+1)
+ p[2]='=';
+ p+=4;
+ }
+ *p=0;
+ *str = s;
+ return strlen(s);
+}
+
+int base64_decode(const char *str, void *data)
+{
+ const char *p;
+ unsigned char *q;
+ int c;
+ int x;
+ int done = 0;
+ q=(unsigned char*)data;
+ for(p=str; *p && !done; p+=4){
+ x = pos(p[0]);
+ if(x >= 0)
+ c = x;
+ else{
+ done = 3;
+ break;
+ }
+ c*=64;
+
+ x = pos(p[1]);
+ if(x >= 0)
+ c += x;
+ else
+ return -1;
+ c*=64;
+
+ if(p[2] == '=')
+ done++;
+ else{
+ x = pos(p[2]);
+ if(x >= 0)
+ c += x;
+ else
+ return -1;
+ }
+ c*=64;
+
+ if(p[3] == '=')
+ done++;
+ else{
+ if(done)
+ return -1;
+ x = pos(p[3]);
+ if(x >= 0)
+ c += x;
+ else
+ return -1;
+ }
+ if(done < 3)
+ *q++=(c&0x00ff0000)>>16;
+
+ if(done < 2)
+ *q++=(c&0x0000ff00)>>8;
+ if(done < 1)
+ *q++=(c&0x000000ff)>>0;
+ }
+ return q - (unsigned char*)data;
+}
diff --git a/crypto/heimdal/lib/roken/base64.h b/crypto/heimdal/lib/roken/base64.h
new file mode 100644
index 000000000000..5ad1e3b18ea9
--- /dev/null
+++ b/crypto/heimdal/lib/roken/base64.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: base64.h,v 1.2 1999/12/02 16:58:45 joda Exp $ */
+
+#ifndef _BASE64_H_
+#define _BASE64_H_
+
+int base64_encode(const void *data, int size, char **str);
+int base64_decode(const char *str, void *data);
+
+#endif
diff --git a/crypto/heimdal/lib/roken/chown.c b/crypto/heimdal/lib/roken/chown.c
new file mode 100644
index 000000000000..f3d34e303030
--- /dev/null
+++ b/crypto/heimdal/lib/roken/chown.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: chown.c,v 1.3 1999/12/02 16:58:45 joda Exp $");
+#endif
+
+#include "roken.h"
+
+int
+chown(const char *path, uid_t owner, gid_t group)
+{
+ return 0;
+}
diff --git a/crypto/heimdal/lib/roken/concat.c b/crypto/heimdal/lib/roken/concat.c
new file mode 100644
index 000000000000..ca295c030ae5
--- /dev/null
+++ b/crypto/heimdal/lib/roken/concat.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: concat.c,v 1.4 1999/12/02 16:58:45 joda Exp $");
+#endif
+#include "roken.h"
+
+int
+roken_concat (char *s, size_t len, ...)
+{
+ int ret;
+ va_list args;
+
+ va_start(args, len);
+ ret = roken_vconcat (s, len, args);
+ va_end(args);
+ return ret;
+}
+
+int
+roken_vconcat (char *s, size_t len, va_list args)
+{
+ const char *a;
+
+ while ((a = va_arg(args, const char*))) {
+ size_t n = strlen (a);
+
+ if (n >= len)
+ return -1;
+ memcpy (s, a, n);
+ s += n;
+ len -= n;
+ }
+ *s = '\0';
+ return 0;
+}
+
+size_t
+roken_vmconcat (char **s, size_t max_len, va_list args)
+{
+ const char *a;
+ char *p, *q;
+ size_t len = 0;
+ *s = NULL;
+ p = malloc(1);
+ if(p == NULL)
+ return 0;
+ len = 1;
+ while ((a = va_arg(args, const char*))) {
+ size_t n = strlen (a);
+
+ if(max_len && len + n > max_len){
+ free(p);
+ return 0;
+ }
+ q = realloc(p, len + n);
+ if(q == NULL){
+ free(p);
+ return 0;
+ }
+ p = q;
+ memcpy (p + len - 1, a, n);
+ len += n;
+ }
+ p[len - 1] = '\0';
+ *s = p;
+ return len;
+}
+
+size_t
+roken_mconcat (char **s, size_t max_len, ...)
+{
+ int ret;
+ va_list args;
+
+ va_start(args, max_len);
+ ret = roken_vmconcat (s, max_len, args);
+ va_end(args);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/copyhostent.c b/crypto/heimdal/lib/roken/copyhostent.c
new file mode 100644
index 000000000000..a3be6db9134d
--- /dev/null
+++ b/crypto/heimdal/lib/roken/copyhostent.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: copyhostent.c,v 1.2 1999/12/02 16:58:45 joda Exp $");
+#endif
+
+#include "roken.h"
+
+/*
+ * return a malloced copy of `h'
+ */
+
+struct hostent *
+copyhostent (const struct hostent *h)
+{
+ struct hostent *res;
+ char **p;
+ int i, n;
+
+ res = malloc (sizeof (*res));
+ if (res == NULL)
+ return NULL;
+ res->h_name = NULL;
+ res->h_aliases = NULL;
+ res->h_addrtype = h->h_addrtype;
+ res->h_length = h->h_length;
+ res->h_addr_list = NULL;
+ res->h_name = strdup (h->h_name);
+ if (res->h_name == NULL) {
+ freehostent (res);
+ return NULL;
+ }
+ for (n = 0, p = h->h_aliases; *p != NULL; ++p)
+ ++n;
+ res->h_aliases = malloc ((n + 1) * sizeof(*res->h_aliases));
+ if (res->h_aliases == NULL) {
+ freehostent (res);
+ return NULL;
+ }
+ for (i = 0; i < n + 1; ++i)
+ res->h_aliases[i] = NULL;
+ for (i = 0; i < n; ++i) {
+ res->h_aliases[i] = strdup (h->h_aliases[i]);
+ if (res->h_aliases[i] == NULL) {
+ freehostent (res);
+ return NULL;
+ }
+ }
+
+ for (n = 0, p = h->h_addr_list; *p != NULL; ++p)
+ ++n;
+ res->h_addr_list = malloc ((n + 1) * sizeof(*res->h_addr_list));
+ if (res->h_addr_list == NULL) {
+ freehostent (res);
+ return NULL;
+ }
+ for (i = 0; i < n + 1; ++i) {
+ res->h_addr_list[i] = NULL;
+ }
+ for (i = 0; i < n; ++i) {
+ res->h_addr_list[i] = malloc (h->h_length);
+ if (res->h_addr_list[i] == NULL) {
+ freehostent (res);
+ return NULL;
+ }
+ memcpy (res->h_addr_list[i], h->h_addr_list[i], h->h_length);
+ }
+ return res;
+}
+
diff --git a/crypto/heimdal/lib/roken/daemon.c b/crypto/heimdal/lib/roken/daemon.c
new file mode 100644
index 000000000000..758856c8ada8
--- /dev/null
+++ b/crypto/heimdal/lib/roken/daemon.c
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+RCSID("$Id: daemon.c,v 1.3 1997/10/04 21:55:48 joda Exp $");
+
+#ifndef HAVE_DAEMON
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "roken.h"
+
+int
+daemon(int nochdir, int noclose)
+{
+ int fd;
+
+ switch (fork()) {
+ case -1:
+ return (-1);
+ case 0:
+ break;
+ default:
+ _exit(0);
+ }
+
+ if (setsid() == -1)
+ return (-1);
+
+ if (!nochdir)
+ chdir("/");
+
+ if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ if (fd > 2)
+ close (fd);
+ }
+ return (0);
+}
+
+#endif /* HAVE_DAEMON */
diff --git a/crypto/heimdal/lib/roken/emalloc.c b/crypto/heimdal/lib/roken/emalloc.c
new file mode 100644
index 000000000000..bbea1e0b5f0b
--- /dev/null
+++ b/crypto/heimdal/lib/roken/emalloc.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: emalloc.c,v 1.4 1999/12/02 16:58:45 joda Exp $");
+#endif
+
+#include <stdlib.h>
+#include <err.h>
+
+#include <roken.h>
+
+/*
+ * Like malloc but never fails.
+ */
+
+void *
+emalloc (size_t sz)
+{
+ void *tmp = malloc (sz);
+
+ if (tmp == NULL && sz != 0)
+ err (1, "malloc %lu", (unsigned long)sz);
+ return tmp;
+}
diff --git a/crypto/heimdal/lib/roken/eread.c b/crypto/heimdal/lib/roken/eread.c
new file mode 100644
index 000000000000..9a1b24bd55df
--- /dev/null
+++ b/crypto/heimdal/lib/roken/eread.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: eread.c,v 1.2 1999/12/02 16:58:45 joda Exp $");
+#endif
+
+#include <unistd.h>
+#include <err.h>
+
+#include <roken.h>
+
+/*
+ * Like read but never fails (and never returns partial data).
+ */
+
+ssize_t
+eread (int fd, void *buf, size_t nbytes)
+{
+ ssize_t ret;
+
+ ret = net_read (fd, buf, nbytes);
+ if (ret < 0)
+ err (1, "read");
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/erealloc.c b/crypto/heimdal/lib/roken/erealloc.c
new file mode 100644
index 000000000000..8afa8f3d7b61
--- /dev/null
+++ b/crypto/heimdal/lib/roken/erealloc.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: erealloc.c,v 1.4 1999/12/02 16:58:45 joda Exp $");
+#endif
+
+#include <stdlib.h>
+#include <err.h>
+
+#include <roken.h>
+
+/*
+ * Like realloc but never fails.
+ */
+
+void *
+erealloc (void *ptr, size_t sz)
+{
+ void *tmp = realloc (ptr, sz);
+
+ if (tmp == NULL && sz != 0)
+ err (1, "realloc %lu", (unsigned long)sz);
+ return tmp;
+}
diff --git a/crypto/heimdal/lib/roken/err.c b/crypto/heimdal/lib/roken/err.c
new file mode 100644
index 000000000000..29b1f7b5672d
--- /dev/null
+++ b/crypto/heimdal/lib/roken/err.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: err.c,v 1.6 1999/12/02 16:58:45 joda Exp $");
+#endif
+
+#include "err.h"
+
+void
+err(int eval, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verr(eval, fmt, ap);
+ va_end(ap);
+}
diff --git a/crypto/heimdal/lib/roken/err.h b/crypto/heimdal/lib/roken/err.h
new file mode 100644
index 000000000000..b0b649f92b46
--- /dev/null
+++ b/crypto/heimdal/lib/roken/err.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: err.h,v 1.15 1999/12/02 16:58:45 joda Exp $ */
+
+#ifndef __ERR_H__
+#define __ERR_H__
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+extern const char *__progname;
+
+#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(x)
+#endif
+
+void warnerr(int doerrno, const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 2, 0)));
+
+void verr(int eval, const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 2, 0)));
+void err(int eval, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 2, 3)));
+void verrx(int eval, const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 2, 0)));
+void errx(int eval, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 2, 3)));
+void vwarn(const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 1, 0)));
+void warn(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+void vwarnx(const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 1, 0)));
+void warnx(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+#endif /* __ERR_H__ */
diff --git a/crypto/heimdal/lib/roken/errx.c b/crypto/heimdal/lib/roken/errx.c
new file mode 100644
index 000000000000..2f8ec18dd24e
--- /dev/null
+++ b/crypto/heimdal/lib/roken/errx.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: errx.c,v 1.6 1999/12/02 16:58:45 joda Exp $");
+#endif
+
+#include "err.h"
+
+void
+errx(int eval, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verrx(eval, fmt, ap);
+ va_end(ap);
+}
diff --git a/crypto/heimdal/lib/roken/estrdup.c b/crypto/heimdal/lib/roken/estrdup.c
new file mode 100644
index 000000000000..8c0d9a748cb3
--- /dev/null
+++ b/crypto/heimdal/lib/roken/estrdup.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: estrdup.c,v 1.2 1999/12/02 16:58:45 joda Exp $");
+#endif
+
+#include <stdlib.h>
+#include <err.h>
+
+#include <roken.h>
+
+/*
+ * Like strdup but never fails.
+ */
+
+char *
+estrdup (const char *str)
+{
+ char *tmp = strdup (str);
+
+ if (tmp == NULL)
+ err (1, "strdup");
+ return tmp;
+}
diff --git a/crypto/heimdal/lib/roken/ewrite.c b/crypto/heimdal/lib/roken/ewrite.c
new file mode 100644
index 000000000000..b2c43de8dbc9
--- /dev/null
+++ b/crypto/heimdal/lib/roken/ewrite.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: ewrite.c,v 1.2 1999/12/02 16:58:45 joda Exp $");
+#endif
+
+#include <unistd.h>
+#include <err.h>
+
+#include <roken.h>
+
+/*
+ * Like write but never fails (and never returns partial data).
+ */
+
+ssize_t
+ewrite (int fd, const void *buf, size_t nbytes)
+{
+ ssize_t ret;
+
+ ret = net_write (fd, buf, nbytes);
+ if (ret < 0)
+ err (1, "write");
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/fchown.c b/crypto/heimdal/lib/roken/fchown.c
new file mode 100644
index 000000000000..61e854691e83
--- /dev/null
+++ b/crypto/heimdal/lib/roken/fchown.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: fchown.c,v 1.3 1999/12/02 16:58:46 joda Exp $");
+#endif
+
+#include "roken.h"
+
+int
+fchown(int fd, uid_t owner, gid_t group)
+{
+ return 0;
+}
diff --git a/crypto/heimdal/lib/roken/flock.c b/crypto/heimdal/lib/roken/flock.c
new file mode 100644
index 000000000000..13da4f474bef
--- /dev/null
+++ b/crypto/heimdal/lib/roken/flock.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_FLOCK
+RCSID("$Id: flock.c,v 1.4 1999/12/02 16:58:46 joda Exp $");
+
+#include "roken.h"
+
+
+#define OP_MASK (LOCK_SH | LOCK_EX | LOCK_UN)
+
+int
+flock(int fd, int operation)
+{
+#if defined(HAVE_FCNTL) && defined(F_SETLK)
+ struct flock arg;
+ int code, cmd;
+
+ arg.l_whence = SEEK_SET;
+ arg.l_start = 0;
+ arg.l_len = 0; /* means to EOF */
+
+ if (operation & LOCK_NB)
+ cmd = F_SETLK;
+ else
+ cmd = F_SETLKW; /* Blocking */
+
+ switch (operation & OP_MASK) {
+ case LOCK_UN:
+ arg.l_type = F_UNLCK;
+ code = fcntl(fd, F_SETLK, &arg);
+ break;
+ case LOCK_SH:
+ arg.l_type = F_RDLCK;
+ code = fcntl(fd, cmd, &arg);
+ break;
+ case LOCK_EX:
+ arg.l_type = F_WRLCK;
+ code = fcntl(fd, cmd, &arg);
+ break;
+ default:
+ errno = EINVAL;
+ code = -1;
+ break;
+ }
+ return code;
+#else
+ return -1;
+#endif
+}
+
+#endif
+
diff --git a/crypto/heimdal/lib/roken/fnmatch.c b/crypto/heimdal/lib/roken/fnmatch.c
new file mode 100644
index 000000000000..dc01d6ea61ba
--- /dev/null
+++ b/crypto/heimdal/lib/roken/fnmatch.c
@@ -0,0 +1,173 @@
+/* $NetBSD: fnmatch.c,v 1.11 1995/02/27 03:43:06 cgd Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
+#else
+static char rcsid[] = "$NetBSD: fnmatch.c,v 1.11 1995/02/27 03:43:06 cgd Exp $";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ * Compares a filename or pathname to a pattern.
+ */
+
+#include <fnmatch.h>
+#include <string.h>
+
+#define EOS '\0'
+
+static const char *rangematch (const char *, int, int);
+
+int
+fnmatch(const char *pattern, const char *string, int flags)
+{
+ const char *stringstart;
+ char c, test;
+
+ for (stringstart = string;;)
+ switch (c = *pattern++) {
+ case EOS:
+ return (*string == EOS ? 0 : FNM_NOMATCH);
+ case '?':
+ if (*string == EOS)
+ return (FNM_NOMATCH);
+ if (*string == '/' && (flags & FNM_PATHNAME))
+ return (FNM_NOMATCH);
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+ ++string;
+ break;
+ case '*':
+ c = *pattern;
+ /* Collapse multiple stars. */
+ while (c == '*')
+ c = *++pattern;
+
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+
+ /* Optimize for pattern with * at end or before /. */
+ if (c == EOS)
+ if (flags & FNM_PATHNAME)
+ return (strchr(string, '/') == NULL ?
+ 0 : FNM_NOMATCH);
+ else
+ return (0);
+ else if (c == '/' && flags & FNM_PATHNAME) {
+ if ((string = strchr(string, '/')) == NULL)
+ return (FNM_NOMATCH);
+ break;
+ }
+
+ /* General case, use recursion. */
+ while ((test = *string) != EOS) {
+ if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
+ return (0);
+ if (test == '/' && flags & FNM_PATHNAME)
+ break;
+ ++string;
+ }
+ return (FNM_NOMATCH);
+ case '[':
+ if (*string == EOS)
+ return (FNM_NOMATCH);
+ if (*string == '/' && flags & FNM_PATHNAME)
+ return (FNM_NOMATCH);
+ if ((pattern =
+ rangematch(pattern, *string, flags)) == NULL)
+ return (FNM_NOMATCH);
+ ++string;
+ break;
+ case '\\':
+ if (!(flags & FNM_NOESCAPE)) {
+ if ((c = *pattern++) == EOS) {
+ c = '\\';
+ --pattern;
+ }
+ }
+ /* FALLTHROUGH */
+ default:
+ if (c != *string++)
+ return (FNM_NOMATCH);
+ break;
+ }
+ /* NOTREACHED */
+}
+
+static const char *
+rangematch(const char *pattern, int test, int flags)
+{
+ int negate, ok;
+ char c, c2;
+
+ /*
+ * A bracket expression starting with an unquoted circumflex
+ * character produces unspecified results (IEEE 1003.2-1992,
+ * 3.13.2). This implementation treats it like '!', for
+ * consistency with the regular expression syntax.
+ * J.T. Conklin (conklin@ngai.kaleida.com)
+ */
+ if (negate = (*pattern == '!' || *pattern == '^'))
+ ++pattern;
+
+ for (ok = 0; (c = *pattern++) != ']';) {
+ if (c == '\\' && !(flags & FNM_NOESCAPE))
+ c = *pattern++;
+ if (c == EOS)
+ return (NULL);
+ if (*pattern == '-'
+ && (c2 = *(pattern+1)) != EOS && c2 != ']') {
+ pattern += 2;
+ if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+ c2 = *pattern++;
+ if (c2 == EOS)
+ return (NULL);
+ if (c <= test && test <= c2)
+ ok = 1;
+ } else if (c == test)
+ ok = 1;
+ }
+ return (ok == negate ? NULL : pattern);
+}
diff --git a/crypto/heimdal/lib/roken/fnmatch.h b/crypto/heimdal/lib/roken/fnmatch.h
new file mode 100644
index 000000000000..95c91d600b64
--- /dev/null
+++ b/crypto/heimdal/lib/roken/fnmatch.h
@@ -0,0 +1,49 @@
+/* $NetBSD: fnmatch.h,v 1.5 1994/10/26 00:55:53 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _FNMATCH_H_
+#define _FNMATCH_H_
+
+#define FNM_NOMATCH 1 /* Match failed. */
+
+#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
+#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
+#define FNM_PERIOD 0x04 /* Period must be matched by period. */
+
+int fnmatch (const char *, const char *, int);
+
+#endif /* !_FNMATCH_H_ */
diff --git a/crypto/heimdal/lib/roken/freeaddrinfo.c b/crypto/heimdal/lib/roken/freeaddrinfo.c
new file mode 100644
index 000000000000..f963d15620e3
--- /dev/null
+++ b/crypto/heimdal/lib/roken/freeaddrinfo.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: freeaddrinfo.c,v 1.2 1999/12/03 04:10:06 assar Exp $");
+#endif
+
+#include "roken.h"
+
+/*
+ * free the list of `struct addrinfo' starting at `ai'
+ */
+
+void
+freeaddrinfo(struct addrinfo *ai)
+{
+ for (; ai != NULL; ai = ai->ai_next) {
+ free (ai->ai_canonname);
+ free (ai->ai_addr);
+ }
+}
diff --git a/crypto/heimdal/lib/roken/freehostent.c b/crypto/heimdal/lib/roken/freehostent.c
new file mode 100644
index 000000000000..0cd92cd732cd
--- /dev/null
+++ b/crypto/heimdal/lib/roken/freehostent.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: freehostent.c,v 1.2 1999/12/02 16:58:46 joda Exp $");
+#endif
+
+#include "roken.h"
+
+/*
+ * free a malloced hostent
+ */
+
+void
+freehostent (struct hostent *h)
+{
+ char **p;
+
+ free (h->h_name);
+ if (h->h_aliases != NULL) {
+ for (p = h->h_aliases; *p != NULL; ++p)
+ free (*p);
+ free (h->h_aliases);
+ }
+ if (h->h_addr_list != NULL) {
+ for (p = h->h_addr_list; *p != NULL; ++p)
+ free (*p);
+ free (h->h_addr_list);
+ }
+ free (h);
+}
diff --git a/crypto/heimdal/lib/roken/gai_strerror.c b/crypto/heimdal/lib/roken/gai_strerror.c
new file mode 100644
index 000000000000..07f7c395e7a9
--- /dev/null
+++ b/crypto/heimdal/lib/roken/gai_strerror.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: gai_strerror.c,v 1.2 1999/12/03 04:10:06 assar Exp $");
+#endif
+
+#include "roken.h"
+
+static struct gai_error {
+ int code;
+ char *str;
+} errors[] = {
+{EAI_NOERROR, "no error"},
+{EAI_ADDRFAMILY, "address family for nodename not supported"},
+{EAI_AGAIN, "temporary failure in name resolution"},
+{EAI_BADFLAGS, "invalid value for ai_flags"},
+{EAI_FAIL, "non-recoverable failure in name resolution"},
+{EAI_FAMILY, "ai_family not supported"},
+{EAI_MEMORY, "memory allocation failure"},
+{EAI_NODATA, "no address associated with nodename"},
+{EAI_NONAME, "nodename nor servname provided, or not known"},
+{EAI_SERVICE, "servname not supported for ai_socktype"},
+{EAI_SOCKTYPE, "ai_socktype not supported"},
+{EAI_SYSTEM, "system error returned in errno"},
+{0, NULL},
+};
+
+/*
+ *
+ */
+
+char *
+gai_strerror(int ecode)
+{
+ struct gai_error *g;
+
+ for (g = errors; g->str != NULL; ++g)
+ if (g->code == ecode)
+ return g->str;
+ return "unknown error code in gai_strerror";
+}
diff --git a/crypto/heimdal/lib/roken/get_default_username.c b/crypto/heimdal/lib/roken/get_default_username.c
new file mode 100644
index 000000000000..10b0863888d3
--- /dev/null
+++ b/crypto/heimdal/lib/roken/get_default_username.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: get_default_username.c,v 1.3 1999/12/02 16:58:46 joda Exp $");
+#endif /* HAVE_CONFIG_H */
+
+#include "roken.h"
+
+/*
+ * Try to return what should be considered the default username or
+ * NULL if we can't guess at all.
+ */
+
+const char *
+get_default_username (void)
+{
+ const char *user;
+
+ user = getenv ("USER");
+ if (user == NULL)
+ user = getenv ("LOGNAME");
+ if (user == NULL)
+ user = getenv ("USERNAME");
+
+#if defined(HAVE_GETLOGIN) && !defined(POSIX_GETLOGIN)
+ if (user == NULL) {
+ user = (const char *)getlogin ();
+ if (user != NULL)
+ return user;
+ }
+#endif
+#ifdef HAVE_PWD_H
+ {
+ uid_t uid = getuid ();
+ struct passwd *pwd;
+
+ if (user != NULL) {
+ pwd = k_getpwnam (user);
+ if (pwd != NULL && pwd->pw_uid == uid)
+ return user;
+ }
+ pwd = k_getpwuid (uid);
+ if (pwd != NULL)
+ return pwd->pw_name;
+ }
+#endif
+ return user;
+}
diff --git a/crypto/heimdal/lib/roken/get_window_size.c b/crypto/heimdal/lib/roken/get_window_size.c
new file mode 100644
index 000000000000..4eff8d2d2c6e
--- /dev/null
+++ b/crypto/heimdal/lib/roken/get_window_size.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: get_window_size.c,v 1.9 1999/12/02 16:58:46 joda Exp $");
+#endif
+
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if 0 /* Where were those needed? /confused */
+#ifdef HAVE_SYS_PROC_H
+#include <sys/proc.h>
+#endif
+
+#ifdef HAVE_SYS_TTY_H
+#include <sys/tty.h>
+#endif
+#endif
+
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
+#include <roken.h>
+
+int
+get_window_size(int fd, struct winsize *wp)
+{
+ int ret = -1;
+
+ memset(wp, 0, sizeof(*wp));
+
+#if defined(TIOCGWINSZ)
+ ret = ioctl(fd, TIOCGWINSZ, wp);
+#elif defined(TIOCGSIZE)
+ {
+ struct ttysize ts;
+
+ ret = ioctl(fd, TIOCGSIZE, &ts);
+ if(ret == 0) {
+ wp->ws_row = ts.ts_lines;
+ wp->ws_col = ts.ts_cols;
+ }
+ }
+#elif defined(HAVE__SCRSIZE)
+ {
+ int dst[2];
+
+ _scrsize(dst);
+ wp->ws_row = dst[1];
+ wp->ws_col = dst[0];
+ ret = 0;
+ }
+#endif
+ if (ret != 0) {
+ char *s;
+ if((s = getenv("COLUMNS")))
+ wp->ws_col = atoi(s);
+ if((s = getenv("LINES")))
+ wp->ws_row = atoi(s);
+ if(wp->ws_col > 0 && wp->ws_row > 0)
+ ret = 0;
+ }
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/getaddrinfo-test.c b/crypto/heimdal/lib/roken/getaddrinfo-test.c
new file mode 100644
index 000000000000..ede9c956894f
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getaddrinfo-test.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getaddrinfo-test.c,v 1.2 1999/12/03 04:10:07 assar Exp $");
+#endif
+
+#include "roken.h"
+#include "getarg.h"
+
+static int flags;
+static int family;
+static int socktype;
+
+static int version_flag;
+static int help_flag;
+
+static struct getargs args[] = {
+ {"flags", 0, arg_integer, &flags, "flags", NULL},
+ {"family", 0, arg_integer, &family, "family", NULL},
+ {"socktype",0, arg_integer, &socktype, "socktype", NULL},
+ {"version", 0, arg_flag, &version_flag, "print version",NULL},
+ {"help", 0, arg_flag, &help_flag, NULL, NULL}
+};
+
+static void
+usage(int ret)
+{
+ arg_printusage (args,
+ sizeof(args) / sizeof(args[0]),
+ NULL,
+ "[nodename servname...]");
+ exit (ret);
+}
+
+static void
+doit (const char *nodename, const char *servname)
+{
+ struct addrinfo hints;
+ struct addrinfo *res, *r;
+ int ret;
+
+ printf ("(%s,%s)... ", nodename ? nodename : "null", servname);
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_flags = flags;
+ hints.ai_family = family;
+ hints.ai_socktype = socktype;
+
+ ret = getaddrinfo (nodename, servname, &hints, &res);
+ if (ret) {
+ printf ("error: %s\n", gai_strerror(ret));
+ return;
+ }
+ printf ("\n");
+
+ for (r = res; r != NULL; r = r->ai_next) {
+ char addrstr[256];
+
+ if (inet_ntop (r->ai_family,
+ socket_get_address (r->ai_addr),
+ addrstr, sizeof(addrstr)) == NULL) {
+ printf ("\tbad address?\n");
+ continue;
+ }
+ printf ("\t(family = %d, socktype = %d, protocol = %d, "
+ "address = \"%s\", port = %d",
+ r->ai_family, r->ai_socktype, r->ai_protocol,
+ addrstr,
+ ntohs(socket_get_port (r->ai_addr)));
+ if (r->ai_canonname)
+ printf (", canonname = \"%s\"", r->ai_canonname);
+ printf ("\n");
+ }
+ freeaddrinfo (res);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+ int i;
+
+ set_progname (argv[0]);
+
+ if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
+ &optind))
+ usage (1);
+
+ if (help_flag)
+ usage (0);
+
+ if (version_flag) {
+ print_version (NULL);
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc % 2 != 0)
+ usage (1);
+
+ for (i = 0; i < argc; i += 2) {
+ const char *nodename = argv[i];
+
+ if (strcmp (nodename, "null") == 0)
+ nodename = NULL;
+
+ doit (nodename, argv[i+1]);
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/roken/getaddrinfo.c b/crypto/heimdal/lib/roken/getaddrinfo.c
new file mode 100644
index 000000000000..db18742d20d1
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getaddrinfo.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getaddrinfo.c,v 1.6 1999/12/20 00:56:44 assar Exp $");
+#endif
+
+#include "roken.h"
+
+/*
+ * uses hints->ai_socktype and hints->ai_protocol
+ */
+
+static int
+get_port_protocol_socktype (const char *servname,
+ const struct addrinfo *hints,
+ int *port,
+ int *protocol,
+ int *socktype)
+{
+ struct servent *se;
+ const char *proto_str = NULL;
+
+ *socktype = 0;
+
+ if (hints != NULL && hints->ai_protocol != 0) {
+ struct protoent *protoent = getprotobynumber (hints->ai_protocol);
+
+ if (protoent == NULL)
+ return EAI_SOCKTYPE; /* XXX */
+
+ proto_str = protoent->p_name;
+ *protocol = protoent->p_proto;
+ }
+
+ if (hints != NULL)
+ *socktype = hints->ai_socktype;
+
+ if (*socktype == SOCK_STREAM) {
+ se = getservbyname (servname, proto_str ? proto_str : "tcp");
+ if (proto_str == NULL)
+ *protocol = IPPROTO_TCP;
+ } else if (*socktype == SOCK_DGRAM) {
+ se = getservbyname (servname, proto_str ? proto_str : "udp");
+ if (proto_str == NULL)
+ *protocol = IPPROTO_UDP;
+ } else if (*socktype == 0) {
+ if (proto_str != NULL) {
+ se = getservbyname (servname, proto_str);
+ } else {
+ se = getservbyname (servname, "tcp");
+ *protocol = IPPROTO_TCP;
+ *socktype = SOCK_STREAM;
+ if (se == NULL) {
+ se = getservbyname (servname, "udp");
+ *protocol = IPPROTO_UDP;
+ *socktype = SOCK_DGRAM;
+ }
+ }
+ } else
+ return EAI_SOCKTYPE;
+
+ if (se == NULL) {
+ char *endstr;
+
+ *port = htons(strtol (servname, &endstr, 10));
+ if (servname == endstr)
+ return EAI_NONAME;
+ } else {
+ *port = se->s_port;
+ }
+ return 0;
+}
+
+static int
+add_one (int port, int protocol, int socktype,
+ struct addrinfo ***ptr,
+ int (*func)(struct addrinfo *, void *data, int port),
+ void *data,
+ char *canonname)
+{
+ struct addrinfo *a;
+ int ret;
+
+ a = malloc (sizeof (*a));
+ if (a == NULL)
+ return EAI_MEMORY;
+ memset (a, 0, sizeof(*a));
+ a->ai_flags = 0;
+ a->ai_next = NULL;
+ a->ai_protocol = protocol;
+ a->ai_socktype = socktype;
+ a->ai_canonname = canonname;
+ ret = (*func)(a, data, port);
+ if (ret) {
+ free (a);
+ return ret;
+ }
+ **ptr = a;
+ *ptr = &a->ai_next;
+ return 0;
+}
+
+static int
+const_v4 (struct addrinfo *a, void *data, int port)
+{
+ struct sockaddr_in *sin;
+ struct in_addr *addr = (struct in_addr *)data;
+
+ a->ai_family = PF_INET;
+ a->ai_addrlen = sizeof(*sin);
+ a->ai_addr = malloc (sizeof(*sin));
+ if (a->ai_addr == NULL)
+ return EAI_MEMORY;
+ sin = (struct sockaddr_in *)a->ai_addr;
+ memset (sin, 0, sizeof(*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ sin->sin_addr = *addr;
+ return 0;
+}
+
+#ifdef HAVE_IPV6
+static int
+const_v6 (struct addrinfo *a, void *data, int port)
+{
+ struct sockaddr_in6 *sin6;
+ struct in6_addr *addr = (struct in6_addr *)data;
+
+ a->ai_family = PF_INET6;
+ a->ai_addrlen = sizeof(*sin6);
+ a->ai_addr = malloc (sizeof(*sin6));
+ if (a->ai_addr == NULL)
+ return EAI_MEMORY;
+ sin6 = (struct sockaddr_in6 *)a->ai_addr;
+ memset (sin6, 0, sizeof(*sin6));
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = port;
+ sin6->sin6_addr = *addr;
+ return 0;
+}
+#endif
+
+static int
+get_null (const struct addrinfo *hints,
+ int port, int protocol, int socktype,
+ struct addrinfo **res)
+{
+ struct in_addr v4_addr;
+#ifdef HAVE_IPV6
+ struct in6_addr v6_addr;
+#endif
+ struct addrinfo *first = NULL;
+ struct addrinfo **current = &first;
+ int family = PF_UNSPEC;
+ int ret;
+
+ if (hints != NULL)
+ family = hints->ai_family;
+
+ if (hints && hints->ai_flags & AI_PASSIVE) {
+ v4_addr.s_addr = INADDR_ANY;
+#ifdef HAVE_IPV6
+ v6_addr = in6addr_any;
+#endif
+ } else {
+ v4_addr.s_addr = htonl(INADDR_LOOPBACK);
+#ifdef HAVE_IPV6
+ v6_addr = in6addr_loopback;
+#endif
+ }
+
+#ifdef HAVE_IPV6
+ if (family == PF_INET6 || family == PF_UNSPEC) {
+ ret = add_one (port, protocol, socktype,
+ &current, const_v6, &v6_addr, NULL);
+ }
+#endif
+ if (family == PF_INET || family == PF_UNSPEC) {
+ ret = add_one (port, protocol, socktype,
+ &current, const_v4, &v4_addr, NULL);
+ }
+ *res = first;
+ return 0;
+}
+
+static int
+add_hostent (int port, int protocol, int socktype,
+ struct addrinfo ***current,
+ int (*func)(struct addrinfo *, void *data, int port),
+ struct hostent *he, int *flags)
+{
+ char **h;
+ int ret;
+ char *canonname = NULL;
+
+ if (*flags & AI_CANONNAME) {
+ canonname = he->h_name;
+
+ if (strchr (he->h_name, '.') == NULL)
+ for (h = he->h_aliases; *h; ++h) {
+ if (strchr (*h, '.') != NULL) {
+ canonname = *h;
+ break;
+ }
+ }
+ canonname = strdup (canonname);
+ if (canonname == NULL)
+ return EAI_MEMORY;
+ }
+
+ for (h = he->h_addr_list; *h != NULL; ++h) {
+ ret = add_one (port, protocol, socktype,
+ current, func, *h, canonname);
+ if (ret)
+ return ret;
+ if (*flags & AI_CANONNAME) {
+ *flags &= ~AI_CANONNAME;
+ canonname = NULL;
+ }
+ }
+ return 0;
+}
+
+static int
+get_number (const char *nodename,
+ const struct addrinfo *hints,
+ int port, int protocol, int socktype,
+ struct addrinfo **res)
+{
+ struct addrinfo *first = NULL;
+ struct addrinfo **current = &first;
+ int family = PF_UNSPEC;
+ int ret;
+
+ if (hints != NULL) {
+ family = hints->ai_family;
+ }
+
+#ifdef HAVE_IPV6
+ if (family == PF_INET6 || family == PF_UNSPEC) {
+ struct in6_addr v6_addr;
+
+ if (inet_pton (PF_INET6, nodename, &v6_addr) == 1) {
+ ret = add_one (port, protocol, socktype,
+ &current, const_v6, &v6_addr, NULL);
+ *res = first;
+ return ret;
+ }
+ }
+#endif
+ if (family == PF_INET || family == PF_UNSPEC) {
+ struct in_addr v4_addr;
+
+ if (inet_pton (PF_INET, nodename, &v4_addr) == 1) {
+ ret = add_one (port, protocol, socktype,
+ &current, const_v4, &v4_addr, NULL);
+ *res = first;
+ return ret;
+ }
+ }
+ return EAI_NONAME;
+}
+
+static int
+get_nodes (const char *nodename,
+ const struct addrinfo *hints,
+ int port, int protocol, int socktype,
+ struct addrinfo **res)
+{
+ struct addrinfo *first = NULL;
+ struct addrinfo **current = &first;
+ int family = PF_UNSPEC;
+ int flags = 0;
+ int ret = EAI_NONAME;
+ int error;
+
+ if (hints != NULL) {
+ family = hints->ai_family;
+ flags = hints->ai_flags;
+ }
+
+#ifdef HAVE_IPV6
+ if (family == PF_INET6 || family == PF_UNSPEC) {
+ struct hostent *he;
+
+ he = getipnodebyname (nodename, PF_INET6, 0, &error);
+
+ if (he != NULL) {
+ ret = add_hostent (port, protocol, socktype,
+ &current, const_v6, he, &flags);
+ freehostent (he);
+ }
+ }
+#endif
+ if (family == PF_INET || family == PF_UNSPEC) {
+ struct hostent *he;
+
+ he = getipnodebyname (nodename, PF_INET, 0, &error);
+
+ if (he != NULL) {
+ ret = add_hostent (port, protocol, socktype,
+ &current, const_v4, he, &flags);
+ freehostent (he);
+ }
+ }
+ *res = first;
+ return ret;
+}
+
+/*
+ * hints:
+ *
+ * struct addrinfo {
+ * int ai_flags;
+ * int ai_family;
+ * int ai_socktype;
+ * int ai_protocol;
+ * ...
+ * };
+ */
+
+int
+getaddrinfo(const char *nodename,
+ const char *servname,
+ const struct addrinfo *hints,
+ struct addrinfo **res)
+{
+ int ret;
+ int port = 0;
+ int protocol = 0;
+ int socktype = 0;
+
+ *res = NULL;
+
+ if (servname == NULL && nodename == NULL)
+ return EAI_NONAME;
+
+ if (hints != NULL
+ && hints->ai_family != PF_UNSPEC
+ && hints->ai_family != PF_INET
+#ifdef HAVE_IPV6
+ && hints->ai_family != PF_INET6
+#endif
+ )
+ return EAI_FAMILY;
+
+ if (servname != NULL) {
+ ret = get_port_protocol_socktype (servname, hints,
+ &port, &protocol, &socktype);
+ if (ret)
+ return ret;
+ }
+ if (nodename != NULL) {
+ ret = get_number (nodename, hints, port, protocol, socktype, res);
+ if (ret) {
+ if(hints && hints->ai_flags & AI_NUMERICHOST)
+ ret = EAI_NONAME;
+ else
+ ret = get_nodes (nodename, hints, port, protocol, socktype,
+ res);
+ }
+ } else {
+ ret = get_null (hints, port, protocol, socktype, res);
+ }
+ if (ret)
+ freeaddrinfo (*res);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/getarg.3 b/crypto/heimdal/lib/roken/getarg.3
new file mode 100644
index 000000000000..78a88028caf4
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getarg.3
@@ -0,0 +1,317 @@
+.\" Copyright (c) 1999 Kungliga Tekniska Högskolan
+.\" $Id: getarg.3,v 1.2 1999/10/18 17:14:31 joda Exp $
+.Dd September 24, 1999
+.Dt GETARG 3
+.Os ROKEN
+.Sh NAME
+.Nm getarg ,
+.Nm arg_printusage
+.Nd collect command line options
+.Sh SYNOPSIS
+.Fd #include <getarg.h>
+
+.Ft int
+.Fn getarg "struct getargs *args" "size_t num_args" "int argc" "char **argv" "int *optind"
+
+.Ft void
+.Fn arg_printusage "struct getargs *args" "size_t num_args" "const char *progname" "const char *extra_string"
+
+.Sh DESCRIPTION
+.Fn getarg
+collects any command line options given to a program in an easily used way.
+.Fn arg_printusage
+pretty-prints the available options, with a short help text.
+.Pp
+.Fa args
+is the option specification to use, and it's an array of
+.Fa struct getargs
+elements.
+.Fa num_args
+is the size of
+.Fa args
+(in elements).
+.Fa argc
+and
+.Fa argv
+are the argument count and argument vector to extract option from.
+.Fa optind
+is a pointer to an integer where the index to the last processed
+argument is stored, it must be initialised to the first index (minus
+one) to process (normally 0) before the first call.
+.Pp
+.Fa arg_printusage
+take the same
+.Fa args
+and
+.Fa num_args
+as getarg;
+.Fa progname is the name of the program (to be used in the help text), and
+.Fa extra_string
+is a string to print after the actual options to indicate more
+arguments. The usefulness of this function is realised only be people
+who has used programs that has help strings that doesn't match what
+the code does.
+.Pp
+The
+.Fa getargs
+struct has the following elements.
+
+.Bd -literal
+struct getargs{
+ const char *long_name;
+ char short_name;
+ enum { arg_integer,
+ arg_string,
+ arg_flag,
+ arg_negative_flag,
+ arg_strings,
+ arg_double,
+ arg_collect
+ } type;
+ void *value;
+ const char *help;
+ const char *arg_help;
+};
+.Ed
+.Pp
+.Fa long_name
+is the long name of the option, it can be
+.Dv NULL ,
+if you don't want a long name.
+.Fa short_name
+is the characted to use as short option, it can be zero. If the option
+has a value the
+.Fa value
+field gets filled in with that value interpreted as specified by the
+.Fa type
+field.
+.Fa help
+is a longer help string for the option as a whole, if it's
+.Dv NULL
+the help text for the option is omitted (but it's still displayed in
+the synopsis).
+.Fa arg_help
+is a description of the argument, if
+.Dv NULL
+a default value will be used, depending on the type of the option:
+.Pp
+.Bl -hang -width arg_negative_flag
+.It arg_integer
+the argument is a signed integer, and
+.Fa value
+should point to an
+.Fa int .
+.It Fa arg_string
+the argument is a string, and
+.Fa value
+should point to a
+.Fa char* .
+.It Fa arg_flag
+the argument is a flag, and
+.Fa value
+should point to a
+.Fa int .
+It gets filled in with either zero or one, depending on how the option
+is given, the normal case beeing one. Note that if the option isn't
+given, the value isn't altered, so it should be initialised to some
+useful default.
+.It Fa arg_negative_flag
+this is the same as
+.Fa arg_flag
+but it reverses the meaning of the flag (a given short option clears
+the flag), and the synopsis of a long option is negated.
+.It Fa arg_strings
+the argument can be given multiple times, and the values are collected
+in an array;
+.Fa value
+should be a pointer to a
+.Fa struct getarg_strings
+structure, which holds a length and a string pointer.
+.It Fa arg_double
+argument is a double precision floating point value, and
+.Fa value
+should point to a
+.Fa double .
+.It Fa arg_collect
+allows more fine-grained control of the option parsing process.
+.Fa value
+should be a pointer to a
+.Fa getarg_collect_info
+structure:
+.Bd -literal
+typedef int (*getarg_collect_func)(int short_opt,
+ int argc,
+ char **argv,
+ int *optind,
+ int *optarg,
+ void *data);
+
+typedef struct getarg_collect_info {
+ getarg_collect_func func;
+ void *data;
+} getarg_collect_info;
+.Ed
+.Pp
+With the
+.Fa func
+member set to a function to call, and
+.Fa data
+to some application specific data. The parameters to the collect function are:
+.Bl -inset
+.It Fa short_flag
+non-zero if this call is via a short option flag, zero otherwise
+.It Fa argc , argv
+the whole argument list
+.It Fa optind
+pointer to the index in argv where the flag is
+.It Fa optarg
+pointer to the index in argv[*optind] where the flag name starts
+.It Fa data
+application specific data
+.El
+.Pp
+You can modify
+.Fa *optind ,
+and
+.Fa *optarg ,
+but to do this correct you (more or less) have to know about the inner
+workings of getarg.
+
+You can skip parts of arguments by increasing
+.Fa *optarg
+(you could
+implement the
+.Fl z Ns Ar 3
+set of flags from
+.Nm gzip
+with this), or whole argument strings by increasing
+.Fa *optind
+(let's say you want a flag
+.Fl c Ar x y z
+to specify a coordinate); if you also have to set
+.Fa *optarg
+to a sane value.
+.Pp
+The collect function should return one of
+.Dv ARG_ERR_NO_MATCH , ARG_ERR_BAD_ARG , ARG_ERR_NO_ARG
+on error, zero otherwise.
+.Pp
+For your convenience there is a function,
+.Fn getarg_optarg ,
+that returns the traditional argument string, and you pass it all
+arguments, sans data, that where given to the collection function.
+.Pp
+Don't use this more this unless you absolutely have to.
+.El
+.Pp
+Option parsing is similar to what
+.Xr getopt
+uses. Short options without arguments can be compressed
+.Pf ( Fl xyz
+is the same as
+.Fl x y z ) ,
+and short
+options with arguments take these as either the rest of the
+argv-string or as the next option
+.Pf ( Fl o Ns Ar foo ,
+or
+.Fl o Ar foo ) .
+.Pp
+Long option names are prefixed with -- (double dash), and the value
+with a = (equal),
+.Fl -foo= Ns Ar bar .
+Long option flags can either be specified as they are
+.Pf ( Fl -help ) ,
+or with an (boolean parsable) option
+.Pf ( Fl -help= Ns Ar yes ,
+.Fl -help= Ns Ar true ,
+or similar), or they can also be negated
+.Pf ( Fl -no-help
+is the same as
+.Fl -help= Ns no ) ,
+and if you're really confused you can do it multiple times
+.Pf ( Fl -no-no-help= Ns Ar false ,
+or even
+.Fl -no-no-help= Ns Ar maybe ) .
+
+.Pp
+.Sh EXAMPLE
+.Bd -literal
+#include <stdio.h>
+#include <string.h>
+#include <getarg.h>
+
+char *source = "Ouagadougou";
+char *destination;
+int weight;
+int include_catalog = 1;
+int help_flag;
+
+struct getargs args[] = {
+ { "source", 's', arg_string, &source,
+ "source of shippment", "city" },
+ { "destination", 'd', arg_string, &destination,
+ "destination of shippment", "city" },
+ { "weight", 'w', arg_integer, &weight,
+ "weight of shippment", "tons" },
+ { "catalog", 'c', arg_negative_flag, &include_catalog,
+ "include product catalog" },
+ { "help", 'h', arg_flag, &help_flag }
+};
+
+int num_args = sizeof(args) / sizeof(args[0]); /* number of elements in args */
+
+const char *progname = "ship++";
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+ if (getarg(args, num_args, argc, argv, &optind)) {
+ arg_printusage(args, num_args, progname, "stuff...");
+ exit (1);
+ }
+ if (help_flag) {
+ arg_printusage(args, num_args, progname, "stuff...");
+ exit (0);
+ }
+ if (destination == NULL) {
+ fprintf(stderr, "%s: must specify destination\n", progname);
+ exit(1);
+ }
+ if (strcmp(source, destination) == 0) {
+ fprintf(stderr, "%s: destination must be different from source\n");
+ exit(1);
+ }
+ /* include more stuff here ... */
+ exit(2);
+}
+.Ed
+.Pp
+The output help output from this program looks like this:
+.Bd -literal
+$ ship++ --help
+Usage: ship++ [--source=city] [-s city] [--destination=city] [-d city]
+ [--weight=tons] [-w tons] [--no-catalog] [-c] [--help] [-h] stuff...
+-s city, --source=city source of shippment
+-d city, --destination=city destination of shippment
+-w tons, --weight=tons weight of shippment
+-c, --no-catalog include product catalog
+.Ed
+
+.Sh BUGS
+It should be more flexible, so it would be possible to use other more
+complicated option syntaxes, such as what
+.Xr ps 1 ,
+and
+.Xr tar 1 ,
+uses, or the AFS model where you can skip the flag names as long as
+the options come in the correct order.
+.Pp
+Options with multiple arguments should be handled better.
+.Pp
+Should be integreated with SL.
+.Pp
+It's very confusing that the struct you pass in is called getargS.
+.Sh SEE ALSO
+.Xr getopt 3
diff --git a/crypto/heimdal/lib/roken/getarg.c b/crypto/heimdal/lib/roken/getarg.c
new file mode 100644
index 000000000000..505e41867ad6
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getarg.c
@@ -0,0 +1,547 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getarg.c,v 1.32 1999/12/02 16:58:46 joda Exp $");
+#endif
+
+#include <stdio.h>
+#include <roken.h>
+#include "getarg.h"
+
+#define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
+
+static size_t
+print_arg (char *string, size_t len, int mdoc, int longp, struct getargs *arg)
+{
+ const char *s;
+
+ *string = '\0';
+
+ if (ISFLAG(*arg) || (!longp && arg->type == arg_counter))
+ return 0;
+
+ if(mdoc){
+ if(longp)
+ strlcat(string, "= Ns", len);
+ strlcat(string, " Ar ", len);
+ }else
+ if (longp)
+ strlcat (string, "=", len);
+ else
+ strlcat (string, " ", len);
+
+ if (arg->arg_help)
+ s = arg->arg_help;
+ else if (arg->type == arg_integer || arg->type == arg_counter)
+ s = "integer";
+ else if (arg->type == arg_string)
+ s = "string";
+ else if (arg->type == arg_double)
+ s = "float";
+ else
+ s = "<undefined>";
+
+ strlcat(string, s, len);
+ return 1 + strlen(s);
+}
+
+static void
+mandoc_template(struct getargs *args,
+ size_t num_args,
+ const char *progname,
+ const char *extra_string)
+{
+ int i;
+ char timestr[64], cmd[64];
+ char buf[128];
+ const char *p;
+ time_t t;
+
+ printf(".\\\" Things to fix:\n");
+ printf(".\\\" * correct section, and operating system\n");
+ printf(".\\\" * remove Op from mandatory flags\n");
+ printf(".\\\" * use better macros for arguments (like .Pa for files)\n");
+ printf(".\\\"\n");
+ t = time(NULL);
+ strftime(timestr, sizeof(timestr), "%B %e, %Y", localtime(&t));
+ printf(".Dd %s\n", timestr);
+ p = strrchr(progname, '/');
+ if(p) p++; else p = progname;
+ strlcpy(cmd, p, sizeof(cmd));
+ strupr(cmd);
+
+ printf(".Dt %s SECTION\n", cmd);
+ printf(".Os OPERATING_SYSTEM\n");
+ printf(".Sh NAME\n");
+ printf(".Nm %s\n", p);
+ printf(".Nd\n");
+ printf("in search of a description\n");
+ printf(".Sh SYNOPSIS\n");
+ printf(".Nm\n");
+ for(i = 0; i < num_args; i++){
+ /* we seem to hit a limit on number of arguments if doing
+ short and long flags with arguments -- split on two lines */
+ if(ISFLAG(args[i]) ||
+ args[i].short_name == 0 || args[i].long_name == NULL) {
+ printf(".Op ");
+
+ if(args[i].short_name) {
+ print_arg(buf, sizeof(buf), 1, 0, args + i);
+ printf("Fl %c%s", args[i].short_name, buf);
+ if(args[i].long_name)
+ printf(" | ");
+ }
+ if(args[i].long_name) {
+ print_arg(buf, sizeof(buf), 1, 1, args + i);
+ printf("Fl -%s%s", args[i].long_name, buf);
+ }
+ printf("\n");
+ } else {
+ print_arg(buf, sizeof(buf), 1, 0, args + i);
+ printf(".Oo Fl %c%s \\*(Ba Xo\n", args[i].short_name, buf);
+ print_arg(buf, sizeof(buf), 1, 1, args + i);
+ printf(".Fl -%s%s Oc\n.Xc\n", args[i].long_name, buf);
+ }
+ /*
+ if(args[i].type == arg_strings)
+ fprintf (stderr, "...");
+ */
+ }
+ if (extra_string && *extra_string)
+ printf (".Ar %s\n", extra_string);
+ printf(".Sh DESCRIPTION\n");
+ printf("Supported options:\n");
+ printf(".Bl -tag -width Ds\n");
+ for(i = 0; i < num_args; i++){
+ printf(".It Xo\n");
+ if(args[i].short_name){
+ printf(".Fl %c", args[i].short_name);
+ print_arg(buf, sizeof(buf), 1, 0, args + i);
+ printf("%s", buf);
+ if(args[i].long_name)
+ printf(" Ns ,");
+ printf("\n");
+ }
+ if(args[i].long_name){
+ printf(".Fl -%s", args[i].long_name);
+ print_arg(buf, sizeof(buf), 1, 1, args + i);
+ printf("%s\n", buf);
+ }
+ printf(".Xc\n");
+ if(args[i].help)
+ printf("%s\n", args[i].help);
+ /*
+ if(args[i].type == arg_strings)
+ fprintf (stderr, "...");
+ */
+ }
+ printf(".El\n");
+ printf(".\\\".Sh ENVIRONMENT\n");
+ printf(".\\\".Sh FILES\n");
+ printf(".\\\".Sh EXAMPLES\n");
+ printf(".\\\".Sh DIAGNOSTICS\n");
+ printf(".\\\".Sh SEE ALSO\n");
+ printf(".\\\".Sh STANDARDS\n");
+ printf(".\\\".Sh HISTORY\n");
+ printf(".\\\".Sh AUTHORS\n");
+ printf(".\\\".Sh BUGS\n");
+}
+
+static int
+check_column(FILE *f, int col, int len, int columns)
+{
+ if(col + len > columns) {
+ fprintf(f, "\n");
+ col = fprintf(f, " ");
+ }
+ return col;
+}
+
+void
+arg_printusage (struct getargs *args,
+ size_t num_args,
+ const char *progname,
+ const char *extra_string)
+{
+ int i;
+ size_t max_len = 0;
+ char buf[128];
+ int col = 0, columns;
+ struct winsize ws;
+
+ if (progname == NULL)
+ progname = __progname;
+
+ if(getenv("GETARGMANDOC")){
+ mandoc_template(args, num_args, progname, extra_string);
+ return;
+ }
+ if(get_window_size(2, &ws) == 0)
+ columns = ws.ws_col;
+ else
+ columns = 80;
+ col = 0;
+ col += fprintf (stderr, "Usage: %s", progname);
+ for (i = 0; i < num_args; ++i) {
+ size_t len = 0;
+
+ if (args[i].long_name) {
+ buf[0] = '\0';
+ strlcat(buf, "[--", sizeof(buf));
+ len += 2;
+ if(args[i].type == arg_negative_flag) {
+ strlcat(buf, "no-", sizeof(buf));
+ len += 3;
+ }
+ strlcat(buf, args[i].long_name, sizeof(buf));
+ len += strlen(args[i].long_name);
+ len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ 0, 1, &args[i]);
+ strlcat(buf, "]", sizeof(buf));
+ if(args[i].type == arg_strings)
+ strlcat(buf, "...", sizeof(buf));
+ col = check_column(stderr, col, strlen(buf) + 1, columns);
+ col += fprintf(stderr, " %s", buf);
+ }
+ if (args[i].short_name) {
+ snprintf(buf, sizeof(buf), "[-%c", args[i].short_name);
+ len += 2;
+ len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ 0, 0, &args[i]);
+ strlcat(buf, "]", sizeof(buf));
+ if(args[i].type == arg_strings)
+ strlcat(buf, "...", sizeof(buf));
+ col = check_column(stderr, col, strlen(buf) + 1, columns);
+ col += fprintf(stderr, " %s", buf);
+ }
+ if (args[i].long_name && args[i].short_name)
+ len += 2; /* ", " */
+ max_len = max(max_len, len);
+ }
+ if (extra_string) {
+ col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+ fprintf (stderr, " %s\n", extra_string);
+ } else
+ fprintf (stderr, "\n");
+ for (i = 0; i < num_args; ++i) {
+ if (args[i].help) {
+ size_t count = 0;
+
+ if (args[i].short_name) {
+ count += fprintf (stderr, "-%c", args[i].short_name);
+ print_arg (buf, sizeof(buf), 0, 0, &args[i]);
+ count += fprintf(stderr, "%s", buf);
+ }
+ if (args[i].short_name && args[i].long_name)
+ count += fprintf (stderr, ", ");
+ if (args[i].long_name) {
+ count += fprintf (stderr, "--");
+ if (args[i].type == arg_negative_flag)
+ count += fprintf (stderr, "no-");
+ count += fprintf (stderr, "%s", args[i].long_name);
+ print_arg (buf, sizeof(buf), 0, 1, &args[i]);
+ count += fprintf(stderr, "%s", buf);
+ }
+ while(count++ <= max_len)
+ putc (' ', stderr);
+ fprintf (stderr, "%s\n", args[i].help);
+ }
+ }
+}
+
+static void
+add_string(getarg_strings *s, char *value)
+{
+ s->strings = realloc(s->strings, (s->num_strings + 1) * sizeof(*s->strings));
+ s->strings[s->num_strings] = value;
+ s->num_strings++;
+}
+
+static int
+arg_match_long(struct getargs *args, size_t num_args,
+ char *argv, int argc, char **rargv, int *optind)
+{
+ int i;
+ char *optarg = NULL;
+ int negate = 0;
+ int partial_match = 0;
+ struct getargs *partial = NULL;
+ struct getargs *current = NULL;
+ int argv_len;
+ char *p;
+
+ argv_len = strlen(argv);
+ p = strchr (argv, '=');
+ if (p != NULL)
+ argv_len = p - argv;
+
+ for (i = 0; i < num_args; ++i) {
+ if(args[i].long_name) {
+ int len = strlen(args[i].long_name);
+ char *p = argv;
+ int p_len = argv_len;
+ negate = 0;
+
+ for (;;) {
+ if (strncmp (args[i].long_name, p, p_len) == 0) {
+ if(p_len == len)
+ current = &args[i];
+ else {
+ ++partial_match;
+ partial = &args[i];
+ }
+ optarg = p + p_len;
+ } else if (ISFLAG(args[i]) && strncmp (p, "no-", 3) == 0) {
+ negate = !negate;
+ p += 3;
+ p_len -= 3;
+ continue;
+ }
+ break;
+ }
+ if (current)
+ break;
+ }
+ }
+ if (current == NULL) {
+ if (partial_match == 1)
+ current = partial;
+ else
+ return ARG_ERR_NO_MATCH;
+ }
+
+ if(*optarg == '\0'
+ && !ISFLAG(*current)
+ && current->type != arg_collect
+ && current->type != arg_counter)
+ return ARG_ERR_NO_MATCH;
+ switch(current->type){
+ case arg_integer:
+ {
+ int tmp;
+ if(sscanf(optarg + 1, "%d", &tmp) != 1)
+ return ARG_ERR_BAD_ARG;
+ *(int*)current->value = tmp;
+ return 0;
+ }
+ case arg_string:
+ {
+ *(char**)current->value = optarg + 1;
+ return 0;
+ }
+ case arg_strings:
+ {
+ add_string((getarg_strings*)current->value, optarg + 1);
+ return 0;
+ }
+ case arg_flag:
+ case arg_negative_flag:
+ {
+ int *flag = current->value;
+ if(*optarg == '\0' ||
+ strcmp(optarg + 1, "yes") == 0 ||
+ strcmp(optarg + 1, "true") == 0){
+ *flag = !negate;
+ return 0;
+ } else if (*optarg && strcmp(optarg + 1, "maybe") == 0) {
+ *flag = rand() & 1;
+ } else {
+ *flag = negate;
+ return 0;
+ }
+ return ARG_ERR_BAD_ARG;
+ }
+ case arg_counter :
+ {
+ int val;
+
+ if (*optarg == '\0')
+ val = 1;
+ else {
+ char *endstr;
+
+ val = strtol (optarg, &endstr, 0);
+ if (endstr == optarg)
+ return ARG_ERR_BAD_ARG;
+ }
+ *(int *)current->value += val;
+ return 0;
+ }
+ case arg_double:
+ {
+ double tmp;
+ if(sscanf(optarg + 1, "%lf", &tmp) != 1)
+ return ARG_ERR_BAD_ARG;
+ *(double*)current->value = tmp;
+ return 0;
+ }
+ case arg_collect:{
+ struct getarg_collect_info *c = current->value;
+ int o = argv - rargv[*optind];
+ return (*c->func)(FALSE, argc, rargv, optind, &o, c->data);
+ }
+
+ default:
+ abort ();
+ }
+}
+
+static int
+arg_match_short (struct getargs *args, size_t num_args,
+ char *argv, int argc, char **rargv, int *optind)
+{
+ int j, k;
+
+ for(j = 1; j > 0 && j < strlen(rargv[*optind]); j++) {
+ for(k = 0; k < num_args; k++) {
+ char *optarg;
+
+ if(args[k].short_name == 0)
+ continue;
+ if(argv[j] == args[k].short_name) {
+ if(args[k].type == arg_flag) {
+ *(int*)args[k].value = 1;
+ break;
+ }
+ if(args[k].type == arg_negative_flag) {
+ *(int*)args[k].value = 0;
+ break;
+ }
+ if(args[k].type == arg_counter) {
+ ++*(int *)args[k].value;
+ break;
+ }
+ if(args[k].type == arg_collect) {
+ struct getarg_collect_info *c = args[k].value;
+
+ if((*c->func)(TRUE, argc, rargv, optind, &j, c->data))
+ return ARG_ERR_BAD_ARG;
+ break;
+ }
+
+ if(argv[j + 1])
+ optarg = &argv[j + 1];
+ else {
+ ++*optind;
+ optarg = rargv[*optind];
+ }
+ if(optarg == NULL)
+ return ARG_ERR_NO_ARG;
+ if(args[k].type == arg_integer) {
+ int tmp;
+ if(sscanf(optarg, "%d", &tmp) != 1)
+ return ARG_ERR_BAD_ARG;
+ *(int*)args[k].value = tmp;
+ return 0;
+ } else if(args[k].type == arg_string) {
+ *(char**)args[k].value = optarg;
+ return 0;
+ } else if(args[k].type == arg_strings) {
+ add_string((getarg_strings*)args[k].value, optarg);
+ return 0;
+ } else if(args[k].type == arg_double) {
+ double tmp;
+ if(sscanf(optarg, "%lf", &tmp) != 1)
+ return ARG_ERR_BAD_ARG;
+ *(double*)args[k].value = tmp;
+ return 0;
+ }
+ return ARG_ERR_BAD_ARG;
+ }
+ }
+ if (k == num_args)
+ return ARG_ERR_NO_MATCH;
+ }
+ return 0;
+}
+
+int
+getarg(struct getargs *args, size_t num_args,
+ int argc, char **argv, int *optind)
+{
+ int i;
+ int ret = 0;
+
+ srand (time(NULL));
+ (*optind)++;
+ for(i = *optind; i < argc; i++) {
+ if(argv[i][0] != '-')
+ break;
+ if(argv[i][1] == '-'){
+ if(argv[i][2] == 0){
+ i++;
+ break;
+ }
+ ret = arg_match_long (args, num_args, argv[i] + 2,
+ argc, argv, &i);
+ } else {
+ ret = arg_match_short (args, num_args, argv[i],
+ argc, argv, &i);
+ }
+ if(ret)
+ break;
+ }
+ *optind = i;
+ return ret;
+}
+
+#if TEST
+int foo_flag = 2;
+int flag1 = 0;
+int flag2 = 0;
+int bar_int;
+char *baz_string;
+
+struct getargs args[] = {
+ { NULL, '1', arg_flag, &flag1, "one", NULL },
+ { NULL, '2', arg_flag, &flag2, "two", NULL },
+ { "foo", 'f', arg_negative_flag, &foo_flag, "foo", NULL },
+ { "bar", 'b', arg_integer, &bar_int, "bar", "seconds"},
+ { "baz", 'x', arg_string, &baz_string, "baz", "name" },
+};
+
+int main(int argc, char **argv)
+{
+ int optind = 0;
+ while(getarg(args, 5, argc, argv, &optind))
+ printf("Bad arg: %s\n", argv[optind]);
+ printf("flag1 = %d\n", flag1);
+ printf("flag2 = %d\n", flag2);
+ printf("foo_flag = %d\n", foo_flag);
+ printf("bar_int = %d\n", bar_int);
+ printf("baz_flag = %s\n", baz_string);
+ arg_printusage (args, 5, argv[0], "nothing here");
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/getarg.h b/crypto/heimdal/lib/roken/getarg.h
new file mode 100644
index 000000000000..7fd374bba53d
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getarg.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: getarg.h,v 1.10 1999/12/02 16:58:46 joda Exp $ */
+
+#ifndef __GETARG_H__
+#define __GETARG_H__
+
+#include <stddef.h>
+
+struct getargs{
+ const char *long_name;
+ char short_name;
+ enum { arg_integer,
+ arg_string,
+ arg_flag,
+ arg_negative_flag,
+ arg_strings,
+ arg_double,
+ arg_collect,
+ arg_counter
+ } type;
+ void *value;
+ const char *help;
+ const char *arg_help;
+};
+
+enum {
+ ARG_ERR_NO_MATCH = 1,
+ ARG_ERR_BAD_ARG,
+ ARG_ERR_NO_ARG
+};
+
+typedef struct getarg_strings {
+ int num_strings;
+ char **strings;
+} getarg_strings;
+
+typedef int (*getarg_collect_func)(int short_opt,
+ int argc,
+ char **argv,
+ int *optind,
+ int *optarg,
+ void *data);
+
+typedef struct getarg_collect_info {
+ getarg_collect_func func;
+ void *data;
+} getarg_collect_info;
+
+int getarg(struct getargs *args, size_t num_args,
+ int argc, char **argv, int *optind);
+
+void arg_printusage (struct getargs *args,
+ size_t num_args,
+ const char *progname,
+ const char *extra_string);
+
+#endif /* __GETARG_H__ */
diff --git a/crypto/heimdal/lib/roken/getcap.c b/crypto/heimdal/lib/roken/getcap.c
new file mode 100644
index 000000000000..997fabf253cd
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getcap.c
@@ -0,0 +1,1118 @@
+/* $NetBSD: getcap.c,v 1.29 1999/03/29 09:27:29 abs Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Casey Leedom of Lawrence Livermore National Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+RCSID("$Id: getcap.c,v 1.7 1999/11/17 21:11:58 assar Exp $");
+
+#include <sys/types.h>
+#include <ctype.h>
+#if defined(HAVE_DB_185_H)
+#include <db_185.h>
+#elif defined(HAVE_DB_H)
+#include <db.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define BFRAG 1024
+#if 0
+#define BSIZE 1024
+#endif
+#define ESC ('[' & 037) /* ASCII ESC */
+#define MAX_RECURSION 32 /* maximum getent recursion */
+#define SFRAG 100 /* cgetstr mallocs in SFRAG chunks */
+
+#define RECOK (char)0
+#define TCERR (char)1
+#define SHADOW (char)2
+
+static size_t topreclen; /* toprec length */
+static char *toprec; /* Additional record specified by cgetset() */
+static int gottoprec; /* Flag indicating retrieval of toprecord */
+
+#if defined(HAVE_DBOPEN) && defined(HAVE_DB_H)
+#define USE_DB
+#endif
+
+#ifdef USE_DB
+static int cdbget (DB *, char **, const char *);
+#endif
+static int getent (char **, size_t *, char **, int, const char *, int, char *);
+static int nfcmp (char *, char *);
+
+
+int cgetset(const char *ent);
+char *cgetcap(char *buf, const char *cap, int type);
+int cgetent(char **buf, char **db_array, const char *name);
+int cgetmatch(const char *buf, const char *name);
+int cgetclose(void);
+#if 0
+int cgetfirst(char **buf, char **db_array);
+int cgetnext(char **bp, char **db_array);
+#endif
+int cgetstr(char *buf, const char *cap, char **str);
+int cgetustr(char *buf, const char *cap, char **str);
+int cgetnum(char *buf, const char *cap, long *num);
+/*
+ * Cgetset() allows the addition of a user specified buffer to be added
+ * to the database array, in effect "pushing" the buffer on top of the
+ * virtual database. 0 is returned on success, -1 on failure.
+ */
+int
+cgetset(const char *ent)
+{
+ const char *source, *check;
+ char *dest;
+
+ if (ent == NULL) {
+ if (toprec)
+ free(toprec);
+ toprec = NULL;
+ topreclen = 0;
+ return (0);
+ }
+ topreclen = strlen(ent);
+ if ((toprec = malloc (topreclen + 1)) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ gottoprec = 0;
+
+ source=ent;
+ dest=toprec;
+ while (*source) { /* Strip whitespace */
+ *dest++ = *source++; /* Do not check first field */
+ while (*source == ':') {
+ check=source+1;
+ while (*check && (isspace((unsigned char)*check) ||
+ (*check=='\\' && isspace((unsigned char)check[1]))))
+ ++check;
+ if( *check == ':' )
+ source=check;
+ else
+ break;
+
+ }
+ }
+ *dest=0;
+
+ return (0);
+}
+
+/*
+ * Cgetcap searches the capability record buf for the capability cap with
+ * type `type'. A pointer to the value of cap is returned on success, NULL
+ * if the requested capability couldn't be found.
+ *
+ * Specifying a type of ':' means that nothing should follow cap (:cap:).
+ * In this case a pointer to the terminating ':' or NUL will be returned if
+ * cap is found.
+ *
+ * If (cap, '@') or (cap, terminator, '@') is found before (cap, terminator)
+ * return NULL.
+ */
+char *
+cgetcap(char *buf, const char *cap, int type)
+{
+ char *bp;
+ const char *cp;
+
+ bp = buf;
+ for (;;) {
+ /*
+ * Skip past the current capability field - it's either the
+ * name field if this is the first time through the loop, or
+ * the remainder of a field whose name failed to match cap.
+ */
+ for (;;)
+ if (*bp == '\0')
+ return (NULL);
+ else
+ if (*bp++ == ':')
+ break;
+
+ /*
+ * Try to match (cap, type) in buf.
+ */
+ for (cp = cap; *cp == *bp && *bp != '\0'; cp++, bp++)
+ continue;
+ if (*cp != '\0')
+ continue;
+ if (*bp == '@')
+ return (NULL);
+ if (type == ':') {
+ if (*bp != '\0' && *bp != ':')
+ continue;
+ return(bp);
+ }
+ if (*bp != type)
+ continue;
+ bp++;
+ return (*bp == '@' ? NULL : bp);
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * Cgetent extracts the capability record name from the NULL terminated file
+ * array db_array and returns a pointer to a malloc'd copy of it in buf.
+ * Buf must be retained through all subsequent calls to cgetcap, cgetnum,
+ * cgetflag, and cgetstr, but may then be free'd. 0 is returned on success,
+ * -1 if the requested record couldn't be found, -2 if a system error was
+ * encountered (couldn't open/read a file, etc.), and -3 if a potential
+ * reference loop is detected.
+ */
+int
+cgetent(char **buf, char **db_array, const char *name)
+{
+ size_t dummy;
+
+ return (getent(buf, &dummy, db_array, -1, name, 0, NULL));
+}
+
+/*
+ * Getent implements the functions of cgetent. If fd is non-negative,
+ * *db_array has already been opened and fd is the open file descriptor. We
+ * do this to save time and avoid using up file descriptors for tc=
+ * recursions.
+ *
+ * Getent returns the same success/failure codes as cgetent. On success, a
+ * pointer to a malloc'ed capability record with all tc= capabilities fully
+ * expanded and its length (not including trailing ASCII NUL) are left in
+ * *cap and *len.
+ *
+ * Basic algorithm:
+ * + Allocate memory incrementally as needed in chunks of size BFRAG
+ * for capability buffer.
+ * + Recurse for each tc=name and interpolate result. Stop when all
+ * names interpolated, a name can't be found, or depth exceeds
+ * MAX_RECURSION.
+ */
+static int
+getent(char **cap, size_t *len, char **db_array, int fd,
+ const char *name, int depth, char *nfield)
+{
+ char *r_end, *rp = NULL, **db_p; /* pacify gcc */
+ int myfd = 0, eof, foundit;
+ char *record;
+ int tc_not_resolved;
+
+ /*
+ * Return with ``loop detected'' error if we've recursed more than
+ * MAX_RECURSION times.
+ */
+ if (depth > MAX_RECURSION)
+ return (-3);
+
+ /*
+ * Check if we have a top record from cgetset().
+ */
+ if (depth == 0 && toprec != NULL && cgetmatch(toprec, name) == 0) {
+ if ((record = malloc (topreclen + BFRAG)) == NULL) {
+ errno = ENOMEM;
+ return (-2);
+ }
+ (void)strcpy(record, toprec); /* XXX: strcpy is safe */
+ db_p = db_array;
+ rp = record + topreclen + 1;
+ r_end = rp + BFRAG;
+ goto tc_exp;
+ }
+ /*
+ * Allocate first chunk of memory.
+ */
+ if ((record = malloc(BFRAG)) == NULL) {
+ errno = ENOMEM;
+ return (-2);
+ }
+ r_end = record + BFRAG;
+ foundit = 0;
+ /*
+ * Loop through database array until finding the record.
+ */
+
+ for (db_p = db_array; *db_p != NULL; db_p++) {
+ eof = 0;
+
+ /*
+ * Open database if not already open.
+ */
+
+ if (fd >= 0) {
+ (void)lseek(fd, (off_t)0, SEEK_SET);
+ } else {
+#ifdef USE_DB
+ char pbuf[_POSIX_PATH_MAX];
+ char *cbuf;
+ size_t clen;
+ int retval;
+ DB *capdbp;
+
+ (void)snprintf(pbuf, sizeof(pbuf), "%s.db", *db_p);
+ if ((capdbp = dbopen(pbuf, O_RDONLY, 0, DB_HASH, 0))
+ != NULL) {
+ free(record);
+ retval = cdbget(capdbp, &record, name);
+ if (retval < 0) {
+ /* no record available */
+ (void)capdbp->close(capdbp);
+ return (retval);
+ }
+ /* save the data; close frees it */
+ clen = strlen(record);
+ cbuf = malloc(clen + 1);
+ memmove(cbuf, record, clen + 1);
+ if (capdbp->close(capdbp) < 0) {
+ free(cbuf);
+ return (-2);
+ }
+ *len = clen;
+ *cap = cbuf;
+ return (retval);
+ } else
+#endif
+ {
+ fd = open(*db_p, O_RDONLY, 0);
+ if (fd < 0) {
+ /* No error on unfound file. */
+ continue;
+ }
+ myfd = 1;
+ }
+ }
+ /*
+ * Find the requested capability record ...
+ */
+ {
+ char buf[BUFSIZ];
+ char *b_end, *bp, *cp;
+ int c, slash;
+
+ /*
+ * Loop invariants:
+ * There is always room for one more character in record.
+ * R_end always points just past end of record.
+ * Rp always points just past last character in record.
+ * B_end always points just past last character in buf.
+ * Bp always points at next character in buf.
+ * Cp remembers where the last colon was.
+ */
+ b_end = buf;
+ bp = buf;
+ cp = 0;
+ slash = 0;
+ for (;;) {
+
+ /*
+ * Read in a line implementing (\, newline)
+ * line continuation.
+ */
+ rp = record;
+ for (;;) {
+ if (bp >= b_end) {
+ int n;
+
+ n = read(fd, buf, sizeof(buf));
+ if (n <= 0) {
+ if (myfd)
+ (void)close(fd);
+ if (n < 0) {
+ free(record);
+ return (-2);
+ } else {
+ fd = -1;
+ eof = 1;
+ break;
+ }
+ }
+ b_end = buf+n;
+ bp = buf;
+ }
+
+ c = *bp++;
+ if (c == '\n') {
+ if (slash) {
+ slash = 0;
+ rp--;
+ continue;
+ } else
+ break;
+ }
+ if (slash) {
+ slash = 0;
+ cp = 0;
+ }
+ if (c == ':') {
+ /*
+ * If the field was `empty' (i.e.
+ * contained only white space), back up
+ * to the colon (eliminating the
+ * field).
+ */
+ if (cp)
+ rp = cp;
+ else
+ cp = rp;
+ } else if (c == '\\') {
+ slash = 1;
+ } else if (c != ' ' && c != '\t') {
+ /*
+ * Forget where the colon was, as this
+ * is not an empty field.
+ */
+ cp = 0;
+ }
+ *rp++ = c;
+
+ /*
+ * Enforce loop invariant: if no room
+ * left in record buffer, try to get
+ * some more.
+ */
+ if (rp >= r_end) {
+ u_int pos;
+ size_t newsize;
+
+ pos = rp - record;
+ newsize = r_end - record + BFRAG;
+ record = realloc(record, newsize);
+ if (record == NULL) {
+ errno = ENOMEM;
+ if (myfd)
+ (void)close(fd);
+ return (-2);
+ }
+ r_end = record + newsize;
+ rp = record + pos;
+ }
+ }
+ /* Eliminate any white space after the last colon. */
+ if (cp)
+ rp = cp + 1;
+ /* Loop invariant lets us do this. */
+ *rp++ = '\0';
+
+ /*
+ * If encountered eof check next file.
+ */
+ if (eof)
+ break;
+
+ /*
+ * Toss blank lines and comments.
+ */
+ if (*record == '\0' || *record == '#')
+ continue;
+
+ /*
+ * See if this is the record we want ...
+ */
+ if (cgetmatch(record, name) == 0) {
+ if (nfield == NULL || !nfcmp(nfield, record)) {
+ foundit = 1;
+ break; /* found it! */
+ }
+ }
+ }
+ }
+ if (foundit)
+ break;
+ }
+
+ if (!foundit)
+ return (-1);
+
+ /*
+ * Got the capability record, but now we have to expand all tc=name
+ * references in it ...
+ */
+ tc_exp: {
+ char *newicap, *s;
+ size_t ilen, newilen;
+ int diff, iret, tclen;
+ char *icap, *scan, *tc, *tcstart, *tcend;
+
+ /*
+ * Loop invariants:
+ * There is room for one more character in record.
+ * R_end points just past end of record.
+ * Rp points just past last character in record.
+ * Scan points at remainder of record that needs to be
+ * scanned for tc=name constructs.
+ */
+ scan = record;
+ tc_not_resolved = 0;
+ for (;;) {
+ if ((tc = cgetcap(scan, "tc", '=')) == NULL)
+ break;
+
+ /*
+ * Find end of tc=name and stomp on the trailing `:'
+ * (if present) so we can use it to call ourselves.
+ */
+ s = tc;
+ for (;;)
+ if (*s == '\0')
+ break;
+ else
+ if (*s++ == ':') {
+ *(s - 1) = '\0';
+ break;
+ }
+ tcstart = tc - 3;
+ tclen = s - tcstart;
+ tcend = s;
+
+ iret = getent(&icap, &ilen, db_p, fd, tc, depth+1,
+ NULL);
+ newicap = icap; /* Put into a register. */
+ newilen = ilen;
+ if (iret != 0) {
+ /* an error */
+ if (iret < -1) {
+ if (myfd)
+ (void)close(fd);
+ free(record);
+ return (iret);
+ }
+ if (iret == 1)
+ tc_not_resolved = 1;
+ /* couldn't resolve tc */
+ if (iret == -1) {
+ *(s - 1) = ':';
+ scan = s - 1;
+ tc_not_resolved = 1;
+ continue;
+
+ }
+ }
+ /* not interested in name field of tc'ed record */
+ s = newicap;
+ for (;;)
+ if (*s == '\0')
+ break;
+ else
+ if (*s++ == ':')
+ break;
+ newilen -= s - newicap;
+ newicap = s;
+
+ /* make sure interpolated record is `:'-terminated */
+ s += newilen;
+ if (*(s-1) != ':') {
+ *s = ':'; /* overwrite NUL with : */
+ newilen++;
+ }
+
+ /*
+ * Make sure there's enough room to insert the
+ * new record.
+ */
+ diff = newilen - tclen;
+ if (diff >= r_end - rp) {
+ u_int pos, tcpos, tcposend;
+ size_t newsize;
+
+ pos = rp - record;
+ newsize = r_end - record + diff + BFRAG;
+ tcpos = tcstart - record;
+ tcposend = tcend - record;
+ record = realloc(record, newsize);
+ if (record == NULL) {
+ errno = ENOMEM;
+ if (myfd)
+ (void)close(fd);
+ free(icap);
+ return (-2);
+ }
+ r_end = record + newsize;
+ rp = record + pos;
+ tcstart = record + tcpos;
+ tcend = record + tcposend;
+ }
+
+ /*
+ * Insert tc'ed record into our record.
+ */
+ s = tcstart + newilen;
+ memmove(s, tcend, (size_t)(rp - tcend));
+ memmove(tcstart, newicap, newilen);
+ rp += diff;
+ free(icap);
+
+ /*
+ * Start scan on `:' so next cgetcap works properly
+ * (cgetcap always skips first field).
+ */
+ scan = s-1;
+ }
+
+ }
+ /*
+ * Close file (if we opened it), give back any extra memory, and
+ * return capability, length and success.
+ */
+ if (myfd)
+ (void)close(fd);
+ *len = rp - record - 1; /* don't count NUL */
+ if (r_end > rp)
+ if ((record =
+ realloc(record, (size_t)(rp - record))) == NULL) {
+ errno = ENOMEM;
+ return (-2);
+ }
+
+ *cap = record;
+ if (tc_not_resolved)
+ return (1);
+ return (0);
+}
+
+#ifdef USE_DB
+static int
+cdbget(DB *capdbp, char **bp, const char *name)
+{
+ DBT key;
+ DBT data;
+
+ /* LINTED key is not modified */
+ key.data = (char *)name;
+ key.size = strlen(name);
+
+ for (;;) {
+ /* Get the reference. */
+ switch(capdbp->get(capdbp, &key, &data, 0)) {
+ case -1:
+ return (-2);
+ case 1:
+ return (-1);
+ }
+
+ /* If not an index to another record, leave. */
+ if (((char *)data.data)[0] != SHADOW)
+ break;
+
+ key.data = (char *)data.data + 1;
+ key.size = data.size - 1;
+ }
+
+ *bp = (char *)data.data + 1;
+ return (((char *)(data.data))[0] == TCERR ? 1 : 0);
+}
+#endif /* USE_DB */
+
+/*
+ * Cgetmatch will return 0 if name is one of the names of the capability
+ * record buf, -1 if not.
+ */
+int
+cgetmatch(const char *buf, const char *name)
+{
+ const char *np, *bp;
+
+ /*
+ * Start search at beginning of record.
+ */
+ bp = buf;
+ for (;;) {
+ /*
+ * Try to match a record name.
+ */
+ np = name;
+ for (;;)
+ if (*np == '\0') {
+ if (*bp == '|' || *bp == ':' || *bp == '\0')
+ return (0);
+ else
+ break;
+ } else
+ if (*bp++ != *np++)
+ break;
+
+ /*
+ * Match failed, skip to next name in record.
+ */
+ bp--; /* a '|' or ':' may have stopped the match */
+ for (;;)
+ if (*bp == '\0' || *bp == ':')
+ return (-1); /* match failed totally */
+ else
+ if (*bp++ == '|')
+ break; /* found next name */
+ }
+}
+
+#if 0
+int
+cgetfirst(char **buf, char **db_array)
+{
+ (void)cgetclose();
+ return (cgetnext(buf, db_array));
+}
+#endif
+
+static FILE *pfp;
+static int slash;
+static char **dbp;
+
+int
+cgetclose(void)
+{
+ if (pfp != NULL) {
+ (void)fclose(pfp);
+ pfp = NULL;
+ }
+ dbp = NULL;
+ gottoprec = 0;
+ slash = 0;
+ return(0);
+}
+
+#if 0
+/*
+ * Cgetnext() gets either the first or next entry in the logical database
+ * specified by db_array. It returns 0 upon completion of the database, 1
+ * upon returning an entry with more remaining, and -1 if an error occurs.
+ */
+int
+cgetnext(char **bp, char **db_array)
+{
+ size_t len;
+ int status, done;
+ char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE];
+ size_t dummy;
+
+ if (dbp == NULL)
+ dbp = db_array;
+
+ if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL) {
+ (void)cgetclose();
+ return (-1);
+ }
+ for(;;) {
+ if (toprec && !gottoprec) {
+ gottoprec = 1;
+ line = toprec;
+ } else {
+ line = fgetln(pfp, &len);
+ if (line == NULL && pfp) {
+ if (ferror(pfp)) {
+ (void)cgetclose();
+ return (-1);
+ } else {
+ (void)fclose(pfp);
+ pfp = NULL;
+ if (*++dbp == NULL) {
+ (void)cgetclose();
+ return (0);
+ } else if ((pfp =
+ fopen(*dbp, "r")) == NULL) {
+ (void)cgetclose();
+ return (-1);
+ } else
+ continue;
+ }
+ } else
+ line[len - 1] = '\0';
+ if (len == 1) {
+ slash = 0;
+ continue;
+ }
+ if (isspace((unsigned char)*line) ||
+ *line == ':' || *line == '#' || slash) {
+ if (line[len - 2] == '\\')
+ slash = 1;
+ else
+ slash = 0;
+ continue;
+ }
+ if (line[len - 2] == '\\')
+ slash = 1;
+ else
+ slash = 0;
+ }
+
+
+ /*
+ * Line points to a name line.
+ */
+ done = 0;
+ np = nbuf;
+ for (;;) {
+ for (cp = line; *cp != '\0'; cp++) {
+ if (*cp == ':') {
+ *np++ = ':';
+ done = 1;
+ break;
+ }
+ if (*cp == '\\')
+ break;
+ *np++ = *cp;
+ }
+ if (done) {
+ *np = '\0';
+ break;
+ } else { /* name field extends beyond the line */
+ line = fgetln(pfp, &len);
+ if (line == NULL && pfp) {
+ if (ferror(pfp)) {
+ (void)cgetclose();
+ return (-1);
+ }
+ (void)fclose(pfp);
+ pfp = NULL;
+ *np = '\0';
+ break;
+ } else
+ line[len - 1] = '\0';
+ }
+ }
+ rp = buf;
+ for(cp = nbuf; *cp != '\0'; cp++)
+ if (*cp == '|' || *cp == ':')
+ break;
+ else
+ *rp++ = *cp;
+
+ *rp = '\0';
+ /*
+ * XXX
+ * Last argument of getent here should be nbuf if we want true
+ * sequential access in the case of duplicates.
+ * With NULL, getent will return the first entry found
+ * rather than the duplicate entry record. This is a
+ * matter of semantics that should be resolved.
+ */
+ status = getent(bp, &dummy, db_array, -1, buf, 0, NULL);
+ if (status == -2 || status == -3)
+ (void)cgetclose();
+
+ return (status + 1);
+ }
+ /* NOTREACHED */
+}
+#endif
+
+/*
+ * Cgetstr retrieves the value of the string capability cap from the
+ * capability record pointed to by buf. A pointer to a decoded, NUL
+ * terminated, malloc'd copy of the string is returned in the char *
+ * pointed to by str. The length of the string not including the trailing
+ * NUL is returned on success, -1 if the requested string capability
+ * couldn't be found, -2 if a system error was encountered (storage
+ * allocation failure).
+ */
+int
+cgetstr(char *buf, const char *cap, char **str)
+{
+ u_int m_room;
+ const char *bp;
+ char *mp;
+ int len;
+ char *mem;
+
+ /*
+ * Find string capability cap
+ */
+ bp = cgetcap(buf, cap, '=');
+ if (bp == NULL)
+ return (-1);
+
+ /*
+ * Conversion / storage allocation loop ... Allocate memory in
+ * chunks SFRAG in size.
+ */
+ if ((mem = malloc(SFRAG)) == NULL) {
+ errno = ENOMEM;
+ return (-2); /* couldn't even allocate the first fragment */
+ }
+ m_room = SFRAG;
+ mp = mem;
+
+ while (*bp != ':' && *bp != '\0') {
+ /*
+ * Loop invariants:
+ * There is always room for one more character in mem.
+ * Mp always points just past last character in mem.
+ * Bp always points at next character in buf.
+ */
+ if (*bp == '^') {
+ bp++;
+ if (*bp == ':' || *bp == '\0')
+ break; /* drop unfinished escape */
+ *mp++ = *bp++ & 037;
+ } else if (*bp == '\\') {
+ bp++;
+ if (*bp == ':' || *bp == '\0')
+ break; /* drop unfinished escape */
+ if ('0' <= *bp && *bp <= '7') {
+ int n, i;
+
+ n = 0;
+ i = 3; /* maximum of three octal digits */
+ do {
+ n = n * 8 + (*bp++ - '0');
+ } while (--i && '0' <= *bp && *bp <= '7');
+ *mp++ = n;
+ }
+ else switch (*bp++) {
+ case 'b': case 'B':
+ *mp++ = '\b';
+ break;
+ case 't': case 'T':
+ *mp++ = '\t';
+ break;
+ case 'n': case 'N':
+ *mp++ = '\n';
+ break;
+ case 'f': case 'F':
+ *mp++ = '\f';
+ break;
+ case 'r': case 'R':
+ *mp++ = '\r';
+ break;
+ case 'e': case 'E':
+ *mp++ = ESC;
+ break;
+ case 'c': case 'C':
+ *mp++ = ':';
+ break;
+ default:
+ /*
+ * Catches '\', '^', and
+ * everything else.
+ */
+ *mp++ = *(bp-1);
+ break;
+ }
+ } else
+ *mp++ = *bp++;
+ m_room--;
+
+ /*
+ * Enforce loop invariant: if no room left in current
+ * buffer, try to get some more.
+ */
+ if (m_room == 0) {
+ size_t size = mp - mem;
+
+ if ((mem = realloc(mem, size + SFRAG)) == NULL)
+ return (-2);
+ m_room = SFRAG;
+ mp = mem + size;
+ }
+ }
+ *mp++ = '\0'; /* loop invariant let's us do this */
+ m_room--;
+ len = mp - mem - 1;
+
+ /*
+ * Give back any extra memory and return value and success.
+ */
+ if (m_room != 0)
+ if ((mem = realloc(mem, (size_t)(mp - mem))) == NULL)
+ return (-2);
+ *str = mem;
+ return (len);
+}
+
+/*
+ * Cgetustr retrieves the value of the string capability cap from the
+ * capability record pointed to by buf. The difference between cgetustr()
+ * and cgetstr() is that cgetustr does not decode escapes but rather treats
+ * all characters literally. A pointer to a NUL terminated malloc'd
+ * copy of the string is returned in the char pointed to by str. The
+ * length of the string not including the trailing NUL is returned on success,
+ * -1 if the requested string capability couldn't be found, -2 if a system
+ * error was encountered (storage allocation failure).
+ */
+int
+cgetustr(char *buf, const char *cap, char **str)
+{
+ u_int m_room;
+ const char *bp;
+ char *mp;
+ int len;
+ char *mem;
+
+ /*
+ * Find string capability cap
+ */
+ if ((bp = cgetcap(buf, cap, '=')) == NULL)
+ return (-1);
+
+ /*
+ * Conversion / storage allocation loop ... Allocate memory in
+ * chunks SFRAG in size.
+ */
+ if ((mem = malloc(SFRAG)) == NULL) {
+ errno = ENOMEM;
+ return (-2); /* couldn't even allocate the first fragment */
+ }
+ m_room = SFRAG;
+ mp = mem;
+
+ while (*bp != ':' && *bp != '\0') {
+ /*
+ * Loop invariants:
+ * There is always room for one more character in mem.
+ * Mp always points just past last character in mem.
+ * Bp always points at next character in buf.
+ */
+ *mp++ = *bp++;
+ m_room--;
+
+ /*
+ * Enforce loop invariant: if no room left in current
+ * buffer, try to get some more.
+ */
+ if (m_room == 0) {
+ size_t size = mp - mem;
+
+ if ((mem = realloc(mem, size + SFRAG)) == NULL)
+ return (-2);
+ m_room = SFRAG;
+ mp = mem + size;
+ }
+ }
+ *mp++ = '\0'; /* loop invariant let's us do this */
+ m_room--;
+ len = mp - mem - 1;
+
+ /*
+ * Give back any extra memory and return value and success.
+ */
+ if (m_room != 0)
+ if ((mem = realloc(mem, (size_t)(mp - mem))) == NULL)
+ return (-2);
+ *str = mem;
+ return (len);
+}
+
+/*
+ * Cgetnum retrieves the value of the numeric capability cap from the
+ * capability record pointed to by buf. The numeric value is returned in
+ * the long pointed to by num. 0 is returned on success, -1 if the requested
+ * numeric capability couldn't be found.
+ */
+int
+cgetnum(char *buf, const char *cap, long *num)
+{
+ long n;
+ int base, digit;
+ const char *bp;
+
+ /*
+ * Find numeric capability cap
+ */
+ bp = cgetcap(buf, cap, '#');
+ if (bp == NULL)
+ return (-1);
+
+ /*
+ * Look at value and determine numeric base:
+ * 0x... or 0X... hexadecimal,
+ * else 0... octal,
+ * else decimal.
+ */
+ if (*bp == '0') {
+ bp++;
+ if (*bp == 'x' || *bp == 'X') {
+ bp++;
+ base = 16;
+ } else
+ base = 8;
+ } else
+ base = 10;
+
+ /*
+ * Conversion loop ...
+ */
+ n = 0;
+ for (;;) {
+ if ('0' <= *bp && *bp <= '9')
+ digit = *bp - '0';
+ else if ('a' <= *bp && *bp <= 'f')
+ digit = 10 + *bp - 'a';
+ else if ('A' <= *bp && *bp <= 'F')
+ digit = 10 + *bp - 'A';
+ else
+ break;
+
+ if (digit >= base)
+ break;
+
+ n = n * base + digit;
+ bp++;
+ }
+
+ /*
+ * Return value and success.
+ */
+ *num = n;
+ return (0);
+}
+
+
+/*
+ * Compare name field of record.
+ */
+static int
+nfcmp(char *nf, char *rec)
+{
+ char *cp, tmp;
+ int ret;
+
+ for (cp = rec; *cp != ':'; cp++)
+ ;
+
+ tmp = *(cp + 1);
+ *(cp + 1) = '\0';
+ ret = strcmp(nf, rec);
+ *(cp + 1) = tmp;
+
+ return (ret);
+}
diff --git a/crypto/heimdal/lib/roken/getcwd.c b/crypto/heimdal/lib/roken/getcwd.c
new file mode 100644
index 000000000000..c1f26100216c
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getcwd.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getcwd.c,v 1.12 1999/12/02 16:58:46 joda Exp $");
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "roken.h"
+
+char*
+getcwd(char *path, size_t size)
+{
+ char xxx[MaxPathLen];
+ char *ret;
+ ret = getwd(xxx);
+ if(ret)
+ strlcpy(path, xxx, size);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/getdtablesize.c b/crypto/heimdal/lib/roken/getdtablesize.c
new file mode 100644
index 000000000000..9f9c74bdc59b
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getdtablesize.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getdtablesize.c,v 1.10 1999/12/02 16:58:46 joda Exp $");
+#endif
+
+#include "roken.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
+int getdtablesize(void)
+{
+ int files = -1;
+#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
+ files = sysconf(_SC_OPEN_MAX);
+#else /* !defined(HAVE_SYSCONF) */
+#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
+ struct rlimit res;
+ if (getrlimit(RLIMIT_NOFILE, &res) == 0)
+ files = res.rlim_cur;
+#else /* !definded(HAVE_GETRLIMIT) */
+#if defined(HAVE_SYSCTL) && defined(CTL_KERN) && defined(KERN_MAXFILES)
+ int mib[2];
+ size_t len;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_MAXFILES;
+ len = sizeof(files);
+ sysctl(&mib, 2, &files, sizeof(nfil), NULL, 0);
+#endif /* defined(HAVE_SYSCTL) */
+#endif /* !definded(HAVE_GETRLIMIT) */
+#endif /* !defined(HAVE_SYSCONF) */
+
+#ifdef OPEN_MAX
+ if (files < 0)
+ files = OPEN_MAX;
+#endif
+
+#ifdef NOFILE
+ if (files < 0)
+ files = NOFILE;
+#endif
+
+ return files;
+}
diff --git a/crypto/heimdal/lib/roken/getegid.c b/crypto/heimdal/lib/roken/getegid.c
new file mode 100644
index 000000000000..b6eab857e41a
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getegid.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+#ifndef HAVE_GETEGID
+
+RCSID("$Id: getegid.c,v 1.2 1999/12/02 16:58:46 joda Exp $");
+
+int getegid(void)
+{
+ return getgid();
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/geteuid.c b/crypto/heimdal/lib/roken/geteuid.c
new file mode 100644
index 000000000000..4bdf531bf921
--- /dev/null
+++ b/crypto/heimdal/lib/roken/geteuid.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+#ifndef HAVE_GETEUID
+
+RCSID("$Id: geteuid.c,v 1.2 1999/12/02 16:58:46 joda Exp $");
+
+int geteuid(void)
+{
+ return getuid();
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/getgid.c b/crypto/heimdal/lib/roken/getgid.c
new file mode 100644
index 000000000000..f2ca01a69982
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getgid.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+#ifndef HAVE_GETGID
+
+RCSID("$Id: getgid.c,v 1.2 1999/12/02 16:58:46 joda Exp $");
+
+int getgid(void)
+{
+ return 17;
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/gethostname.c b/crypto/heimdal/lib/roken/gethostname.c
new file mode 100644
index 000000000000..753ba9f1b6b9
--- /dev/null
+++ b/crypto/heimdal/lib/roken/gethostname.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+#ifndef HAVE_GETHOSTNAME
+
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
+/*
+ * Return the local host's name in "name", up to "namelen" characters.
+ * "name" will be null-terminated if "namelen" is big enough.
+ * The return code is 0 on success, -1 on failure. (The calling
+ * interface is identical to gethostname(2).)
+ */
+
+int
+gethostname(char *name, int namelen)
+{
+#if defined(HAVE_UNAME)
+ {
+ struct utsname utsname;
+ int ret;
+
+ ret = uname (&utsname);
+ if (ret < 0)
+ return ret;
+ strlcpy (name, utsname.nodename, namelen);
+ return 0;
+ }
+#else
+ strlcpy (name, "some.random.host", namelen);
+ return 0;
+#endif
+}
+
+#endif /* GETHOSTNAME */
diff --git a/crypto/heimdal/lib/roken/getipnodebyaddr.c b/crypto/heimdal/lib/roken/getipnodebyaddr.c
new file mode 100644
index 000000000000..f22aad7f73cb
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getipnodebyaddr.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getipnodebyaddr.c,v 1.2 1999/12/02 16:58:46 joda Exp $");
+#endif
+
+#include "roken.h"
+
+/*
+ * lookup `src, len' (address family `af') in DNS and return a pointer
+ * to a malloced struct hostent or NULL.
+ */
+
+struct hostent *
+getipnodebyaddr (const void *src, size_t len, int af, int *error_num)
+{
+ struct hostent *tmp;
+
+ tmp = gethostbyaddr (src, len, af);
+ if (tmp == NULL) {
+ switch (h_errno) {
+ case HOST_NOT_FOUND :
+ case TRY_AGAIN :
+ case NO_RECOVERY :
+ *error_num = h_errno;
+ break;
+ case NO_DATA :
+ *error_num = NO_ADDRESS;
+ break;
+ default :
+ *error_num = NO_RECOVERY;
+ break;
+ }
+ return NULL;
+ }
+ tmp = copyhostent (tmp);
+ if (tmp == NULL) {
+ *error_num = TRY_AGAIN;
+ return NULL;
+ }
+ return tmp;
+}
diff --git a/crypto/heimdal/lib/roken/getipnodebyname.c b/crypto/heimdal/lib/roken/getipnodebyname.c
new file mode 100644
index 000000000000..576feef0aea6
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getipnodebyname.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getipnodebyname.c,v 1.3 1999/12/02 16:58:46 joda Exp $");
+#endif
+
+#include "roken.h"
+
+#ifndef HAVE_H_ERRNO
+static int h_errno = NO_RECOVERY;
+#endif
+
+/*
+ * lookup `name' (address family `af') in DNS and return a pointer
+ * to a malloced struct hostent or NULL.
+ */
+
+struct hostent *
+getipnodebyname (const char *name, int af, int flags, int *error_num)
+{
+ struct hostent *tmp;
+
+#ifdef HAVE_GETHOSTBYNAME2
+ tmp = gethostbyname2 (name, af);
+#else
+ if (af != AF_INET) {
+ *error_num = NO_ADDRESS;
+ return NULL;
+ }
+ tmp = gethostbyname (name);
+#endif
+ if (tmp == NULL) {
+ switch (h_errno) {
+ case HOST_NOT_FOUND :
+ case TRY_AGAIN :
+ case NO_RECOVERY :
+ *error_num = h_errno;
+ break;
+ case NO_DATA :
+ *error_num = NO_ADDRESS;
+ break;
+ default :
+ *error_num = NO_RECOVERY;
+ break;
+ }
+ return NULL;
+ }
+ tmp = copyhostent (tmp);
+ if (tmp == NULL) {
+ *error_num = TRY_AGAIN;
+ return NULL;
+ }
+ return tmp;
+}
diff --git a/crypto/heimdal/lib/roken/getnameinfo.c b/crypto/heimdal/lib/roken/getnameinfo.c
new file mode 100644
index 000000000000..7e2d232d6c36
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getnameinfo.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getnameinfo.c,v 1.2 1999/12/03 04:10:07 assar Exp $");
+#endif
+
+#include "roken.h"
+
+static int
+doit (int af,
+ const void *addr,
+ size_t addrlen,
+ int port,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags)
+{
+ if (host != NULL) {
+ if (flags & NI_NUMERICHOST) {
+ if (inet_ntop (af, addr, host, hostlen) == NULL)
+ return EAI_SYSTEM;
+ } else {
+ struct hostent *he = gethostbyaddr (addr,
+ addrlen,
+ af);
+ if (he != NULL) {
+ strlcpy (host, he->h_name, hostlen);
+ if (flags & NI_NOFQDN) {
+ char *dot = strchr (host, '.');
+ if (dot != NULL)
+ *dot = '\0';
+ }
+ } else if (flags & NI_NAMEREQD) {
+ return EAI_NONAME;
+ } else if (inet_ntop (AF_INET, addr, host, hostlen) == NULL)
+ return EAI_SYSTEM;
+ }
+ }
+
+ if (serv != NULL) {
+ if (flags & NI_NUMERICSERV) {
+ snprintf (serv, servlen, "%u", ntohs(port));
+ } else {
+ const char *proto = "tcp";
+ struct servent *se;
+
+ if (flags & NI_DGRAM)
+ proto = "udp";
+
+ se = getservbyport (port, proto);
+ if (se == NULL) {
+ snprintf (serv, servlen, "%u", ntohs(port));
+ } else {
+ strlcpy (serv, se->s_name, servlen);
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+getnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags)
+{
+ switch (sa->sa_family) {
+#ifdef HAVE_IPV6
+ case AF_INET6 : {
+ const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+
+ return doit (AF_INET6, &sin6->sin6_addr, sizeof(sin6->sin6_addr),
+ sin6->sin6_port,
+ host, hostlen,
+ serv, servlen,
+ flags);
+ }
+#endif
+ case AF_INET : {
+ const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
+
+ return doit (AF_INET, &sin->sin_addr, sizeof(sin->sin_addr),
+ sin->sin_port,
+ host, hostlen,
+ serv, servlen,
+ flags);
+ }
+ default :
+ return EAI_FAMILY;
+ }
+}
diff --git a/crypto/heimdal/lib/roken/getnameinfo_verified.c b/crypto/heimdal/lib/roken/getnameinfo_verified.c
new file mode 100644
index 000000000000..2a23d24dd06a
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getnameinfo_verified.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: getnameinfo_verified.c,v 1.2 1999/12/05 10:52:09 assar Exp $");
+#endif
+
+#include "roken.h"
+
+int
+getnameinfo_verified(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags)
+{
+ int ret;
+ struct addrinfo *ai, *a;
+
+ if (host == NULL)
+ return EAI_NONAME;
+
+ ret = getnameinfo (sa, salen, host, hostlen, serv, servlen, flags);
+ if (ret)
+ return ret;
+ ret = getaddrinfo (host, serv, NULL, &ai);
+ if (ret)
+ return ret;
+ for (a = ai; a != NULL; a = a->ai_next) {
+ if (a->ai_addrlen == salen
+ && memcmp (a->ai_addr, sa, salen) == 0)
+ return 0;
+ }
+ if (flags & NI_NAMEREQD)
+ return EAI_NONAME;
+ ret = getnameinfo (sa, salen, host, hostlen, serv, servlen,
+ flags | NI_NUMERICSERV | NI_NUMERICHOST);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/getopt.c b/crypto/heimdal/lib/roken/getopt.c
new file mode 100644
index 000000000000..45fc35023453
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getopt.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getopt.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#ifndef __STDC__
+#define const
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * get option letter from argument vector
+ */
+int opterr = 1, /* if error message should be printed */
+ optind = 1, /* index into parent argv vector */
+ optopt, /* character checked for validity */
+ optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+int
+getopt(nargc, nargv, ostr)
+ int nargc;
+ char * const *nargv;
+ const char *ostr;
+{
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+ char *p;
+
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc || *(place = nargv[optind]) != '-') {
+ place = EMSG;
+ return(-1);
+ }
+ if (place[1] && *++place == '-') { /* found "--" */
+ ++optind;
+ place = EMSG;
+ return(-1);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' ||
+ !(oli = strchr(ostr, optopt))) {
+ /*
+ * if the user didn't specify '-' as an option,
+ * assume it means -1 (EOF).
+ */
+ if (optopt == (int)'-')
+ return(-1);
+ if (!*place)
+ ++optind;
+ if (opterr && *ostr != ':') {
+ if (!(p = strrchr(*nargv, '/')))
+ p = *nargv;
+ else
+ ++p;
+ fprintf(stderr, "%s: illegal option -- %c\n",
+ p, optopt);
+ }
+ return(BADCH);
+ }
+ if (*++oli != ':') { /* don't need argument */
+ optarg = NULL;
+ if (!*place)
+ ++optind;
+ }
+ else { /* need an argument */
+ if (*place) /* no white space */
+ optarg = place;
+ else if (nargc <= ++optind) { /* no arg */
+ place = EMSG;
+ if (!(p = strrchr(*nargv, '/')))
+ p = *nargv;
+ else
+ ++p;
+ if (*ostr == ':')
+ return(BADARG);
+ if (opterr)
+ fprintf(stderr,
+ "%s: option requires an argument -- %c\n",
+ p, optopt);
+ return(BADCH);
+ }
+ else /* white space */
+ optarg = nargv[optind];
+ place = EMSG;
+ ++optind;
+ }
+ return(optopt); /* dump back option letter */
+}
diff --git a/crypto/heimdal/lib/roken/gettimeofday.c b/crypto/heimdal/lib/roken/gettimeofday.c
new file mode 100644
index 000000000000..ec8b62f64e76
--- /dev/null
+++ b/crypto/heimdal/lib/roken/gettimeofday.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+#ifndef HAVE_GETTIMEOFDAY
+
+RCSID("$Id: gettimeofday.c,v 1.8 1999/12/02 16:58:46 joda Exp $");
+
+/*
+ * Simple gettimeofday that only returns seconds.
+ */
+int
+gettimeofday (struct timeval *tp, void *ignore)
+{
+ time_t t;
+
+ t = time(NULL);
+ tp->tv_sec = t;
+ tp->tv_usec = 0;
+ return 0;
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/getuid.c b/crypto/heimdal/lib/roken/getuid.c
new file mode 100644
index 000000000000..6ebce0a810cd
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getuid.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+#ifndef HAVE_GETUID
+
+RCSID("$Id: getuid.c,v 1.3 1999/12/02 16:58:46 joda Exp $");
+
+int getuid(void)
+{
+ return 17;
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/getusershell.c b/crypto/heimdal/lib/roken/getusershell.c
new file mode 100644
index 000000000000..87a48ece19b5
--- /dev/null
+++ b/crypto/heimdal/lib/roken/getusershell.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+RCSID("$Id: getusershell.c,v 1.8 1997/04/20 06:18:03 assar Exp $");
+
+#ifndef HAVE_GETUSERSHELL
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifndef _PATH_SHELLS
+#define _PATH_SHELLS "/etc/shells"
+#endif
+
+#ifndef _PATH_BSHELL
+#define _PATH_BSHELL "/bin/sh"
+#endif
+
+#ifndef _PATH_CSHELL
+#define _PATH_CSHELL "/bin/csh"
+#endif
+
+/*
+ * Local shells should NOT be added here. They should be added in
+ * /etc/shells.
+ */
+
+static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
+static char **curshell, **shells, *strings;
+static char **initshells (void);
+
+/*
+ * Get a list of shells from _PATH_SHELLS, if it exists.
+ */
+char *
+getusershell()
+{
+ char *ret;
+
+ if (curshell == NULL)
+ curshell = initshells();
+ ret = *curshell;
+ if (ret != NULL)
+ curshell++;
+ return (ret);
+}
+
+void
+endusershell()
+{
+
+ if (shells != NULL)
+ free(shells);
+ shells = NULL;
+ if (strings != NULL)
+ free(strings);
+ strings = NULL;
+ curshell = NULL;
+}
+
+void
+setusershell()
+{
+
+ curshell = initshells();
+}
+
+static char **
+initshells()
+{
+ char **sp, *cp;
+ FILE *fp;
+ struct stat statb;
+
+ if (shells != NULL)
+ free(shells);
+ shells = NULL;
+ if (strings != NULL)
+ free(strings);
+ strings = NULL;
+ if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
+ return (okshells);
+ if (fstat(fileno(fp), &statb) == -1) {
+ fclose(fp);
+ return (okshells);
+ }
+ if ((strings = malloc((u_int)statb.st_size)) == NULL) {
+ fclose(fp);
+ return (okshells);
+ }
+ shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
+ if (shells == NULL) {
+ fclose(fp);
+ free(strings);
+ strings = NULL;
+ return (okshells);
+ }
+ sp = shells;
+ cp = strings;
+ while (fgets(cp, MaxPathLen + 1, fp) != NULL) {
+ while (*cp != '#' && *cp != '/' && *cp != '\0')
+ cp++;
+ if (*cp == '#' || *cp == '\0')
+ continue;
+ *sp++ = cp;
+ while (!isspace(*cp) && *cp != '#' && *cp != '\0')
+ cp++;
+ *cp++ = '\0';
+ }
+ *sp = NULL;
+ fclose(fp);
+ return (shells);
+}
+#endif /* HAVE_GETUSERSHELL */
diff --git a/crypto/heimdal/lib/roken/glob.c b/crypto/heimdal/lib/roken/glob.c
new file mode 100644
index 000000000000..66e8ec6db8cb
--- /dev/null
+++ b/crypto/heimdal/lib/roken/glob.c
@@ -0,0 +1,835 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+/*
+ * glob(3) -- a superset of the one defined in POSIX 1003.2.
+ *
+ * The [!...] convention to negate a range is supported (SysV, Posix, ksh).
+ *
+ * Optional extra services, controlled by flags not defined by POSIX:
+ *
+ * GLOB_QUOTE:
+ * Escaping convention: \ inhibits any special meaning the following
+ * character might have (except \ at end of string is retained).
+ * GLOB_MAGCHAR:
+ * Set in gl_flags if pattern contained a globbing character.
+ * GLOB_NOMAGIC:
+ * Same as GLOB_NOCHECK, but it will only append pattern if it did
+ * not contain any magic characters. [Used in csh style globbing]
+ * GLOB_ALTDIRFUNC:
+ * Use alternately specified directory access functions.
+ * GLOB_TILDE:
+ * expand ~user/foo to the /home/dir/of/user/foo
+ * GLOB_BRACE:
+ * expand {1,2}{a,b} to 1a 1b 2a 2b
+ * gl_matchc:
+ * Number of matches in the current invocation of glob.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include <ctype.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include <errno.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "glob.h"
+#include "roken.h"
+
+#define CHAR_DOLLAR '$'
+#define CHAR_DOT '.'
+#define CHAR_EOS '\0'
+#define CHAR_LBRACKET '['
+#define CHAR_NOT '!'
+#define CHAR_QUESTION '?'
+#define CHAR_QUOTE '\\'
+#define CHAR_RANGE '-'
+#define CHAR_RBRACKET ']'
+#define CHAR_SEP '/'
+#define CHAR_STAR '*'
+#define CHAR_TILDE '~'
+#define CHAR_UNDERSCORE '_'
+#define CHAR_LBRACE '{'
+#define CHAR_RBRACE '}'
+#define CHAR_SLASH '/'
+#define CHAR_COMMA ','
+
+#ifndef DEBUG
+
+#define M_QUOTE 0x8000
+#define M_PROTECT 0x4000
+#define M_MASK 0xffff
+#define M_ASCII 0x00ff
+
+typedef u_short Char;
+
+#else
+
+#define M_QUOTE 0x80
+#define M_PROTECT 0x40
+#define M_MASK 0xff
+#define M_ASCII 0x7f
+
+typedef char Char;
+
+#endif
+
+
+#define CHAR(c) ((Char)((c)&M_ASCII))
+#define META(c) ((Char)((c)|M_QUOTE))
+#define M_ALL META('*')
+#define M_END META(']')
+#define M_NOT META('!')
+#define M_ONE META('?')
+#define M_RNG META('-')
+#define M_SET META('[')
+#define ismeta(c) (((c)&M_QUOTE) != 0)
+
+
+static int compare (const void *, const void *);
+static void g_Ctoc (const Char *, char *);
+static int g_lstat (Char *, struct stat *, glob_t *);
+static DIR *g_opendir (Char *, glob_t *);
+static Char *g_strchr (Char *, int);
+#ifdef notdef
+static Char *g_strcat (Char *, const Char *);
+#endif
+static int g_stat (Char *, struct stat *, glob_t *);
+static int glob0 (const Char *, glob_t *);
+static int glob1 (Char *, glob_t *);
+static int glob2 (Char *, Char *, Char *, glob_t *);
+static int glob3 (Char *, Char *, Char *, Char *, glob_t *);
+static int globextend (const Char *, glob_t *);
+static const Char * globtilde (const Char *, Char *, glob_t *);
+static int globexp1 (const Char *, glob_t *);
+static int globexp2 (const Char *, const Char *, glob_t *, int *);
+static int match (Char *, Char *, Char *);
+#ifdef DEBUG
+static void qprintf (const char *, Char *);
+#endif
+
+int
+glob(const char *pattern,
+ int flags,
+ int (*errfunc)(const char *, int),
+ glob_t *pglob)
+{
+ const u_char *patnext;
+ int c;
+ Char *bufnext, *bufend, patbuf[MaxPathLen+1];
+
+ patnext = (u_char *) pattern;
+ if (!(flags & GLOB_APPEND)) {
+ pglob->gl_pathc = 0;
+ pglob->gl_pathv = NULL;
+ if (!(flags & GLOB_DOOFFS))
+ pglob->gl_offs = 0;
+ }
+ pglob->gl_flags = flags & ~GLOB_MAGCHAR;
+ pglob->gl_errfunc = errfunc;
+ pglob->gl_matchc = 0;
+
+ bufnext = patbuf;
+ bufend = bufnext + MaxPathLen;
+ if (flags & GLOB_QUOTE) {
+ /* Protect the quoted characters. */
+ while (bufnext < bufend && (c = *patnext++) != CHAR_EOS)
+ if (c == CHAR_QUOTE) {
+ if ((c = *patnext++) == CHAR_EOS) {
+ c = CHAR_QUOTE;
+ --patnext;
+ }
+ *bufnext++ = c | M_PROTECT;
+ }
+ else
+ *bufnext++ = c;
+ }
+ else
+ while (bufnext < bufend && (c = *patnext++) != CHAR_EOS)
+ *bufnext++ = c;
+ *bufnext = CHAR_EOS;
+
+ if (flags & GLOB_BRACE)
+ return globexp1(patbuf, pglob);
+ else
+ return glob0(patbuf, pglob);
+}
+
+/*
+ * Expand recursively a glob {} pattern. When there is no more expansion
+ * invoke the standard globbing routine to glob the rest of the magic
+ * characters
+ */
+static int globexp1(const Char *pattern, glob_t *pglob)
+{
+ const Char* ptr = pattern;
+ int rv;
+
+ /* Protect a single {}, for find(1), like csh */
+ if (pattern[0] == CHAR_LBRACE && pattern[1] == CHAR_RBRACE && pattern[2] == CHAR_EOS)
+ return glob0(pattern, pglob);
+
+ while ((ptr = (const Char *) g_strchr((Char *) ptr, CHAR_LBRACE)) != NULL)
+ if (!globexp2(ptr, pattern, pglob, &rv))
+ return rv;
+
+ return glob0(pattern, pglob);
+}
+
+
+/*
+ * Recursive brace globbing helper. Tries to expand a single brace.
+ * If it succeeds then it invokes globexp1 with the new pattern.
+ * If it fails then it tries to glob the rest of the pattern and returns.
+ */
+static int globexp2(const Char *ptr, const Char *pattern,
+ glob_t *pglob, int *rv)
+{
+ int i;
+ Char *lm, *ls;
+ const Char *pe, *pm, *pl;
+ Char patbuf[MaxPathLen + 1];
+
+ /* copy part up to the brace */
+ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
+ continue;
+ ls = lm;
+
+ /* Find the balanced brace */
+ for (i = 0, pe = ++ptr; *pe; pe++)
+ if (*pe == CHAR_LBRACKET) {
+ /* Ignore everything between [] */
+ for (pm = pe++; *pe != CHAR_RBRACKET && *pe != CHAR_EOS; pe++)
+ continue;
+ if (*pe == CHAR_EOS) {
+ /*
+ * We could not find a matching CHAR_RBRACKET.
+ * Ignore and just look for CHAR_RBRACE
+ */
+ pe = pm;
+ }
+ }
+ else if (*pe == CHAR_LBRACE)
+ i++;
+ else if (*pe == CHAR_RBRACE) {
+ if (i == 0)
+ break;
+ i--;
+ }
+
+ /* Non matching braces; just glob the pattern */
+ if (i != 0 || *pe == CHAR_EOS) {
+ *rv = glob0(patbuf, pglob);
+ return 0;
+ }
+
+ for (i = 0, pl = pm = ptr; pm <= pe; pm++)
+ switch (*pm) {
+ case CHAR_LBRACKET:
+ /* Ignore everything between [] */
+ for (pl = pm++; *pm != CHAR_RBRACKET && *pm != CHAR_EOS; pm++)
+ continue;
+ if (*pm == CHAR_EOS) {
+ /*
+ * We could not find a matching CHAR_RBRACKET.
+ * Ignore and just look for CHAR_RBRACE
+ */
+ pm = pl;
+ }
+ break;
+
+ case CHAR_LBRACE:
+ i++;
+ break;
+
+ case CHAR_RBRACE:
+ if (i) {
+ i--;
+ break;
+ }
+ /* FALLTHROUGH */
+ case CHAR_COMMA:
+ if (i && *pm == CHAR_COMMA)
+ break;
+ else {
+ /* Append the current string */
+ for (lm = ls; (pl < pm); *lm++ = *pl++)
+ continue;
+ /*
+ * Append the rest of the pattern after the
+ * closing brace
+ */
+ for (pl = pe + 1; (*lm++ = *pl++) != CHAR_EOS;)
+ continue;
+
+ /* Expand the current pattern */
+#ifdef DEBUG
+ qprintf("globexp2:", patbuf);
+#endif
+ *rv = globexp1(patbuf, pglob);
+
+ /* move after the comma, to the next string */
+ pl = pm + 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ *rv = 0;
+ return 0;
+}
+
+
+
+/*
+ * expand tilde from the passwd file.
+ */
+static const Char *
+globtilde(const Char *pattern, Char *patbuf, glob_t *pglob)
+{
+ struct passwd *pwd;
+ char *h;
+ const Char *p;
+ Char *b;
+
+ if (*pattern != CHAR_TILDE || !(pglob->gl_flags & GLOB_TILDE))
+ return pattern;
+
+ /* Copy up to the end of the string or / */
+ for (p = pattern + 1, h = (char *) patbuf; *p && *p != CHAR_SLASH;
+ *h++ = *p++)
+ continue;
+
+ *h = CHAR_EOS;
+
+ if (((char *) patbuf)[0] == CHAR_EOS) {
+ /*
+ * handle a plain ~ or ~/ by expanding $HOME
+ * first and then trying the password file
+ */
+ if ((h = getenv("HOME")) == NULL) {
+ if ((pwd = k_getpwuid(getuid())) == NULL)
+ return pattern;
+ else
+ h = pwd->pw_dir;
+ }
+ }
+ else {
+ /*
+ * Expand a ~user
+ */
+ if ((pwd = k_getpwnam((char*) patbuf)) == NULL)
+ return pattern;
+ else
+ h = pwd->pw_dir;
+ }
+
+ /* Copy the home directory */
+ for (b = patbuf; *h; *b++ = *h++)
+ continue;
+
+ /* Append the rest of the pattern */
+ while ((*b++ = *p++) != CHAR_EOS)
+ continue;
+
+ return patbuf;
+}
+
+
+/*
+ * The main glob() routine: compiles the pattern (optionally processing
+ * quotes), calls glob1() to do the real pattern matching, and finally
+ * sorts the list (unless unsorted operation is requested). Returns 0
+ * if things went well, nonzero if errors occurred. It is not an error
+ * to find no matches.
+ */
+static int
+glob0(const Char *pattern, glob_t *pglob)
+{
+ const Char *qpatnext;
+ int c, err, oldpathc;
+ Char *bufnext, patbuf[MaxPathLen+1];
+
+ qpatnext = globtilde(pattern, patbuf, pglob);
+ oldpathc = pglob->gl_pathc;
+ bufnext = patbuf;
+
+ /* We don't need to check for buffer overflow any more. */
+ while ((c = *qpatnext++) != CHAR_EOS) {
+ switch (c) {
+ case CHAR_LBRACKET:
+ c = *qpatnext;
+ if (c == CHAR_NOT)
+ ++qpatnext;
+ if (*qpatnext == CHAR_EOS ||
+ g_strchr((Char *) qpatnext+1, CHAR_RBRACKET) == NULL) {
+ *bufnext++ = CHAR_LBRACKET;
+ if (c == CHAR_NOT)
+ --qpatnext;
+ break;
+ }
+ *bufnext++ = M_SET;
+ if (c == CHAR_NOT)
+ *bufnext++ = M_NOT;
+ c = *qpatnext++;
+ do {
+ *bufnext++ = CHAR(c);
+ if (*qpatnext == CHAR_RANGE &&
+ (c = qpatnext[1]) != CHAR_RBRACKET) {
+ *bufnext++ = M_RNG;
+ *bufnext++ = CHAR(c);
+ qpatnext += 2;
+ }
+ } while ((c = *qpatnext++) != CHAR_RBRACKET);
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ *bufnext++ = M_END;
+ break;
+ case CHAR_QUESTION:
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ *bufnext++ = M_ONE;
+ break;
+ case CHAR_STAR:
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ /* collapse adjacent stars to one,
+ * to avoid exponential behavior
+ */
+ if (bufnext == patbuf || bufnext[-1] != M_ALL)
+ *bufnext++ = M_ALL;
+ break;
+ default:
+ *bufnext++ = CHAR(c);
+ break;
+ }
+ }
+ *bufnext = CHAR_EOS;
+#ifdef DEBUG
+ qprintf("glob0:", patbuf);
+#endif
+
+ if ((err = glob1(patbuf, pglob)) != 0)
+ return(err);
+
+ /*
+ * If there was no match we are going to append the pattern
+ * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
+ * and the pattern did not contain any magic characters
+ * GLOB_NOMAGIC is there just for compatibility with csh.
+ */
+ if (pglob->gl_pathc == oldpathc &&
+ ((pglob->gl_flags & GLOB_NOCHECK) ||
+ ((pglob->gl_flags & GLOB_NOMAGIC) &&
+ !(pglob->gl_flags & GLOB_MAGCHAR))))
+ return(globextend(pattern, pglob));
+ else if (!(pglob->gl_flags & GLOB_NOSORT))
+ qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
+ pglob->gl_pathc - oldpathc, sizeof(char *), compare);
+ return(0);
+}
+
+static int
+compare(const void *p, const void *q)
+{
+ return(strcmp(*(char **)p, *(char **)q));
+}
+
+static int
+glob1(Char *pattern, glob_t *pglob)
+{
+ Char pathbuf[MaxPathLen+1];
+
+ /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
+ if (*pattern == CHAR_EOS)
+ return(0);
+ return(glob2(pathbuf, pathbuf, pattern, pglob));
+}
+
+/*
+ * The functions glob2 and glob3 are mutually recursive; there is one level
+ * of recursion for each segment in the pattern that contains one or more
+ * meta characters.
+ */
+
+#ifndef S_ISLNK
+#if defined(S_IFLNK) && defined(S_IFMT)
+#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
+#else
+#define S_ISLNK(mode) 0
+#endif
+#endif
+
+static int
+glob2(Char *pathbuf, Char *pathend, Char *pattern, glob_t *pglob)
+{
+ struct stat sb;
+ Char *p, *q;
+ int anymeta;
+
+ /*
+ * Loop over pattern segments until end of pattern or until
+ * segment with meta character found.
+ */
+ for (anymeta = 0;;) {
+ if (*pattern == CHAR_EOS) { /* End of pattern? */
+ *pathend = CHAR_EOS;
+ if (g_lstat(pathbuf, &sb, pglob))
+ return(0);
+
+ if (((pglob->gl_flags & GLOB_MARK) &&
+ pathend[-1] != CHAR_SEP) && (S_ISDIR(sb.st_mode)
+ || (S_ISLNK(sb.st_mode) &&
+ (g_stat(pathbuf, &sb, pglob) == 0) &&
+ S_ISDIR(sb.st_mode)))) {
+ *pathend++ = CHAR_SEP;
+ *pathend = CHAR_EOS;
+ }
+ ++pglob->gl_matchc;
+ return(globextend(pathbuf, pglob));
+ }
+
+ /* Find end of next segment, copy tentatively to pathend. */
+ q = pathend;
+ p = pattern;
+ while (*p != CHAR_EOS && *p != CHAR_SEP) {
+ if (ismeta(*p))
+ anymeta = 1;
+ *q++ = *p++;
+ }
+
+ if (!anymeta) { /* No expansion, do next segment. */
+ pathend = q;
+ pattern = p;
+ while (*pattern == CHAR_SEP)
+ *pathend++ = *pattern++;
+ } else /* Need expansion, recurse. */
+ return(glob3(pathbuf, pathend, pattern, p, pglob));
+ }
+ /* CHAR_NOTREACHED */
+}
+
+static int
+glob3(Char *pathbuf, Char *pathend, Char *pattern, Char *restpattern,
+ glob_t *pglob)
+{
+ struct dirent *dp;
+ DIR *dirp;
+ int err;
+ char buf[MaxPathLen];
+
+ /*
+ * The readdirfunc declaration can't be prototyped, because it is
+ * assigned, below, to two functions which are prototyped in glob.h
+ * and dirent.h as taking pointers to differently typed opaque
+ * structures.
+ */
+ struct dirent *(*readdirfunc)(void *);
+
+ *pathend = CHAR_EOS;
+ errno = 0;
+
+ if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
+ /* TODO: don't call for ENOENT or ENOTDIR? */
+ if (pglob->gl_errfunc) {
+ g_Ctoc(pathbuf, buf);
+ if (pglob->gl_errfunc(buf, errno) ||
+ pglob->gl_flags & GLOB_ERR)
+ return (GLOB_ABEND);
+ }
+ return(0);
+ }
+
+ err = 0;
+
+ /* Search directory for matching names. */
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ readdirfunc = pglob->gl_readdir;
+ else
+ readdirfunc = (struct dirent *(*)(void *))readdir;
+ while ((dp = (*readdirfunc)(dirp))) {
+ u_char *sc;
+ Char *dc;
+
+ /* Initial CHAR_DOT must be matched literally. */
+ if (dp->d_name[0] == CHAR_DOT && *pattern != CHAR_DOT)
+ continue;
+ for (sc = (u_char *) dp->d_name, dc = pathend;
+ (*dc++ = *sc++) != CHAR_EOS;)
+ continue;
+ if (!match(pathend, pattern, restpattern)) {
+ *pathend = CHAR_EOS;
+ continue;
+ }
+ err = glob2(pathbuf, --dc, restpattern, pglob);
+ if (err)
+ break;
+ }
+
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ (*pglob->gl_closedir)(dirp);
+ else
+ closedir(dirp);
+ return(err);
+}
+
+
+/*
+ * Extend the gl_pathv member of a glob_t structure to accomodate a new item,
+ * add the new item, and update gl_pathc.
+ *
+ * This assumes the BSD realloc, which only copies the block when its size
+ * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
+ * behavior.
+ *
+ * Return 0 if new item added, error code if memory couldn't be allocated.
+ *
+ * Invariant of the glob_t structure:
+ * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
+ * gl_pathv points to (gl_offs + gl_pathc + 1) items.
+ */
+static int
+globextend(const Char *path, glob_t *pglob)
+{
+ char **pathv;
+ int i;
+ u_int newsize;
+ char *copy;
+ const Char *p;
+
+ newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
+ pathv = pglob->gl_pathv ?
+ realloc(pglob->gl_pathv, newsize) :
+ malloc(newsize);
+ if (pathv == NULL)
+ return(GLOB_NOSPACE);
+
+ if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
+ /* first time around -- clear initial gl_offs items */
+ pathv += pglob->gl_offs;
+ for (i = pglob->gl_offs; --i >= 0; )
+ *--pathv = NULL;
+ }
+ pglob->gl_pathv = pathv;
+
+ for (p = path; *p++;)
+ continue;
+ if ((copy = malloc(p - path)) != NULL) {
+ g_Ctoc(path, copy);
+ pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
+ }
+ pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
+ return(copy == NULL ? GLOB_NOSPACE : 0);
+}
+
+
+/*
+ * pattern matching function for filenames. Each occurrence of the *
+ * pattern causes a recursion level.
+ */
+static int
+match(Char *name, Char *pat, Char *patend)
+{
+ int ok, negate_range;
+ Char c, k;
+
+ while (pat < patend) {
+ c = *pat++;
+ switch (c & M_MASK) {
+ case M_ALL:
+ if (pat == patend)
+ return(1);
+ do
+ if (match(name, pat, patend))
+ return(1);
+ while (*name++ != CHAR_EOS);
+ return(0);
+ case M_ONE:
+ if (*name++ == CHAR_EOS)
+ return(0);
+ break;
+ case M_SET:
+ ok = 0;
+ if ((k = *name++) == CHAR_EOS)
+ return(0);
+ if ((negate_range = ((*pat & M_MASK) == M_NOT)) != CHAR_EOS)
+ ++pat;
+ while (((c = *pat++) & M_MASK) != M_END)
+ if ((*pat & M_MASK) == M_RNG) {
+ if (c <= k && k <= pat[1])
+ ok = 1;
+ pat += 2;
+ } else if (c == k)
+ ok = 1;
+ if (ok == negate_range)
+ return(0);
+ break;
+ default:
+ if (*name++ != c)
+ return(0);
+ break;
+ }
+ }
+ return(*name == CHAR_EOS);
+}
+
+/* Free allocated data belonging to a glob_t structure. */
+void
+globfree(glob_t *pglob)
+{
+ int i;
+ char **pp;
+
+ if (pglob->gl_pathv != NULL) {
+ pp = pglob->gl_pathv + pglob->gl_offs;
+ for (i = pglob->gl_pathc; i--; ++pp)
+ if (*pp)
+ free(*pp);
+ free(pglob->gl_pathv);
+ }
+}
+
+static DIR *
+g_opendir(Char *str, glob_t *pglob)
+{
+ char buf[MaxPathLen];
+
+ if (!*str)
+ strlcpy(buf, ".", sizeof(buf));
+ else
+ g_Ctoc(str, buf);
+
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_opendir)(buf));
+
+ return(opendir(buf));
+}
+
+static int
+g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
+{
+ char buf[MaxPathLen];
+
+ g_Ctoc(fn, buf);
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_lstat)(buf, sb));
+ return(lstat(buf, sb));
+}
+
+static int
+g_stat(Char *fn, struct stat *sb, glob_t *pglob)
+{
+ char buf[MaxPathLen];
+
+ g_Ctoc(fn, buf);
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_stat)(buf, sb));
+ return(stat(buf, sb));
+}
+
+static Char *
+g_strchr(Char *str, int ch)
+{
+ do {
+ if (*str == ch)
+ return (str);
+ } while (*str++);
+ return (NULL);
+}
+
+#ifdef notdef
+static Char *
+g_strcat(Char *dst, const Char *src)
+{
+ Char *sdst = dst;
+
+ while (*dst++)
+ continue;
+ --dst;
+ while((*dst++ = *src++) != CHAR_EOS)
+ continue;
+
+ return (sdst);
+}
+#endif
+
+static void
+g_Ctoc(const Char *str, char *buf)
+{
+ char *dc;
+
+ for (dc = buf; (*dc++ = *str++) != CHAR_EOS;)
+ continue;
+}
+
+#ifdef DEBUG
+static void
+qprintf(const Char *str, Char *s)
+{
+ Char *p;
+
+ printf("%s:\n", str);
+ for (p = s; *p; p++)
+ printf("%c", CHAR(*p));
+ printf("\n");
+ for (p = s; *p; p++)
+ printf("%c", *p & M_PROTECT ? '"' : ' ');
+ printf("\n");
+ for (p = s; *p; p++)
+ printf("%c", ismeta(*p) ? '_' : ' ');
+ printf("\n");
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/glob.h b/crypto/heimdal/lib/roken/glob.h
new file mode 100644
index 000000000000..bece48a89cd7
--- /dev/null
+++ b/crypto/heimdal/lib/roken/glob.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)glob.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _GLOB_H_
+#define _GLOB_H_
+
+struct stat;
+typedef struct {
+ int gl_pathc; /* Count of total paths so far. */
+ int gl_matchc; /* Count of paths matching pattern. */
+ int gl_offs; /* Reserved at beginning of gl_pathv. */
+ int gl_flags; /* Copy of flags parameter to glob. */
+ char **gl_pathv; /* List of paths matching pattern. */
+ /* Copy of errfunc parameter to glob. */
+ int (*gl_errfunc) (const char *, int);
+
+ /*
+ * Alternate filesystem access methods for glob; replacement
+ * versions of closedir(3), readdir(3), opendir(3), stat(2)
+ * and lstat(2).
+ */
+ void (*gl_closedir) (void *);
+ struct dirent *(*gl_readdir) (void *);
+ void *(*gl_opendir) (const char *);
+ int (*gl_lstat) (const char *, struct stat *);
+ int (*gl_stat) (const char *, struct stat *);
+} glob_t;
+
+#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
+#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
+#define GLOB_ERR 0x0004 /* Return on error. */
+#define GLOB_MARK 0x0008 /* Append / to matching directories. */
+#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
+#define GLOB_NOSORT 0x0020 /* Don't sort. */
+
+#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
+#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
+#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
+#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
+#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
+#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
+
+#define GLOB_NOSPACE (-1) /* Malloc call failed. */
+#define GLOB_ABEND (-2) /* Unignored error. */
+
+int glob (const char *, int, int (*)(const char *, int), glob_t *);
+void globfree (glob_t *);
+
+#endif /* !_GLOB_H_ */
diff --git a/crypto/heimdal/lib/roken/hstrerror.c b/crypto/heimdal/lib/roken/hstrerror.c
new file mode 100644
index 000000000000..11b6a03891fc
--- /dev/null
+++ b/crypto/heimdal/lib/roken/hstrerror.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: hstrerror.c,v 1.23 1999/12/05 13:18:55 assar Exp $");
+#endif
+
+#ifndef HAVE_HSTRERROR
+
+#if (defined(SunOS) && (SunOS >= 50))
+#define hstrerror broken_proto
+#endif
+#include "roken.h"
+#if (defined(SunOS) && (SunOS >= 50))
+#undef hstrerror
+#endif
+
+#ifndef HAVE_H_ERRNO
+int h_errno = -17; /* Some magic number */
+#endif
+
+#if !(defined(HAVE_H_ERRLIST) && defined(HAVE_H_NERR))
+static const char *const h_errlist[] = {
+ "Resolver Error 0 (no error)",
+ "Unknown host", /* 1 HOST_NOT_FOUND */
+ "Host name lookup failure", /* 2 TRY_AGAIN */
+ "Unknown server error", /* 3 NO_RECOVERY */
+ "No address associated with name", /* 4 NO_ADDRESS */
+};
+
+static
+const
+int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
+#else
+
+#ifndef HAVE_H_ERRLIST_DECLARATION
+extern const char *h_errlist[];
+extern int h_nerr;
+#endif
+
+#endif
+
+const char *
+hstrerror(int herr)
+{
+ if (0 <= herr && herr < h_nerr)
+ return h_errlist[herr];
+ else if(herr == -17)
+ return "unknown error";
+ else
+ return "Error number out of range (hstrerror)";
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/inet_aton.c b/crypto/heimdal/lib/roken/inet_aton.c
new file mode 100644
index 000000000000..cdc6bdd4ed8e
--- /dev/null
+++ b/crypto/heimdal/lib/roken/inet_aton.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: inet_aton.c,v 1.13 1999/12/05 13:26:20 assar Exp $");
+#endif
+
+#include "roken.h"
+
+/* Minimal implementation of inet_aton.
+ * Cannot distinguish between failure and a local broadcast address. */
+
+int
+inet_aton(const char *cp, struct in_addr *addr)
+{
+ addr->s_addr = inet_addr(cp);
+ return (addr->s_addr == INADDR_NONE) ? 0 : 1;
+}
diff --git a/crypto/heimdal/lib/roken/inet_ntop.c b/crypto/heimdal/lib/roken/inet_ntop.c
new file mode 100644
index 000000000000..f79a35eb334b
--- /dev/null
+++ b/crypto/heimdal/lib/roken/inet_ntop.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: inet_ntop.c,v 1.3 1999/12/02 16:58:47 joda Exp $");
+#endif
+
+#include <errno.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#include <roken.h>
+
+/*
+ *
+ */
+
+static const char *
+inet_ntop_v4 (const void *src, char *dst, size_t size)
+{
+ const char digits[] = "0123456789";
+ int i;
+ struct in_addr *addr = (struct in_addr *)src;
+ u_long a = ntohl(addr->s_addr);
+ const char *orig_dst = dst;
+
+ if (size < INET_ADDRSTRLEN) {
+ errno = ENOSPC;
+ return NULL;
+ }
+ for (i = 0; i < 4; ++i) {
+ int n = (a >> (24 - i * 8)) & 0xFF;
+ int non_zerop = 0;
+
+ if (non_zerop || n / 100 > 0) {
+ *dst++ = digits[n / 100];
+ n %= 100;
+ non_zerop = 1;
+ }
+ if (non_zerop || n / 10 > 0) {
+ *dst++ = digits[n / 10];
+ n %= 10;
+ non_zerop = 1;
+ }
+ *dst++ = digits[n];
+ if (i != 3)
+ *dst++ = '.';
+ }
+ *dst++ = '\0';
+ return orig_dst;
+}
+
+#ifdef HAVE_IPV6
+static const char *
+inet_ntop_v6 (const void *src, char *dst, size_t size)
+{
+ const char xdigits[] = "0123456789abcdef";
+ int i;
+ const struct in6_addr *addr = (struct in6_addr *)src;
+ const u_char *ptr = addr->s6_addr;
+ const char *orig_dst = dst;
+
+ if (size < INET6_ADDRSTRLEN) {
+ errno = ENOSPC;
+ return NULL;
+ }
+ for (i = 0; i < 8; ++i) {
+ int non_zerop = 1;
+
+ if (non_zerop || (ptr[0] >> 4)) {
+ *dst++ = xdigits[ptr[0] >> 4];
+ non_zerop = 1;
+ }
+ if (non_zerop || (ptr[0] & 0x0F)) {
+ *dst++ = xdigits[ptr[0] & 0x0F];
+ non_zerop = 1;
+ }
+ if (non_zerop || (ptr[1] >> 4)) {
+ *dst++ = xdigits[ptr[1] >> 4];
+ non_zerop = 1;
+ }
+ if (non_zerop || (ptr[1] & 0x0F)) {
+ *dst++ = xdigits[ptr[1] & 0x0F];
+ non_zerop = 1;
+ }
+ if (i != 7)
+ *dst++ = ':';
+ ptr += 2;
+ }
+ *dst++ = '\0';
+ return orig_dst;
+}
+#endif /* HAVE_IPV6 */
+
+const char *
+inet_ntop(int af, const void *src, char *dst, size_t size)
+{
+ switch (af) {
+ case AF_INET :
+ return inet_ntop_v4 (src, dst, size);
+#ifdef HAVE_IPV6
+ case AF_INET6 :
+ return inet_ntop_v6 (src, dst, size);
+#endif
+ default :
+ errno = EAFNOSUPPORT;
+ return NULL;
+ }
+}
diff --git a/crypto/heimdal/lib/roken/inet_pton.c b/crypto/heimdal/lib/roken/inet_pton.c
new file mode 100644
index 000000000000..9b195c23dafc
--- /dev/null
+++ b/crypto/heimdal/lib/roken/inet_pton.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: inet_pton.c,v 1.2 1999/12/02 16:58:47 joda Exp $");
+#endif
+
+#include <errno.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#include <roken.h>
+
+int
+inet_pton(int af, const char *src, void *dst)
+{
+ if (af != AF_INET) {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+ return inet_aton (src, dst);
+}
diff --git a/crypto/heimdal/lib/roken/initgroups.c b/crypto/heimdal/lib/roken/initgroups.c
new file mode 100644
index 000000000000..dcf1d08e968f
--- /dev/null
+++ b/crypto/heimdal/lib/roken/initgroups.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: initgroups.c,v 1.3 1999/12/02 16:58:47 joda Exp $");
+#endif
+
+#include "roken.h"
+
+int
+initgroups(const char *name, gid_t basegid)
+{
+ return 0;
+}
diff --git a/crypto/heimdal/lib/roken/innetgr.c b/crypto/heimdal/lib/roken/innetgr.c
new file mode 100644
index 000000000000..4bc57f93e566
--- /dev/null
+++ b/crypto/heimdal/lib/roken/innetgr.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+#ifndef HAVE_INNETGR
+
+RCSID("$Id: innetgr.c,v 1.1 1999/03/11 14:04:01 joda Exp $");
+
+int
+innetgr(const char *netgroup, const char *machine,
+ const char *user, const char *domain)
+{
+ return 0;
+}
+#endif
+
diff --git a/crypto/heimdal/lib/roken/iruserok.c b/crypto/heimdal/lib/roken/iruserok.c
new file mode 100644
index 000000000000..3b3880bf3955
--- /dev/null
+++ b/crypto/heimdal/lib/roken/iruserok.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 1983, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: iruserok.c,v 1.23 1999/12/05 13:27:05 assar Exp $");
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+#ifdef HAVE_RPCSVC_YPCLNT_H
+#include <rpcsvc/ypclnt.h>
+#endif
+
+#include "roken.h"
+
+int __check_rhosts_file = 1;
+char *__rcmd_errstr = 0;
+
+/*
+ * Returns "true" if match, 0 if no match.
+ */
+static
+int
+__icheckhost(unsigned raddr, const char *lhost)
+{
+ struct hostent *hp;
+ u_long laddr;
+ char **pp;
+
+ /* Try for raw ip address first. */
+ if (isdigit((unsigned char)*lhost)
+ && (long)(laddr = inet_addr(lhost)) != -1)
+ return (raddr == laddr);
+
+ /* Better be a hostname. */
+ if ((hp = gethostbyname(lhost)) == NULL)
+ return (0);
+
+ /* Spin through ip addresses. */
+ for (pp = hp->h_addr_list; *pp; ++pp)
+ if (memcmp(&raddr, *pp, sizeof(u_long)) == 0)
+ return (1);
+
+ /* No match. */
+ return (0);
+}
+
+/*
+ * Returns 0 if ok, -1 if not ok.
+ */
+static
+int
+__ivaliduser(FILE *hostf, unsigned raddr, const char *luser,
+ const char *ruser)
+{
+ char *user, *p;
+ int ch;
+ char buf[MaxHostNameLen + 128]; /* host + login */
+ char hname[MaxHostNameLen];
+ struct hostent *hp;
+ /* Presumed guilty until proven innocent. */
+ int userok = 0, hostok = 0;
+#ifdef HAVE_YP_GET_DEFAULT_DOMAIN
+ char *ypdomain;
+
+ if (yp_get_default_domain(&ypdomain))
+ ypdomain = NULL;
+#else
+#define ypdomain NULL
+#endif
+ /* We need to get the damn hostname back for netgroup matching. */
+ if ((hp = gethostbyaddr((char *)&raddr,
+ sizeof(u_long),
+ AF_INET)) == NULL)
+ return (-1);
+ strlcpy(hname, hp->h_name, sizeof(hname));
+
+ while (fgets(buf, sizeof(buf), hostf)) {
+ p = buf;
+ /* Skip lines that are too long. */
+ if (strchr(p, '\n') == NULL) {
+ while ((ch = getc(hostf)) != '\n' && ch != EOF);
+ continue;
+ }
+ if (*p == '\n' || *p == '#') {
+ /* comment... */
+ continue;
+ }
+ while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
+ if (isupper((unsigned char)*p))
+ *p = tolower((unsigned char)*p);
+ p++;
+ }
+ if (*p == ' ' || *p == '\t') {
+ *p++ = '\0';
+ while (*p == ' ' || *p == '\t')
+ p++;
+ user = p;
+ while (*p != '\n' && *p != ' ' &&
+ *p != '\t' && *p != '\0')
+ p++;
+ } else
+ user = p;
+ *p = '\0';
+ /*
+ * Do +/- and +@/-@ checking. This looks really nasty,
+ * but it matches SunOS's behavior so far as I can tell.
+ */
+ switch(buf[0]) {
+ case '+':
+ if (!buf[1]) { /* '+' matches all hosts */
+ hostok = 1;
+ break;
+ }
+ if (buf[1] == '@') /* match a host by netgroup */
+ hostok = innetgr((char *)&buf[2],
+ (char *)&hname, NULL, ypdomain);
+ else /* match a host by addr */
+ hostok = __icheckhost(raddr,(char *)&buf[1]);
+ break;
+ case '-': /* reject '-' hosts and all their users */
+ if (buf[1] == '@') {
+ if (innetgr((char *)&buf[2],
+ (char *)&hname, NULL, ypdomain))
+ return(-1);
+ } else {
+ if (__icheckhost(raddr,(char *)&buf[1]))
+ return(-1);
+ }
+ break;
+ default: /* if no '+' or '-', do a simple match */
+ hostok = __icheckhost(raddr, buf);
+ break;
+ }
+ switch(*user) {
+ case '+':
+ if (!*(user+1)) { /* '+' matches all users */
+ userok = 1;
+ break;
+ }
+ if (*(user+1) == '@') /* match a user by netgroup */
+ userok = innetgr(user+2, NULL, (char *)ruser,
+ ypdomain);
+ else /* match a user by direct specification */
+ userok = !(strcmp(ruser, user+1));
+ break;
+ case '-': /* if we matched a hostname, */
+ if (hostok) { /* check for user field rejections */
+ if (!*(user+1))
+ return(-1);
+ if (*(user+1) == '@') {
+ if (innetgr(user+2, NULL,
+ (char *)ruser, ypdomain))
+ return(-1);
+ } else {
+ if (!strcmp(ruser, user+1))
+ return(-1);
+ }
+ }
+ break;
+ default: /* no rejections: try to match the user */
+ if (hostok)
+ userok = !(strcmp(ruser,*user ? user : luser));
+ break;
+ }
+ if (hostok && userok)
+ return(0);
+ }
+ return (-1);
+}
+
+/*
+ * New .rhosts strategy: We are passed an ip address. We spin through
+ * hosts.equiv and .rhosts looking for a match. When the .rhosts only
+ * has ip addresses, we don't have to trust a nameserver. When it
+ * contains hostnames, we spin through the list of addresses the nameserver
+ * gives us and look for a match.
+ *
+ * Returns 0 if ok, -1 if not ok.
+ */
+int
+iruserok(unsigned raddr, int superuser, const char *ruser, const char *luser)
+{
+ char *cp;
+ struct stat sbuf;
+ struct passwd *pwd;
+ FILE *hostf;
+ uid_t uid;
+ int first;
+ char pbuf[MaxPathLen];
+
+ first = 1;
+ hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
+again:
+ if (hostf) {
+ if (__ivaliduser(hostf, raddr, luser, ruser) == 0) {
+ fclose(hostf);
+ return (0);
+ }
+ fclose(hostf);
+ }
+ if (first == 1 && (__check_rhosts_file || superuser)) {
+ first = 0;
+ if ((pwd = k_getpwnam((char*)luser)) == NULL)
+ return (-1);
+ snprintf (pbuf, sizeof(pbuf), "%s/.rhosts", pwd->pw_dir);
+
+ /*
+ * Change effective uid while opening .rhosts. If root and
+ * reading an NFS mounted file system, can't read files that
+ * are protected read/write owner only.
+ */
+ uid = geteuid();
+ seteuid(pwd->pw_uid);
+ hostf = fopen(pbuf, "r");
+ seteuid(uid);
+
+ if (hostf == NULL)
+ return (-1);
+ /*
+ * If not a regular file, or is owned by someone other than
+ * user or root or if writeable by anyone but the owner, quit.
+ */
+ cp = NULL;
+ if (lstat(pbuf, &sbuf) < 0)
+ cp = ".rhosts lstat failed";
+ else if (!S_ISREG(sbuf.st_mode))
+ cp = ".rhosts not regular file";
+ else if (fstat(fileno(hostf), &sbuf) < 0)
+ cp = ".rhosts fstat failed";
+ else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
+ cp = "bad .rhosts owner";
+ else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
+ cp = ".rhosts writeable by other than owner";
+ /* If there were any problems, quit. */
+ if (cp) {
+ __rcmd_errstr = cp;
+ fclose(hostf);
+ return (-1);
+ }
+ goto again;
+ }
+ return (-1);
+}
diff --git a/crypto/heimdal/lib/roken/issuid.c b/crypto/heimdal/lib/roken/issuid.c
new file mode 100644
index 000000000000..af2aae542875
--- /dev/null
+++ b/crypto/heimdal/lib/roken/issuid.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: issuid.c,v 1.3 1999/12/02 16:58:47 joda Exp $");
+#endif
+
+#include "roken.h"
+
+int
+issuid(void)
+{
+#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
+ if(getuid() != geteuid())
+ return 1;
+#endif
+#if defined(HAVE_GETGID) && defined(HAVE_GETEGID)
+ if(getgid() != getegid())
+ return 2;
+#endif
+ return 0;
+}
diff --git a/crypto/heimdal/lib/roken/k_getpwnam.c b/crypto/heimdal/lib/roken/k_getpwnam.c
new file mode 100644
index 000000000000..40681cd2d01b
--- /dev/null
+++ b/crypto/heimdal/lib/roken/k_getpwnam.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: k_getpwnam.c,v 1.9 1999/12/02 16:58:47 joda Exp $");
+#endif /* HAVE_CONFIG_H */
+
+#include "roken.h"
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+
+struct passwd *
+k_getpwnam (const char *user)
+{
+ struct passwd *p;
+
+ p = getpwnam (user);
+#if defined(HAVE_GETSPNAM) && defined(HAVE_STRUCT_SPWD)
+ if(p)
+ {
+ struct spwd *spwd;
+
+ spwd = getspnam (user);
+ if (spwd)
+ p->pw_passwd = spwd->sp_pwdp;
+ endspent ();
+ }
+#else
+ endpwent ();
+#endif
+ return p;
+}
diff --git a/crypto/heimdal/lib/roken/k_getpwuid.c b/crypto/heimdal/lib/roken/k_getpwuid.c
new file mode 100644
index 000000000000..1e2ca5476fe4
--- /dev/null
+++ b/crypto/heimdal/lib/roken/k_getpwuid.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: k_getpwuid.c,v 1.9 1999/12/02 16:58:47 joda Exp $");
+#endif /* HAVE_CONFIG_H */
+
+#include "roken.h"
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+
+struct passwd *
+k_getpwuid (uid_t uid)
+{
+ struct passwd *p;
+
+ p = getpwuid (uid);
+#if defined(HAVE_GETSPNAM) && defined(HAVE_STRUCT_SPWD)
+ if (p)
+ {
+ struct spwd *spwd;
+
+ spwd = getspnam (p->pw_name);
+ if (spwd)
+ p->pw_passwd = spwd->sp_pwdp;
+ endspent ();
+ }
+#else
+ endpwent ();
+#endif
+ return p;
+}
diff --git a/crypto/heimdal/lib/roken/lstat.c b/crypto/heimdal/lib/roken/lstat.c
new file mode 100644
index 000000000000..2f03e19d18f1
--- /dev/null
+++ b/crypto/heimdal/lib/roken/lstat.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: lstat.c,v 1.4 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+#include "roken.h"
+
+int
+lstat(const char *path, struct stat *buf)
+{
+ return stat(path, buf);
+}
diff --git a/crypto/heimdal/lib/roken/make-print-version.c b/crypto/heimdal/lib/roken/make-print-version.c
new file mode 100644
index 000000000000..d08e023da950
--- /dev/null
+++ b/crypto/heimdal/lib/roken/make-print-version.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: make-print-version.c,v 1.2 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+#include <stdio.h>
+
+#ifdef KRB5
+extern char *heimdal_version;
+#endif
+#ifdef KRB4
+extern char *krb4_version;
+#endif
+#include <version.h>
+
+int
+main(int argc, char **argv)
+{
+ FILE *f;
+ if(argc != 2)
+ return 1;
+ f = fopen(argv[1], "w");
+ if(f == NULL)
+ return 1;
+ fprintf(f, "#define VERSIONLIST { ");
+#ifdef KRB5
+ fprintf(f, "\"%s\", ", heimdal_version);
+#endif
+#ifdef KRB4
+ fprintf(f, "\"%s\", ", krb4_version);
+#endif
+ fprintf(f, "}\n");
+ fclose(f);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/roken/memmove.c b/crypto/heimdal/lib/roken/memmove.c
new file mode 100644
index 000000000000..b77d56af9616
--- /dev/null
+++ b/crypto/heimdal/lib/roken/memmove.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: memmove.c,v 1.7 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+/*
+ * memmove for systems that doesn't have it
+ */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+void* memmove(void *s1, const void *s2, size_t n)
+{
+ char *s=(char*)s2, *d=(char*)s1;
+
+ if(d > s){
+ s+=n-1;
+ d+=n-1;
+ while(n){
+ *d--=*s--;
+ n--;
+ }
+ }else if(d < s)
+ while(n){
+ *d++=*s++;
+ n--;
+ }
+ return s1;
+}
diff --git a/crypto/heimdal/lib/roken/mini_inetd.c b/crypto/heimdal/lib/roken/mini_inetd.c
new file mode 100644
index 000000000000..e92dac3d2194
--- /dev/null
+++ b/crypto/heimdal/lib/roken/mini_inetd.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: mini_inetd.c,v 1.21 1999/12/12 00:03:56 assar Exp $");
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#include <err.h>
+#include <roken.h>
+
+/*
+ * accept a connection on `s' and pretend it's served by inetd.
+ */
+
+static void
+accept_it (int s)
+{
+ int s2;
+
+ s2 = accept(s, NULL, 0);
+ if(s2 < 0)
+ err (1, "accept");
+ close(s);
+ dup2(s2, STDIN_FILENO);
+ dup2(s2, STDOUT_FILENO);
+ /* dup2(s2, STDERR_FILENO); */
+ close(s2);
+}
+
+/*
+ * Listen on `port' emulating inetd.
+ */
+
+void
+mini_inetd (int port)
+{
+ int error, ret;
+ struct addrinfo *ai, *a, hints;
+ char portstr[NI_MAXSERV];
+ int n, i;
+ int *fds;
+ fd_set orig_read_set, read_set;
+ int max_fd = -1;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_socktype = SOCK_STREAM;
+
+ snprintf (portstr, sizeof(portstr), "%d", ntohs(port));
+
+ error = getaddrinfo (NULL, portstr, &hints, &ai);
+ if (error)
+ errx (1, "getaddrinfo: %s", gai_strerror (error));
+
+ for (n = 0, a = ai; a != NULL; a = a->ai_next)
+ ++n;
+
+ fds = malloc (n * sizeof(*fds));
+ if (fds == NULL)
+ errx (1, "mini_inetd: out of memory");
+
+ FD_ZERO(&orig_read_set);
+
+ for (i = 0, a = ai; a != NULL; a = a->ai_next, ++i) {
+ fds[i] = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (fds[i] < 0)
+ err (1, "socket");
+ socket_set_reuseaddr (fds[i], 1);
+ if (bind (fds[i], a->ai_addr, a->ai_addrlen) < 0)
+ err (1, "bind");
+ if (listen (fds[i], SOMAXCONN) < 0)
+ err (1, "listen");
+ FD_SET(fds[i], &orig_read_set);
+ max_fd = max(max_fd, fds[i]);
+ }
+ freeaddrinfo (ai);
+
+ do {
+ read_set = orig_read_set;
+
+ ret = select (max_fd + 1, &read_set, NULL, NULL, NULL);
+ if (ret < 0 && errno != EINTR)
+ err (1, "select");
+ } while (ret <= 0);
+
+ for (i = 0; i < n; ++i)
+ if (FD_ISSET (fds[i], &read_set)) {
+ accept_it (fds[i]);
+ return;
+ }
+ abort ();
+}
diff --git a/crypto/heimdal/lib/roken/mkstemp.c b/crypto/heimdal/lib/roken/mkstemp.c
new file mode 100644
index 000000000000..350f4cb7aee1
--- /dev/null
+++ b/crypto/heimdal/lib/roken/mkstemp.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <errno.h>
+
+RCSID("$Id: mkstemp.c,v 1.3 1999/12/02 16:58:51 joda Exp $");
+
+#ifndef HAVE_MKSTEMP
+
+int
+mkstemp(char *template)
+{
+ int start, i;
+ pid_t val;
+ val = getpid();
+ start = strlen(template) - 1;
+ while(template[start] == 'X') {
+ template[start] = '0' + val % 10;
+ val /= 10;
+ start--;
+ }
+
+ do{
+ int fd;
+ fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600);
+ if(fd >= 0 || errno != EEXIST)
+ return fd;
+ i = start + 1;
+ do{
+ if(template[i] == 0)
+ return -1;
+ template[i]++;
+ if(template[i] == '9' + 1)
+ template[i] = 'a';
+ if(template[i] <= 'z')
+ break;
+ template[i] = 'a';
+ i++;
+ }while(1);
+ }while(1);
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/net_read.c b/crypto/heimdal/lib/roken/net_read.c
new file mode 100644
index 000000000000..6d45bfa5471a
--- /dev/null
+++ b/crypto/heimdal/lib/roken/net_read.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: net_read.c,v 1.3 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <roken.h>
+
+/*
+ * Like read but never return partial data.
+ */
+
+ssize_t
+net_read (int fd, void *buf, size_t nbytes)
+{
+ char *cbuf = (char *)buf;
+ ssize_t count;
+ size_t rem = nbytes;
+
+ while (rem > 0) {
+#ifdef WIN32
+ count = recv (fd, cbuf, rem, 0);
+#else
+ count = read (fd, cbuf, rem);
+#endif
+ if (count < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return count;
+ } else if (count == 0) {
+ return count;
+ }
+ cbuf += count;
+ rem -= count;
+ }
+ return nbytes;
+}
diff --git a/crypto/heimdal/lib/roken/net_write.c b/crypto/heimdal/lib/roken/net_write.c
new file mode 100644
index 000000000000..2f63dbeed10e
--- /dev/null
+++ b/crypto/heimdal/lib/roken/net_write.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: net_write.c,v 1.4 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <roken.h>
+
+/*
+ * Like write but never return partial data.
+ */
+
+ssize_t
+net_write (int fd, const void *buf, size_t nbytes)
+{
+ const char *cbuf = (const char *)buf;
+ ssize_t count;
+ size_t rem = nbytes;
+
+ while (rem > 0) {
+#ifdef WIN32
+ count = send (fd, cbuf, rem, 0);
+#else
+ count = write (fd, cbuf, rem);
+#endif
+ if (count < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return count;
+ }
+ cbuf += count;
+ rem -= count;
+ }
+ return nbytes;
+}
diff --git a/crypto/heimdal/lib/roken/parse_bytes-test.c b/crypto/heimdal/lib/roken/parse_bytes-test.c
new file mode 100644
index 000000000000..499d942bf060
--- /dev/null
+++ b/crypto/heimdal/lib/roken/parse_bytes-test.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: parse_bytes-test.c,v 1.2 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+#include "roken.h"
+#include "parse_bytes.h"
+
+static struct testcase {
+ int canonicalp;
+ int val;
+ const char *def_unit;
+ const char *str;
+} tests[] = {
+ {0, 0, NULL, "0 bytes"},
+ {1, 0, NULL, "0"},
+ {0, 1, NULL, "1"},
+ {1, 1, NULL, "1 byte"},
+ {0, 0, "kilobyte", "0"},
+ {0, 1024, "kilobyte", "1"},
+ {1, 1024, "kilobyte", "1 kilobyte"},
+ {1, 1024 * 1024, NULL, "1 megabyte"},
+ {0, 1025, NULL, "1 kilobyte 1"},
+ {1, 1025, NULL, "1 kilobyte 1 byte"},
+};
+
+int
+main(int argc, char **argv)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) {
+ char buf[256];
+ int val = parse_bytes (tests[i].str, tests[i].def_unit);
+ size_t len;
+
+ if (val != tests[i].val) {
+ printf ("parse_bytes (%s, %s) = %d != %d\n",
+ tests[i].str,
+ tests[i].def_unit ? tests[i].def_unit : "none",
+ val, tests[i].val);
+ ++ret;
+ }
+ if (tests[i].canonicalp) {
+ len = unparse_bytes (tests[i].val, buf, sizeof(buf));
+ if (strcmp (tests[i].str, buf) != 0) {
+ printf ("unparse_bytes (%d) = \"%s\" != \"%s\"\n",
+ tests[i].val, buf, tests[i].str);
+ ++ret;
+ }
+ }
+ }
+ if (ret) {
+ printf ("%d errors\n", ret);
+ return 1;
+ } else
+ return 0;
+}
diff --git a/crypto/heimdal/lib/roken/parse_bytes.c b/crypto/heimdal/lib/roken/parse_bytes.c
new file mode 100644
index 000000000000..f3c514fcd677
--- /dev/null
+++ b/crypto/heimdal/lib/roken/parse_bytes.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: parse_bytes.c,v 1.2 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+#include <parse_units.h>
+#include "parse_bytes.h"
+
+static units bytes_units[] = {
+ { "gigabyte", 1024 * 1024 * 1024 },
+ { "gbyte", 1024 * 1024 * 1024 },
+ { "GB", 1024 * 1024 * 1024 },
+ { "megabyte", 1024 * 1024 },
+ { "mbyte", 1024 * 1024 },
+ { "MB", 1024 * 1024 },
+ { "kilobyte", 1024 },
+ { "KB", 1024 },
+ { "byte", 1 },
+ { NULL, 0 }
+};
+
+static units bytes_short_units[] = {
+ { "GB", 1024 * 1024 * 1024 },
+ { "MB", 1024 * 1024 },
+ { "KB", 1024 },
+ { NULL, 0 }
+};
+
+int
+parse_bytes (const char *s, const char *def_unit)
+{
+ return parse_units (s, bytes_units, def_unit);
+}
+
+size_t
+unparse_bytes (int t, char *s, size_t len)
+{
+ return unparse_units (t, bytes_units, s, len);
+}
+
+size_t
+unparse_bytes_short (int t, char *s, size_t len)
+{
+ return unparse_units_approx (t, bytes_short_units, s, len);
+}
diff --git a/crypto/heimdal/lib/roken/parse_bytes.h b/crypto/heimdal/lib/roken/parse_bytes.h
new file mode 100644
index 000000000000..8116c1c8ad77
--- /dev/null
+++ b/crypto/heimdal/lib/roken/parse_bytes.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: parse_bytes.h,v 1.2 1999/12/02 16:58:51 joda Exp $ */
+
+#ifndef __PARSE_BYTES_H__
+#define __PARSE_BYTES_H__
+
+int
+parse_bytes (const char *s, const char *def_unit);
+
+size_t
+unparse_bytes (int t, char *s, size_t len);
+
+size_t
+unparse_bytes_short (int t, char *s, size_t len);
+
+#endif /* __PARSE_BYTES_H__ */
diff --git a/crypto/heimdal/lib/roken/parse_time.c b/crypto/heimdal/lib/roken/parse_time.c
new file mode 100644
index 000000000000..a09ded758de8
--- /dev/null
+++ b/crypto/heimdal/lib/roken/parse_time.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: parse_time.c,v 1.5 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+#include <parse_units.h>
+#include "parse_time.h"
+
+static units time_units[] = {
+ {"year", 365 * 24 * 60 * 60},
+ {"month", 30 * 24 * 60 * 60},
+ {"week", 7 * 24 * 60 * 60},
+ {"day", 24 * 60 * 60},
+ {"hour", 60 * 60},
+ {"h", 60 * 60},
+ {"minute", 60},
+ {"m", 60},
+ {"second", 1},
+ {"s", 1},
+ {NULL, 0},
+};
+
+int
+parse_time (const char *s, const char *def_unit)
+{
+ return parse_units (s, time_units, def_unit);
+}
+
+size_t
+unparse_time (int t, char *s, size_t len)
+{
+ return unparse_units (t, time_units, s, len);
+}
+
+size_t
+unparse_time_approx (int t, char *s, size_t len)
+{
+ return unparse_units_approx (t, time_units, s, len);
+}
+
+void
+print_time_table (FILE *f)
+{
+ print_units_table (time_units, f);
+}
diff --git a/crypto/heimdal/lib/roken/parse_time.h b/crypto/heimdal/lib/roken/parse_time.h
new file mode 100644
index 000000000000..55de505dbba3
--- /dev/null
+++ b/crypto/heimdal/lib/roken/parse_time.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: parse_time.h,v 1.4 1999/12/02 16:58:51 joda Exp $ */
+
+#ifndef __PARSE_TIME_H__
+#define __PARSE_TIME_H__
+
+int
+parse_time (const char *s, const char *def_unit);
+
+size_t
+unparse_time (int t, char *s, size_t len);
+
+size_t
+unparse_time_approx (int t, char *s, size_t len);
+
+void
+print_time_table (FILE *f);
+
+#endif /* __PARSE_TIME_H__ */
diff --git a/crypto/heimdal/lib/roken/parse_units.c b/crypto/heimdal/lib/roken/parse_units.c
new file mode 100644
index 000000000000..34c5030cb65e
--- /dev/null
+++ b/crypto/heimdal/lib/roken/parse_units.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: parse_units.c,v 1.12 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <roken.h>
+#include "parse_units.h"
+
+/*
+ * Parse string in `s' according to `units' and return value.
+ * def_unit defines the default unit.
+ */
+
+static int
+parse_something (const char *s, const struct units *units,
+ const char *def_unit,
+ int (*func)(int res, int val, unsigned mult),
+ int init,
+ int accept_no_val_p)
+{
+ const char *p;
+ int res = init;
+ unsigned def_mult = 1;
+
+ if (def_unit != NULL) {
+ const struct units *u;
+
+ for (u = units; u->name; ++u) {
+ if (strcasecmp (u->name, def_unit) == 0) {
+ def_mult = u->mult;
+ break;
+ }
+ }
+ if (u->name == NULL)
+ return -1;
+ }
+
+ p = s;
+ while (*p) {
+ double val;
+ char *next;
+ const struct units *u, *partial_unit;
+ size_t u_len;
+ unsigned partial;
+ int no_val_p = 0;
+
+ while(isspace((unsigned char)*p) || *p == ',')
+ ++p;
+
+ val = strtod (p, &next); /* strtol(p, &next, 0); */
+ if (val == 0 && p == next) {
+ if(!accept_no_val_p)
+ return -1;
+ no_val_p = 1;
+ }
+ p = next;
+ while (isspace((unsigned char)*p))
+ ++p;
+ if (*p == '\0') {
+ res = (*func)(res, val, def_mult);
+ if (res < 0)
+ return res;
+ break;
+ } else if (*p == '+') {
+ ++p;
+ val = 1;
+ } else if (*p == '-') {
+ ++p;
+ val = -1;
+ }
+ if (no_val_p && val == 0)
+ val = 1;
+ u_len = strcspn (p, ", \t");
+ partial = 0;
+ partial_unit = NULL;
+ if (u_len > 1 && p[u_len - 1] == 's')
+ --u_len;
+ for (u = units; u->name; ++u) {
+ if (strncasecmp (p, u->name, u_len) == 0) {
+ if (u_len == strlen (u->name)) {
+ p += u_len;
+ res = (*func)(res, val, u->mult);
+ if (res < 0)
+ return res;
+ break;
+ } else {
+ ++partial;
+ partial_unit = u;
+ }
+ }
+ }
+ if (u->name == NULL) {
+ if (partial == 1) {
+ p += u_len;
+ res = (*func)(res, val, partial_unit->mult);
+ if (res < 0)
+ return res;
+ } else {
+ return -1;
+ }
+ }
+ if (*p == 's')
+ ++p;
+ }
+ return res;
+}
+
+/*
+ * The string consists of a sequence of `n unit'
+ */
+
+static int
+acc_units(int res, int val, unsigned mult)
+{
+ return res + val * mult;
+}
+
+int
+parse_units (const char *s, const struct units *units,
+ const char *def_unit)
+{
+ return parse_something (s, units, def_unit, acc_units, 0, 0);
+}
+
+/*
+ * The string consists of a sequence of `[+-]flag'. `orig' consists
+ * the original set of flags, those are then modified and returned as
+ * the function value.
+ */
+
+static int
+acc_flags(int res, int val, unsigned mult)
+{
+ if(val == 1)
+ return res | mult;
+ else if(val == -1)
+ return res & ~mult;
+ else if (val == 0)
+ return mult;
+ else
+ return -1;
+}
+
+int
+parse_flags (const char *s, const struct units *units,
+ int orig)
+{
+ return parse_something (s, units, NULL, acc_flags, orig, 1);
+}
+
+/*
+ * Return a string representation according to `units' of `num' in `s'
+ * with maximum length `len'. The actual length is the function value.
+ */
+
+static size_t
+unparse_something (int num, const struct units *units, char *s, size_t len,
+ int (*print) (char *s, size_t len, int div,
+ const char *name, int rem),
+ int (*update) (int in, unsigned mult),
+ const char *zero_string)
+{
+ const struct units *u;
+ size_t ret = 0, tmp;
+
+ if (num == 0)
+ return snprintf (s, len, "%s", zero_string);
+
+ for (u = units; num > 0 && u->name; ++u) {
+ int div;
+
+ div = num / u->mult;
+ if (div) {
+ num = (*update) (num, u->mult);
+ tmp = (*print) (s, len, div, u->name, num);
+
+ len -= tmp;
+ s += tmp;
+ ret += tmp;
+ }
+ }
+ return ret;
+}
+
+static int
+print_unit (char *s, size_t len, int div, const char *name, int rem)
+{
+ return snprintf (s, len, "%u %s%s%s",
+ div, name,
+ div == 1 ? "" : "s",
+ rem > 0 ? " " : "");
+}
+
+static int
+update_unit (int in, unsigned mult)
+{
+ return in % mult;
+}
+
+static int
+update_unit_approx (int in, unsigned mult)
+{
+ if (in / mult > 0)
+ return 0;
+ else
+ return update_unit (in, mult);
+}
+
+size_t
+unparse_units (int num, const struct units *units, char *s, size_t len)
+{
+ return unparse_something (num, units, s, len,
+ print_unit,
+ update_unit,
+ "0");
+}
+
+size_t
+unparse_units_approx (int num, const struct units *units, char *s, size_t len)
+{
+ return unparse_something (num, units, s, len,
+ print_unit,
+ update_unit_approx,
+ "0");
+}
+
+void
+print_units_table (const struct units *units, FILE *f)
+{
+ const struct units *u, *u2;
+ unsigned max_sz = 0;
+
+ for (u = units; u->name; ++u) {
+ max_sz = max(max_sz, strlen(u->name));
+ }
+
+ for (u = units; u->name;) {
+ char buf[1024];
+ const struct units *next;
+
+ for (next = u + 1; next->name && next->mult == u->mult; ++next)
+ ;
+
+ if (next->name) {
+ for (u2 = next;
+ u2->name && u->mult % u2->mult != 0;
+ ++u2)
+ ;
+ if (u2->name == NULL)
+ --u2;
+ unparse_units (u->mult, u2, buf, sizeof(buf));
+ fprintf (f, "1 %*s = %s\n", max_sz, u->name, buf);
+ } else {
+ fprintf (f, "1 %s\n", u->name);
+ }
+ u = next;
+ }
+}
+
+static int
+print_flag (char *s, size_t len, int div, const char *name, int rem)
+{
+ return snprintf (s, len, "%s%s", name, rem > 0 ? ", " : "");
+}
+
+static int
+update_flag (int in, unsigned mult)
+{
+ return in - mult;
+}
+
+size_t
+unparse_flags (int num, const struct units *units, char *s, size_t len)
+{
+ return unparse_something (num, units, s, len,
+ print_flag,
+ update_flag,
+ "");
+}
+
+void
+print_flags_table (const struct units *units, FILE *f)
+{
+ const struct units *u;
+
+ for(u = units; u->name; ++u)
+ fprintf(f, "%s%s", u->name, (u+1)->name ? ", " : "\n");
+}
diff --git a/crypto/heimdal/lib/roken/parse_units.h b/crypto/heimdal/lib/roken/parse_units.h
new file mode 100644
index 000000000000..f159d30e9007
--- /dev/null
+++ b/crypto/heimdal/lib/roken/parse_units.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: parse_units.h,v 1.6 1999/12/02 16:58:51 joda Exp $ */
+
+#ifndef __PARSE_UNITS_H__
+#define __PARSE_UNITS_H__
+
+#include <stdio.h>
+#include <stddef.h>
+
+struct units {
+ const char *name;
+ unsigned mult;
+};
+
+typedef struct units units;
+
+int
+parse_units (const char *s, const struct units *units,
+ const char *def_unit);
+
+void
+print_units_table (const struct units *units, FILE *f);
+
+int
+parse_flags (const char *s, const struct units *units,
+ int orig);
+
+size_t
+unparse_units (int num, const struct units *units, char *s, size_t len);
+
+size_t
+unparse_units_approx (int num, const struct units *units, char *s,
+ size_t len);
+
+size_t
+unparse_flags (int num, const struct units *units, char *s, size_t len);
+
+void
+print_flags_table (const struct units *units, FILE *f);
+
+#endif /* __PARSE_UNITS_H__ */
diff --git a/crypto/heimdal/lib/roken/print_version.c b/crypto/heimdal/lib/roken/print_version.c
new file mode 100644
index 000000000000..809bbb3bb920
--- /dev/null
+++ b/crypto/heimdal/lib/roken/print_version.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: print_version.c,v 1.5 1999/12/02 16:58:51 joda Exp $");
+#endif
+#include "roken.h"
+
+#include "print_version.h"
+
+void
+print_version(const char *progname)
+{
+ const char *arg[] = VERSIONLIST;
+ const int num_args = sizeof(arg) / sizeof(arg[0]);
+ char *msg;
+ size_t len = 0;
+ int i;
+
+ if(progname == NULL)
+ progname = __progname;
+
+ if(num_args == 0)
+ msg = "no version information";
+ else {
+ for(i = 0; i < num_args; i++) {
+ if(i > 0)
+ len += 2;
+ len += strlen(arg[i]);
+ }
+ msg = malloc(len + 1);
+ if(msg == NULL) {
+ fprintf(stderr, "%s: out of memory\n", progname);
+ return;
+ }
+ msg[0] = '\0';
+ for(i = 0; i < num_args; i++) {
+ if(i > 0)
+ strcat(msg, ", ");
+ strcat(msg, arg[i]);
+ }
+ }
+ fprintf(stderr, "%s (%s)\n", progname, msg);
+ fprintf(stderr, "Copyright (c) 1999 Kungliga Tekniska Högskolan\n");
+ if(num_args != 0)
+ free(msg);
+}
diff --git a/crypto/heimdal/lib/roken/putenv.c b/crypto/heimdal/lib/roken/putenv.c
new file mode 100644
index 000000000000..80951d12c534
--- /dev/null
+++ b/crypto/heimdal/lib/roken/putenv.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: putenv.c,v 1.6 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+#include <stdlib.h>
+
+extern char **environ;
+
+/*
+ * putenv --
+ * String points to a string of the form name=value.
+ *
+ * Makes the value of the environment variable name equal to
+ * value by altering an existing variable or creating a new one.
+ */
+int putenv(const char *string)
+{
+ int i;
+ int len;
+
+ len = string - strchr(string, '=') + 1;
+
+ if(environ == NULL){
+ environ = malloc(sizeof(char*));
+ if(environ == NULL)
+ return 1;
+ environ[0] = NULL;
+ }
+
+ for(i = 0; environ[i]; i++)
+ if(strncmp(string, environ[i], len)){
+ environ[len] = string;
+ return 0;
+ }
+ environ = realloc(environ, sizeof(char*) * (i + 1));
+ if(environ == NULL)
+ return 1;
+ environ[i] = string;
+ environ[i+1] = NULL;
+ return 0;
+}
+
diff --git a/crypto/heimdal/lib/roken/rcmd.c b/crypto/heimdal/lib/roken/rcmd.c
new file mode 100644
index 000000000000..41179484bce5
--- /dev/null
+++ b/crypto/heimdal/lib/roken/rcmd.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: rcmd.c,v 1.3 1999/12/02 16:58:51 joda Exp $");
+#endif
+
+#include "roken.h"
+#include <stdio.h>
+
+int
+rcmd(char **ahost,
+ unsigned short inport,
+ const char *locuser,
+ const char *remuser,
+ const char *cmd,
+ int *fd2p)
+{
+ fprintf(stderr, "Only kerberized services are implemented\n");
+ return -1;
+}
diff --git a/crypto/heimdal/lib/roken/readv.c b/crypto/heimdal/lib/roken/readv.c
new file mode 100644
index 000000000000..de2f9ea8af72
--- /dev/null
+++ b/crypto/heimdal/lib/roken/readv.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: readv.c,v 1.5 1999/12/02 16:58:52 joda Exp $");
+#endif
+
+#include "roken.h"
+
+ssize_t
+readv(int d, const struct iovec *iov, int iovcnt)
+{
+ ssize_t ret, nb;
+ size_t tot = 0;
+ int i;
+ char *buf, *p;
+
+ for(i = 0; i < iovcnt; ++i)
+ tot += iov[i].iov_len;
+ buf = malloc(tot);
+ if (tot != 0 && buf == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ nb = ret = read (d, buf, tot);
+ p = buf;
+ while (nb > 0) {
+ ssize_t cnt = min(nb, iov->iov_len);
+
+ memcpy (iov->iov_base, p, cnt);
+ p += cnt;
+ nb -= cnt;
+ }
+ free(buf);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/recvmsg.c b/crypto/heimdal/lib/roken/recvmsg.c
new file mode 100644
index 000000000000..e94ad68c80be
--- /dev/null
+++ b/crypto/heimdal/lib/roken/recvmsg.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: recvmsg.c,v 1.5 1999/12/02 16:58:52 joda Exp $");
+#endif
+
+#include "roken.h"
+
+ssize_t
+recvmsg(int s, struct msghdr *msg, int flags)
+{
+ ssize_t ret, nb;
+ size_t tot = 0;
+ int i;
+ char *buf, *p;
+ struct iovec *iov = msg->msg_iov;
+
+ for(i = 0; i < msg->msg_iovlen; ++i)
+ tot += iov[i].iov_len;
+ buf = malloc(tot);
+ if (tot != 0 && buf == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ nb = ret = recvfrom (s, buf, tot, flags, msg->msg_name, &msg->msg_namelen);
+ p = buf;
+ while (nb > 0) {
+ ssize_t cnt = min(nb, iov->iov_len);
+
+ memcpy (iov->iov_base, p, cnt);
+ p += cnt;
+ nb -= cnt;
+ ++iov;
+ }
+ free(buf);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/resolve.c b/crypto/heimdal/lib/roken/resolve.c
new file mode 100644
index 000000000000..8840740532cc
--- /dev/null
+++ b/crypto/heimdal/lib/roken/resolve.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+#include "resolve.h"
+
+RCSID("$Id: resolve.c,v 1.22 1999/12/02 16:58:52 joda Exp $");
+
+#if defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND)
+
+#define DECL(X) {#X, T_##X}
+
+static struct stot{
+ const char *name;
+ int type;
+}stot[] = {
+ DECL(A),
+ DECL(NS),
+ DECL(CNAME),
+ DECL(PTR),
+ DECL(MX),
+ DECL(TXT),
+ DECL(AFSDB),
+ DECL(SRV),
+ {NULL, 0}
+};
+
+int _resolve_debug;
+
+static int
+string_to_type(const char *name)
+{
+ struct stot *p = stot;
+ for(p = stot; p->name; p++)
+ if(strcasecmp(name, p->name) == 0)
+ return p->type;
+ return -1;
+}
+
+static const char *
+type_to_string(int type)
+{
+ struct stot *p = stot;
+ for(p = stot; p->name; p++)
+ if(type == p->type)
+ return p->name;
+ return NULL;
+}
+
+void
+dns_free_data(struct dns_reply *r)
+{
+ struct resource_record *rr;
+ if(r->q.domain)
+ free(r->q.domain);
+ for(rr = r->head; rr;){
+ struct resource_record *tmp = rr;
+ if(rr->domain)
+ free(rr->domain);
+ if(rr->u.data)
+ free(rr->u.data);
+ rr = rr->next;
+ free(tmp);
+ }
+ free (r);
+}
+
+static struct dns_reply*
+parse_reply(unsigned char *data, int len)
+{
+ unsigned char *p;
+ char host[128];
+ int status;
+
+ struct dns_reply *r;
+ struct resource_record **rr;
+
+ r = calloc(1, sizeof(*r));
+ if (r == NULL)
+ return NULL;
+
+ p = data;
+#if 0
+ /* doesn't work on Crays */
+ memcpy(&r->h, p, sizeof(HEADER));
+ p += sizeof(HEADER);
+#else
+ memcpy(&r->h, p, 12); /* XXX this will probably be mostly garbage */
+ p += 12;
+#endif
+ status = dn_expand(data, data + len, p, host, sizeof(host));
+ if(status < 0){
+ dns_free_data(r);
+ return NULL;
+ }
+ r->q.domain = strdup(host);
+ if(r->q.domain == NULL) {
+ dns_free_data(r);
+ return NULL;
+ }
+ p += status;
+ r->q.type = (p[0] << 8 | p[1]);
+ p += 2;
+ r->q.class = (p[0] << 8 | p[1]);
+ p += 2;
+ rr = &r->head;
+ while(p < data + len){
+ int type, class, ttl, size;
+ status = dn_expand(data, data + len, p, host, sizeof(host));
+ if(status < 0){
+ dns_free_data(r);
+ return NULL;
+ }
+ p += status;
+ type = (p[0] << 8) | p[1];
+ p += 2;
+ class = (p[0] << 8) | p[1];
+ p += 2;
+ ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ p += 4;
+ size = (p[0] << 8) | p[1];
+ p += 2;
+ *rr = (struct resource_record*)calloc(1,
+ sizeof(struct resource_record));
+ if(*rr == NULL) {
+ dns_free_data(r);
+ return NULL;
+ }
+ (*rr)->domain = strdup(host);
+ if((*rr)->domain == NULL) {
+ dns_free_data(r);
+ return NULL;
+ }
+ (*rr)->type = type;
+ (*rr)->class = class;
+ (*rr)->ttl = ttl;
+ (*rr)->size = size;
+ switch(type){
+ case T_NS:
+ case T_CNAME:
+ case T_PTR:
+ status = dn_expand(data, data + len, p, host, sizeof(host));
+ if(status < 0){
+ dns_free_data(r);
+ return NULL;
+ }
+ (*rr)->u.txt = strdup(host);
+ if((*rr)->u.txt == NULL) {
+ dns_free_data(r);
+ return NULL;
+ }
+ break;
+ case T_MX:
+ case T_AFSDB:{
+ status = dn_expand(data, data + len, p + 2, host, sizeof(host));
+ if(status < 0){
+ dns_free_data(r);
+ return NULL;
+ }
+ (*rr)->u.mx = (struct mx_record*)malloc(sizeof(struct mx_record) +
+ strlen(host));
+ if((*rr)->u.mx == NULL) {
+ dns_free_data(r);
+ return NULL;
+ }
+ (*rr)->u.mx->preference = (p[0] << 8) | p[1];
+ strcpy((*rr)->u.mx->domain, host);
+ break;
+ }
+ case T_SRV:{
+ status = dn_expand(data, data + len, p + 6, host, sizeof(host));
+ if(status < 0){
+ dns_free_data(r);
+ return NULL;
+ }
+ (*rr)->u.srv =
+ (struct srv_record*)malloc(sizeof(struct srv_record) +
+ strlen(host));
+ if((*rr)->u.srv == NULL) {
+ dns_free_data(r);
+ return NULL;
+ }
+ (*rr)->u.srv->priority = (p[0] << 8) | p[1];
+ (*rr)->u.srv->weight = (p[2] << 8) | p[3];
+ (*rr)->u.srv->port = (p[4] << 8) | p[5];
+ strcpy((*rr)->u.srv->target, host);
+ break;
+ }
+ case T_TXT:{
+ (*rr)->u.txt = (char*)malloc(size + 1);
+ if((*rr)->u.txt == NULL) {
+ dns_free_data(r);
+ return NULL;
+ }
+ strncpy((*rr)->u.txt, (char*)p + 1, *p);
+ (*rr)->u.txt[*p] = 0;
+ break;
+ }
+
+ default:
+ (*rr)->u.data = (unsigned char*)malloc(size);
+ if(size != 0 && (*rr)->u.data == NULL) {
+ dns_free_data(r);
+ return NULL;
+ }
+ memcpy((*rr)->u.data, p, size);
+ }
+ p += size;
+ rr = &(*rr)->next;
+ }
+ *rr = NULL;
+ return r;
+}
+
+static struct dns_reply *
+dns_lookup_int(const char *domain, int rr_class, int rr_type)
+{
+ unsigned char reply[1024];
+ int len;
+ struct dns_reply *r = NULL;
+ u_long old_options = 0;
+
+ if (_resolve_debug) {
+ old_options = _res.options;
+ _res.options |= RES_DEBUG;
+ fprintf(stderr, "dns_lookup(%s, %d, %s)\n", domain,
+ rr_class, type_to_string(rr_type));
+ }
+ len = res_search(domain, rr_class, rr_type, reply, sizeof(reply));
+ if (_resolve_debug) {
+ _res.options = old_options;
+ fprintf(stderr, "dns_lookup(%s, %d, %s) --> %d\n",
+ domain, rr_class, type_to_string(rr_type), len);
+ }
+ if (len >= 0)
+ r = parse_reply(reply, len);
+ return r;
+}
+
+struct dns_reply *
+dns_lookup(const char *domain, const char *type_name)
+{
+ int type;
+
+ type = string_to_type(type_name);
+ if(type == -1) {
+ if(_resolve_debug)
+ fprintf(stderr, "dns_lookup: unknown resource type: `%s'\n",
+ type_name);
+ return NULL;
+ }
+ return dns_lookup_int(domain, C_IN, type);
+}
+
+#else /* NOT defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) */
+
+struct dns_reply *
+dns_lookup(const char *domain, const char *type_name)
+{
+ return NULL;
+}
+
+void
+dns_free_data(struct dns_reply *r)
+{
+}
+
+#endif
+
+#ifdef TEST
+int
+main(int argc, char **argv)
+{
+ struct dns_reply *r;
+ struct resource_record *rr;
+ r = dns_lookup(argv[1], argv[2]);
+ if(r == NULL){
+ printf("No reply.\n");
+ return 1;
+ }
+ for(rr = r->head; rr;rr=rr->next){
+ printf("%s %s %d ", rr->domain, type_to_string(rr->type), rr->ttl);
+ switch(rr->type){
+ case T_NS:
+ printf("%s\n", (char*)rr->u.data);
+ break;
+ case T_A:
+ printf("%d.%d.%d.%d\n",
+ ((unsigned char*)rr->u.data)[0],
+ ((unsigned char*)rr->u.data)[1],
+ ((unsigned char*)rr->u.data)[2],
+ ((unsigned char*)rr->u.data)[3]);
+ break;
+ case T_MX:
+ case T_AFSDB:{
+ struct mx_record *mx = (struct mx_record*)rr->u.data;
+ printf("%d %s\n", mx->preference, mx->domain);
+ break;
+ }
+ case T_SRV:{
+ struct srv_record *srv = (struct srv_record*)rr->u.data;
+ printf("%d %d %d %s\n", srv->priority, srv->weight,
+ srv->port, srv->target);
+ break;
+ }
+ default:
+ printf("\n");
+ break;
+ }
+ }
+
+ return 0;
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/resolve.h b/crypto/heimdal/lib/roken/resolve.h
new file mode 100644
index 000000000000..c90f6b54ada5
--- /dev/null
+++ b/crypto/heimdal/lib/roken/resolve.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: resolve.h,v 1.8 1999/12/02 16:58:52 joda Exp $ */
+
+#ifndef __RESOLVE_H__
+#define __RESOLVE_H__
+
+/* We use these, but they are not always present in <arpa/nameser.h> */
+
+#ifndef T_TXT
+#define T_TXT 16
+#endif
+#ifndef T_AFSDB
+#define T_AFSDB 18
+#endif
+#ifndef T_SRV
+#define T_SRV 33
+#endif
+#ifndef T_NAPTR
+#define T_NAPTR 35
+#endif
+
+struct dns_query{
+ char *domain;
+ unsigned type;
+ unsigned class;
+};
+
+struct mx_record{
+ unsigned preference;
+ char domain[1];
+};
+
+struct srv_record{
+ unsigned priority;
+ unsigned weight;
+ unsigned port;
+ char target[1];
+};
+
+struct resource_record{
+ char *domain;
+ unsigned type;
+ unsigned class;
+ unsigned ttl;
+ unsigned size;
+ union {
+ void *data;
+ struct mx_record *mx;
+ struct mx_record *afsdb; /* mx and afsdb are identical */
+ struct srv_record *srv;
+ struct in_addr *a;
+ char *txt;
+ }u;
+ struct resource_record *next;
+};
+
+#ifndef T_A /* XXX if <arpa/nameser.h> isn't included */
+typedef int HEADER; /* will never be used */
+#endif
+
+struct dns_reply{
+ HEADER h;
+ struct dns_query q;
+ struct resource_record *head;
+};
+
+
+struct dns_reply* dns_lookup(const char *, const char *);
+void dns_free_data(struct dns_reply *);
+
+#endif /* __RESOLVE_H__ */
diff --git a/crypto/heimdal/lib/roken/resource.h b/crypto/heimdal/lib/roken/resource.h
new file mode 100644
index 000000000000..01cd01d76c8c
--- /dev/null
+++ b/crypto/heimdal/lib/roken/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by roken.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/crypto/heimdal/lib/roken/roken-common.h b/crypto/heimdal/lib/roken/roken-common.h
new file mode 100644
index 000000000000..164547a293d5
--- /dev/null
+++ b/crypto/heimdal/lib/roken/roken-common.h
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: roken-common.h,v 1.24 1999/12/05 13:25:40 assar Exp $ */
+
+#ifndef __ROKEN_COMMON_H__
+#define __ROKEN_COMMON_H__
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK 0x7f000001
+#endif
+
+#ifndef SOMAXCONN
+#define SOMAXCONN 5
+#endif
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+#ifndef max
+#define max(a,b) (((a)>(b))?(a):(b))
+#endif
+
+#ifndef min
+#define min(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef LOG_DAEMON
+#define openlog(id,option,facility) openlog((id),(option))
+#define LOG_DAEMON 0
+#endif
+#ifndef LOG_ODELAY
+#define LOG_ODELAY 0
+#endif
+#ifndef LOG_NDELAY
+#define LOG_NDELAY 0x08
+#endif
+#ifndef LOG_CONS
+#define LOG_CONS 0
+#endif
+#ifndef LOG_AUTH
+#define LOG_AUTH 0
+#endif
+#ifndef LOG_AUTHPRIV
+#define LOG_AUTHPRIV LOG_AUTH
+#endif
+
+#ifndef F_OK
+#define F_OK 0
+#endif
+
+#ifndef O_ACCMODE
+#define O_ACCMODE 003
+#endif
+
+#ifndef _PATH_DEVNULL
+#define _PATH_DEVNULL "/dev/null"
+#endif
+
+#ifndef _PATH_HEQUIV
+#define _PATH_HEQUIV "/etc/hosts.equiv"
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN (1024+4)
+#endif
+
+#ifndef SIG_ERR
+#define SIG_ERR ((RETSIGTYPE (*)())-1)
+#endif
+
+/*
+ * error code for getipnodeby{name,addr}
+ */
+
+#ifndef HOST_NOT_FOUND
+#define HOST_NOT_FOUND 1
+#endif
+
+#ifndef TRY_AGAIN
+#define TRY_AGAIN 2
+#endif
+
+#ifndef NO_RECOVERY
+#define NO_RECOVERY 3
+#endif
+
+#ifndef NO_DATA
+#define NO_DATA 4
+#endif
+
+#ifndef NO_ADDRESS
+#define NO_ADDRESS NO_DATA
+#endif
+
+/*
+ * error code for getaddrinfo
+ */
+
+#ifndef EAI_NOERROR
+#define EAI_NOERROR 0 /* no error */
+#endif
+
+#ifndef EAI_ADDRFAMILY
+
+#define EAI_ADDRFAMILY 1 /* address family for nodename not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with nodename */
+#define EAI_NONAME 8 /* nodename nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+
+#endif /* EAI_ADDRFAMILY */
+
+/* flags for getaddrinfo() */
+
+#ifndef AI_PASSIVE
+
+#define AI_PASSIVE 0x01
+#define AI_CANONNAME 0x02
+#define AI_NUMERICHOST 0x04
+
+#endif /* AI_PASSIVE */
+
+/* flags for getnameinfo() */
+
+#ifndef NI_DGRAM
+#define NI_DGRAM 0x01
+#define NI_NAMEREQD 0x02
+#define NI_NOFQDN 0x04
+#define NI_NUMERICHOST 0x08
+#define NI_NUMERICSERV 0x10
+#endif
+
+/*
+ * constants for getnameinfo
+ */
+
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+#endif
+
+/*
+ * constants for inet_ntop
+ */
+
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+
+/*
+ * for shutdown(2)
+ */
+
+#ifndef SHUT_RD
+#define SHUT_RD 0
+#endif
+
+#ifndef SHUT_WR
+#define SHUT_WR 1
+#endif
+
+#ifndef SHUT_RDWR
+#define SHUT_RDWR 2
+#endif
+
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
+#endif
+
+#if IRIX != 4 /* fix for compiler bug */
+#ifdef RETSIGTYPE
+typedef RETSIGTYPE (*SigAction)(/* int??? */);
+SigAction signal(int iSig, SigAction pAction); /* BSD compatible */
+#endif
+#endif
+
+int ROKEN_LIB_FUNCTION simple_execve(const char*, char*const[], char*const[]);
+int ROKEN_LIB_FUNCTION simple_execvp(const char*, char *const[]);
+int ROKEN_LIB_FUNCTION simple_execlp(const char*, ...);
+int ROKEN_LIB_FUNCTION simple_execle(const char*, ...);
+
+void ROKEN_LIB_FUNCTION print_version(const char *);
+
+void *ROKEN_LIB_FUNCTION emalloc (size_t);
+void *ROKEN_LIB_FUNCTION erealloc (void *, size_t);
+char *ROKEN_LIB_FUNCTION estrdup (const char *);
+
+ssize_t ROKEN_LIB_FUNCTION eread (int fd, void *buf, size_t nbytes);
+ssize_t ROKEN_LIB_FUNCTION ewrite (int fd, const void *buf, size_t nbytes);
+
+void
+socket_set_address_and_port (struct sockaddr *sa, const void *ptr, int port);
+
+size_t
+socket_addr_size (const struct sockaddr *sa);
+
+void
+socket_set_any (struct sockaddr *sa, int af);
+
+size_t
+socket_sockaddr_size (const struct sockaddr *sa);
+
+void *
+socket_get_address (struct sockaddr *sa);
+
+int
+socket_get_port (const struct sockaddr *sa);
+
+void
+socket_set_port (struct sockaddr *sa, int port);
+
+void
+socket_set_debug (int sock);
+
+void
+socket_set_tos (int sock, int tos);
+
+void
+socket_set_reuseaddr (int sock, int val);
+
+#endif /* __ROKEN_COMMON_H__ */
diff --git a/crypto/heimdal/lib/roken/roken.awk b/crypto/heimdal/lib/roken/roken.awk
new file mode 100644
index 000000000000..626fae5906e0
--- /dev/null
+++ b/crypto/heimdal/lib/roken/roken.awk
@@ -0,0 +1,35 @@
+BEGIN {
+ print "#include <stdio.h>"
+ print "#ifdef HAVE_CONFIG_H"
+ print "#include <config.h>"
+ print "#endif"
+ print ""
+ print "int main()"
+ print "{"
+ print "puts(\"/* This is an OS dependent, generated file */\");"
+ print "puts(\"\\n\");"
+ print "puts(\"#ifndef __ROKEN_H__\");"
+ print "puts(\"#define __ROKEN_H__\");"
+ print "puts(\"\");"
+}
+END {
+ print "puts(\"#endif /* __ROKEN_H__ */\");"
+ print "exit(0);"
+ print "}"
+}
+
+$1 == "\#ifdef" || $1 == "\#ifndef" || $1 == "\#if" || $1 == "\#else" || $1 == "\#elif" || $1 == "\#endif" || $1 == "#ifdef" || $1 == "#ifndef" || $1 == "#if" || $1 == "#else" || $1 == "#elif" || $1 == "#endif" {
+ print $0;
+ next
+}
+
+{
+ s = ""
+ for(i = 1; i <= length; i++){
+ x = substr($0, i, 1)
+ if(x == "\"" || x == "\\")
+ s = s "\\";
+ s = s x;
+ }
+ print "puts(\"" s "\");"
+}
diff --git a/crypto/heimdal/lib/roken/roken.def b/crypto/heimdal/lib/roken/roken.def
new file mode 100644
index 000000000000..f9b0369dd1dd
--- /dev/null
+++ b/crypto/heimdal/lib/roken/roken.def
@@ -0,0 +1,17 @@
+LIBRARY roken BASE=0x68f0000
+EXPORTS
+ gettimeofday
+ strcasecmp
+ strtok_r
+ snprintf
+ asprintf
+ vsnprintf
+ base64_decode
+ base64_encode
+ roken_concat
+ roken_vconcat
+ roken_vmconcat
+ roken_mconcat
+ getuid
+ dns_free_data
+ dns_lookup
diff --git a/crypto/heimdal/lib/roken/roken.dsp b/crypto/heimdal/lib/roken/roken.dsp
new file mode 100644
index 000000000000..d84854e3d30d
--- /dev/null
+++ b/crypto/heimdal/lib/roken/roken.dsp
@@ -0,0 +1,156 @@
+# Microsoft Developer Studio Project File - Name="roken" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=roken - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "roken.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "roken.mak" CFG="roken - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "roken - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "roken - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "roken - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir ".\Release"
+# PROP BASE Intermediate_Dir ".\Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\Release"
+# PROP Intermediate_Dir ".\Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MT /GX /O2 /I "..\krb" /I "..\des" /I "..\..\include" /I "..\..\include\win32" /I "." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /base:"0x68e7780" /subsystem:windows /dll /machine:I386
+
+!ELSEIF "$(CFG)" == "roken - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir ".\Debug"
+# PROP BASE Intermediate_Dir ".\Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\Debug"
+# PROP Intermediate_Dir ".\Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MDd /Gm /GX /Zi /Od /I "..\krb" /I "..\des" /I "..\..\include" /I "..\..\include\win32" /I "." /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /def:".\roken.def"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "roken - Win32 Release"
+# Name "roken - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
+# Begin Source File
+
+SOURCE=.\base64.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\concat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\gettimeofday.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\getuid.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\resolve.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\roken.def
+
+!IF "$(CFG)" == "roken - Win32 Release"
+
+!ELSEIF "$(CFG)" == "roken - Win32 Debug"
+
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\snprintf.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strcasecmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtok_r.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
+# Begin Source File
+
+SOURCE=.\resolve.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\roken.rc
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/crypto/heimdal/lib/roken/roken.h.in b/crypto/heimdal/lib/roken/roken.h.in
new file mode 100644
index 000000000000..03cfce47eed8
--- /dev/null
+++ b/crypto/heimdal/lib/roken/roken.h.in
@@ -0,0 +1,573 @@
+/* -*- C -*- */
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: roken.h.in,v 1.133 1999/12/30 02:22:54 assar Exp $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <signal.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
+#include <sys/ioctl.h>
+#endif
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ROKEN_LIB_FUNCTION
+#if defined(__BORLANDC__)
+#define ROKEN_LIB_FUNCTION /* not-ready-definition-yet */
+#elif defined(_MSC_VER)
+#define ROKEN_LIB_FUNCTION /* not-ready-definition-yet2 */
+#else
+#define ROKEN_LIB_FUNCTION
+#endif
+#endif
+
+#include <roken-common.h>
+
+#if !defined(HAVE_SETSID) && defined(HAVE__SETSID)
+#define setsid _setsid
+#endif
+
+#ifndef HAVE_PUTENV
+int putenv(const char *string);
+#endif
+
+#if !defined(HAVE_SETENV) || defined(NEED_SETENV_PROTO)
+int setenv(const char *var, const char *val, int rewrite);
+#endif
+
+#if !defined(HAVE_UNSETENV) || defined(NEED_UNSETENV_PROTO)
+void unsetenv(const char *name);
+#endif
+
+#if !defined(HAVE_GETUSERSHELL) || defined(NEED_GETUSERSHELL_PROTO)
+char *getusershell(void);
+void endusershell(void);
+#endif
+
+#if !defined(HAVE_SNPRINTF) || defined(NEED_SNPRINTF_PROTO)
+int snprintf (char *str, size_t sz, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+#endif
+
+#if !defined(HAVE_VSNPRINTF) || defined(NEED_VSNPRINTF_PROTO)
+int vsnprintf (char *str, size_t sz, const char *format, va_list ap)
+ __attribute__((format (printf, 3, 0)));
+#endif
+
+#if !defined(HAVE_ASPRINTF) || defined(NEED_ASPRINTF_PROTO)
+int asprintf (char **ret, const char *format, ...)
+ __attribute__ ((format (printf, 2, 3)));
+#endif
+
+#if !defined(HAVE_VASPRINTF) || defined(NEED_VASPRINTF_PROTO)
+int vasprintf (char **ret, const char *format, va_list ap)
+ __attribute__((format (printf, 2, 0)));
+#endif
+
+#if !defined(HAVE_ASNPRINTF) || defined(NEED_ASNPRINTF_PROTO)
+int asnprintf (char **ret, size_t max_sz, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+#endif
+
+#if !defined(HAVE_VASNPRINTF) || defined(NEED_VASNPRINTF_PROTO)
+int vasnprintf (char **ret, size_t max_sz, const char *format, va_list ap)
+ __attribute__((format (printf, 3, 0)));
+#endif
+
+#ifndef HAVE_STRDUP
+char * strdup(const char *old);
+#endif
+
+#ifndef HAVE_STRNDUP
+char * strndup(const char *old, size_t sz);
+#endif
+
+#ifndef HAVE_STRLWR
+char * strlwr(char *);
+#endif
+
+#ifndef HAVE_STRNLEN
+size_t strnlen(const char*, size_t);
+#endif
+
+#if !defined(HAVE_STRSEP) || defined(NEED_STRSEP_PROTO)
+char *strsep(char**, const char*);
+#endif
+
+#ifndef HAVE_STRCASECMP
+int strcasecmp(const char *s1, const char *s2);
+#endif
+
+#ifdef NEED_FCLOSE_PROTO
+int fclose(FILE *);
+#endif
+
+#ifdef NEED_STRTOK_R_PROTO
+char *strtok_r(char *s1, const char *s2, char **lasts);
+#endif
+
+#ifndef HAVE_STRUPR
+char * strupr(char *);
+#endif
+
+#ifndef HAVE_STRLCPY
+size_t strlcpy (char *dst, const char *src, size_t dst_sz);
+#endif
+
+#ifndef HAVE_STRLCAT
+size_t strlcat (char *dst, const char *src, size_t dst_sz);
+#endif
+
+#ifndef HAVE_GETDTABLESIZE
+int getdtablesize(void);
+#endif
+
+#if !defined(HAVE_STRERROR) && !defined(strerror)
+char *strerror(int eno);
+#endif
+
+#if !defined(HAVE_HSTRERROR) || defined(NEED_HSTRERROR_PROTO)
+/* This causes a fatal error under Psoriasis */
+#if !(defined(SunOS) && (SunOS >= 50))
+const char *hstrerror(int herr);
+#endif
+#endif
+
+#ifndef HAVE_H_ERRNO_DECLARATION
+extern int h_errno;
+#endif
+
+#if !defined(HAVE_INET_ATON) || defined(NEED_INET_ATON_PROTO)
+int inet_aton(const char *cp, struct in_addr *adr);
+#endif
+
+#ifndef HAVE_INET_NTOP
+const char *
+inet_ntop(int af, const void *src, char *dst, size_t size);
+#endif
+
+#ifndef HAVE_INET_PTON
+int
+inet_pton(int af, const char *src, void *dst);
+#endif
+
+#if !defined(HAVE_GETCWD)
+char* getcwd(char *path, size_t size);
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+struct passwd *k_getpwnam (const char *user);
+struct passwd *k_getpwuid (uid_t uid);
+#endif
+
+const char *get_default_username (void);
+
+#ifndef HAVE_SETEUID
+int seteuid(uid_t euid);
+#endif
+
+#ifndef HAVE_SETEGID
+int setegid(gid_t egid);
+#endif
+
+#ifndef HAVE_LSTAT
+int lstat(const char *path, struct stat *buf);
+#endif
+
+#if !defined(HAVE_MKSTEMP) || defined(NEED_MKSTEMP_PROTO)
+int mkstemp(char *);
+#endif
+
+#ifndef HAVE_CGETENT
+int cgetent(char **buf, char **db_array, const char *name);
+int cgetstr(char *buf, const char *cap, char **str);
+#endif
+
+#ifndef HAVE_INITGROUPS
+int initgroups(const char *name, gid_t basegid);
+#endif
+
+#ifndef HAVE_FCHOWN
+int fchown(int fd, uid_t owner, gid_t group);
+#endif
+
+#ifndef HAVE_DAEMON
+int daemon(int nochdir, int noclose);
+#endif
+
+#ifndef HAVE_INNETGR
+int innetgr(const char *netgroup, const char *machine,
+ const char *user, const char *domain);
+#endif
+
+#ifndef HAVE_CHOWN
+int chown(const char *path, uid_t owner, gid_t group);
+#endif
+
+#ifndef HAVE_RCMD
+int rcmd(char **ahost, unsigned short inport, const char *locuser,
+ const char *remuser, const char *cmd, int *fd2p);
+#endif
+
+#if !defined(HAVE_INNETGR) || defined(NEED_INNETGR_PROTO)
+int innetgr(const char*, const char*, const char*, const char*);
+#endif
+
+#ifndef HAVE_IRUSEROK
+int iruserok(unsigned raddr, int superuser, const char *ruser,
+ const char *luser);
+#endif
+
+#if !defined(HAVE_GETHOSTNAME) || defined(NEED_GETHOSTNAME_PROTO)
+int gethostname(char *name, int namelen);
+#endif
+
+#ifndef HAVE_WRITEV
+ssize_t
+writev(int d, const struct iovec *iov, int iovcnt);
+#endif
+
+#ifndef HAVE_READV
+ssize_t
+readv(int d, const struct iovec *iov, int iovcnt);
+#endif
+
+#ifndef HAVE_MKSTEMP
+int
+mkstemp(char *template);
+#endif
+
+#ifndef HAVE_FLOCK
+#ifndef LOCK_SH
+#define LOCK_SH 1 /* Shared lock */
+#endif
+#ifndef LOCK_EX
+#define LOCK_EX 2 /* Exclusive lock */
+#endif
+#ifndef LOCK_NB
+#define LOCK_NB 4 /* Don't block when locking */
+#endif
+#ifndef LOCK_UN
+#define LOCK_UN 8 /* Unlock */
+#endif
+
+int flock(int fd, int operation);
+#endif /* HAVE_FLOCK */
+
+time_t tm2time (struct tm tm, int local);
+
+int unix_verify_user(char *user, char *password);
+
+void mini_inetd (int port);
+
+int roken_concat (char *s, size_t len, ...);
+
+size_t roken_mconcat (char **s, size_t max_len, ...);
+
+int roken_vconcat (char *s, size_t len, va_list args);
+
+size_t roken_vmconcat (char **s, size_t max_len, va_list args);
+
+ssize_t net_write (int fd, const void *buf, size_t nbytes);
+
+ssize_t net_read (int fd, void *buf, size_t nbytes);
+
+int issuid(void);
+
+#ifndef HAVE_STRUCT_WINSIZE
+struct winsize {
+ unsigned short ws_row, ws_col;
+ unsigned short ws_xpixel, ws_ypixel;
+};
+#endif
+
+int get_window_size(int fd, struct winsize *);
+
+#ifndef HAVE_VSYSLOG
+void vsyslog(int pri, const char *fmt, va_list ap);
+#endif
+
+#ifndef HAVE_OPTARG_DECLARATION
+extern char *optarg;
+#endif
+#ifndef HAVE_OPTIND_DECLARATION
+extern int optind;
+#endif
+#ifndef HAVE_OPTERR_DECLARATION
+extern int opterr;
+#endif
+
+#ifndef HAVE___PROGNAME_DECLARATION
+extern const char *__progname;
+#endif
+
+#ifndef HAVE_ENVIRON_DECLARATION
+extern char **environ;
+#endif
+
+#ifndef HAVE_GETIPNODEBYNAME
+struct hostent *
+getipnodebyname (const char *name, int af, int flags, int *error_num);
+#endif
+
+#ifndef HAVE_GETIPNODEBYADDR
+struct hostent *
+getipnodebyaddr (const void *src, size_t len, int af, int *error_num);
+#endif
+
+#ifndef HAVE_FREEHOSTENT
+void
+freehostent (struct hostent *h);
+#endif
+
+#ifndef HAVE_COPYHOSTENT
+struct hostent *
+copyhostent (const struct hostent *h);
+#endif
+
+#ifndef HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
+
+#ifndef HAVE_SA_FAMILY_T
+typedef unsigned short sa_family_t;
+#endif
+
+#ifdef HAVE_IPV6
+#define _SS_MAXSIZE sizeof(struct sockaddr_in6)
+#else
+#define _SS_MAXSIZE sizeof(struct sockaddr_in)
+#endif
+
+#define _SS_ALIGNSIZE sizeof(unsigned long)
+
+#if HAVE_STRUCT_SOCKADDR_SA_LEN
+
+typedef unsigned char roken_sa_family_t;
+
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (roken_sa_family_t) - sizeof(unsigned char))
+#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (roken_sa_family_t) + sizeof(unsigned char) + _SS_PAD1SIZE + _SS_ALIGNSIZE))
+
+struct sockaddr_storage {
+ unsigned char ss_len;
+ roken_sa_family_t ss_family;
+ char __ss_pad1[_SS_PAD1SIZE];
+ unsigned long __ss_align[_SS_PAD2SIZE / sizeof(unsigned long) + 1];
+};
+
+#else /* !HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+typedef unsigned short roken_sa_family_t;
+
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (roken_sa_family_t))
+#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (roken_sa_family_t) + _SS_PAD1SIZE + _SS_ALIGNSIZE))
+
+struct sockaddr_storage {
+ roken_sa_family_t ss_family;
+ char __ss_pad1[_SS_PAD1SIZE];
+ unsigned long __ss_align[_SS_PAD2SIZE / sizeof(unsigned long) + 1];
+};
+
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */
+
+#ifndef HAVE_STRUCT_ADDRINFO
+struct addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ char *ai_canonname;
+ struct sockaddr *ai_addr;
+ struct addrinfo *ai_next;
+};
+#endif
+
+#ifndef HAVE_GETADDRINFO
+int
+getaddrinfo(const char *nodename,
+ const char *servname,
+ const struct addrinfo *hints,
+ struct addrinfo **res);
+#endif
+
+#ifndef HAVE_GETNAMEINFO
+int getnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags);
+#endif
+
+#ifndef HAVE_FREEADDRINFO
+void
+freeaddrinfo(struct addrinfo *ai);
+#endif
+
+#ifndef HAVE_GAI_STRERROR
+char *
+gai_strerror(int ecode);
+#endif
+
+int
+getnameinfo_verified(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags);
+
+#ifndef HAVE_STRFTIME
+size_t
+strftime (char *buf, size_t maxsize, const char *format,
+ const struct tm *tm);
+#endif
+
+#ifndef HAVE_STRPTIME
+char *
+strptime (const char *buf, const char *format, struct tm *timeptr);
+#endif
+
+/*
+ * kludges and such
+ */
+
+#if 1
+int roken_gethostby_setup(const char*, const char*);
+struct hostent* roken_gethostbyname(const char*);
+struct hostent* roken_gethostbyaddr(const void*, size_t, int);
+#else
+#ifdef GETHOSTBYNAME_PROTO_COMPATIBLE
+#define roken_gethostbyname(x) gethostbyname(x)
+#else
+#define roken_gethostbyname(x) gethostbyname((char *)x)
+#endif
+
+#ifdef GETHOSTBYADDR_PROTO_COMPATIBLE
+#define roken_gethostbyaddr(a, l, t) gethostbyaddr(a, l, t)
+#else
+#define roken_gethostbyaddr(a, l, t) gethostbyaddr((char *)a, l, t)
+#endif
+#endif
+
+#ifdef GETSERVBYNAME_PROTO_COMPATIBLE
+#define roken_getservbyname(x,y) getservbyname(x,y)
+#else
+#define roken_getservbyname(x,y) getservbyname((char *)x, (char *)y)
+#endif
+
+#ifdef OPENLOG_PROTO_COMPATIBLE
+#define roken_openlog(a,b,c) openlog(a,b,c)
+#else
+#define roken_openlog(a,b,c) openlog((char *)a,b,c)
+#endif
+
+void set_progname(char *argv0);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/roken.mak b/crypto/heimdal/lib/roken/roken.mak
new file mode 100644
index 000000000000..da9a834e5551
--- /dev/null
+++ b/crypto/heimdal/lib/roken/roken.mak
@@ -0,0 +1,316 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on roken.dsp
+!IF "$(CFG)" == ""
+CFG=roken - Win32 Release
+!MESSAGE No configuration specified. Defaulting to roken - Win32 Release.
+!ENDIF
+
+!IF "$(CFG)" != "roken - Win32 Release" && "$(CFG)" != "roken - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "roken.mak" CFG="roken - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "roken - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "roken - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "roken - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+# Begin Custom Macros
+OutDir=.\.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\roken.dll"
+
+!ELSE
+
+ALL : "$(OUTDIR)\roken.dll"
+
+!ENDIF
+
+CLEAN :
+ -@erase "$(INTDIR)\base64.obj"
+ -@erase "$(INTDIR)\concat.obj"
+ -@erase "$(INTDIR)\gettimeofday.obj"
+ -@erase "$(INTDIR)\getuid.obj"
+ -@erase "$(INTDIR)\resolve.obj"
+ -@erase "$(INTDIR)\roken.res"
+ -@erase "$(INTDIR)\snprintf.obj"
+ -@erase "$(INTDIR)\strcasecmp.obj"
+ -@erase "$(INTDIR)\strtok_r.obj"
+ -@erase "$(INTDIR)\vc50.idb"
+ -@erase "$(OUTDIR)\roken.dll"
+ -@erase "$(OUTDIR)\roken.exp"
+ -@erase "$(OUTDIR)\roken.lib"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /MT /GX /O2 /I "..\krb" /I "..\des" /I "..\..\include" /I\
+ "..\..\include\win32" /I "." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
+ "HAVE_CONFIG_H" /Fp"$(INTDIR)\roken.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\"\
+ /FD /c
+CPP_OBJS=.\Release/
+CPP_SBRS=.
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\roken.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\roken.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo\
+ /base:"0x68e7780" /subsystem:windows /dll /incremental:no\
+ /pdb:"$(OUTDIR)\roken.pdb" /machine:I386 /def:".\roken.def"\
+ /out:"$(OUTDIR)\roken.dll" /implib:"$(OUTDIR)\roken.lib"
+DEF_FILE= \
+ ".\roken.def"
+LINK32_OBJS= \
+ "$(INTDIR)\base64.obj" \
+ "$(INTDIR)\concat.obj" \
+ "$(INTDIR)\gettimeofday.obj" \
+ "$(INTDIR)\getuid.obj" \
+ "$(INTDIR)\resolve.obj" \
+ "$(INTDIR)\roken.res" \
+ "$(INTDIR)\snprintf.obj" \
+ "$(INTDIR)\strcasecmp.obj" \
+ "$(INTDIR)\strtok_r.obj"
+
+"$(OUTDIR)\roken.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "roken - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+# Begin Custom Macros
+OutDir=.\.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\roken.dll"
+
+!ELSE
+
+ALL : "$(OUTDIR)\roken.dll"
+
+!ENDIF
+
+CLEAN :
+ -@erase "$(INTDIR)\base64.obj"
+ -@erase "$(INTDIR)\concat.obj"
+ -@erase "$(INTDIR)\gettimeofday.obj"
+ -@erase "$(INTDIR)\getuid.obj"
+ -@erase "$(INTDIR)\resolve.obj"
+ -@erase "$(INTDIR)\roken.res"
+ -@erase "$(INTDIR)\snprintf.obj"
+ -@erase "$(INTDIR)\strcasecmp.obj"
+ -@erase "$(INTDIR)\strtok_r.obj"
+ -@erase "$(INTDIR)\vc50.idb"
+ -@erase "$(INTDIR)\vc50.pdb"
+ -@erase "$(OUTDIR)\roken.dll"
+ -@erase "$(OUTDIR)\roken.exp"
+ -@erase "$(OUTDIR)\roken.ilk"
+ -@erase "$(OUTDIR)\roken.lib"
+ -@erase "$(OUTDIR)\roken.pdb"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /MDd /Gm /GX /Zi /Od /I "..\krb" /I "..\des" /I\
+ "..\..\include" /I "..\..\include\win32" /I "." /D "_DEBUG" /D "WIN32" /D\
+ "_WINDOWS" /D "HAVE_CONFIG_H" /Fp"$(INTDIR)\roken.pch" /YX /Fo"$(INTDIR)\\"\
+ /Fd"$(INTDIR)\\" /FD /c
+CPP_OBJS=.\Debug/
+CPP_SBRS=.
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\roken.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\roken.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo\
+ /subsystem:windows /dll /incremental:yes /pdb:"$(OUTDIR)\roken.pdb" /debug\
+ /machine:I386 /def:".\roken.def" /out:"$(OUTDIR)\roken.dll"\
+ /implib:"$(OUTDIR)\roken.lib"
+LINK32_OBJS= \
+ "$(INTDIR)\base64.obj" \
+ "$(INTDIR)\concat.obj" \
+ "$(INTDIR)\gettimeofday.obj" \
+ "$(INTDIR)\getuid.obj" \
+ "$(INTDIR)\resolve.obj" \
+ "$(INTDIR)\roken.res" \
+ "$(INTDIR)\snprintf.obj" \
+ "$(INTDIR)\strcasecmp.obj" \
+ "$(INTDIR)\strtok_r.obj"
+
+"$(OUTDIR)\roken.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+.c{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+
+!IF "$(CFG)" == "roken - Win32 Release" || "$(CFG)" == "roken - Win32 Debug"
+SOURCE=.\base64.c
+DEP_CPP_BASE6=\
+ "..\..\include\win32\config.h"\
+ ".\base64.h"\
+
+
+"$(INTDIR)\base64.obj" : $(SOURCE) $(DEP_CPP_BASE6) "$(INTDIR)"
+
+
+SOURCE=.\concat.c
+DEP_CPP_CONCA=\
+ "..\..\include\win32\config.h"\
+ "..\..\include\win32\roken.h"\
+ ".\err.h"\
+ ".\roken-common.h"\
+ {$(INCLUDE)}"sys\stat.h"\
+ {$(INCLUDE)}"sys\types.h"\
+
+
+"$(INTDIR)\concat.obj" : $(SOURCE) $(DEP_CPP_CONCA) "$(INTDIR)"
+
+
+SOURCE=.\gettimeofday.c
+DEP_CPP_GETTI=\
+ "..\..\include\win32\config.h"\
+ "..\..\include\win32\roken.h"\
+ ".\err.h"\
+ ".\roken-common.h"\
+ {$(INCLUDE)}"sys\stat.h"\
+ {$(INCLUDE)}"sys\types.h"\
+
+
+"$(INTDIR)\gettimeofday.obj" : $(SOURCE) $(DEP_CPP_GETTI) "$(INTDIR)"
+
+
+SOURCE=.\getuid.c
+DEP_CPP_GETUI=\
+ "..\..\include\win32\config.h"\
+ "..\..\include\win32\roken.h"\
+ ".\err.h"\
+ ".\roken-common.h"\
+ {$(INCLUDE)}"sys\stat.h"\
+ {$(INCLUDE)}"sys\types.h"\
+
+
+"$(INTDIR)\getuid.obj" : $(SOURCE) $(DEP_CPP_GETUI) "$(INTDIR)"
+
+
+SOURCE=.\resolve.c
+DEP_CPP_RESOL=\
+ "..\..\include\win32\config.h"\
+ "..\..\include\win32\roken.h"\
+ ".\err.h"\
+ ".\resolve.h"\
+ ".\roken-common.h"\
+ {$(INCLUDE)}"sys\stat.h"\
+ {$(INCLUDE)}"sys\types.h"\
+
+
+"$(INTDIR)\resolve.obj" : $(SOURCE) $(DEP_CPP_RESOL) "$(INTDIR)"
+
+
+SOURCE=.\snprintf.c
+DEP_CPP_SNPRI=\
+ "..\..\include\win32\config.h"\
+ "..\..\include\win32\roken.h"\
+ ".\err.h"\
+ ".\roken-common.h"\
+ {$(INCLUDE)}"sys\stat.h"\
+ {$(INCLUDE)}"sys\types.h"\
+
+
+"$(INTDIR)\snprintf.obj" : $(SOURCE) $(DEP_CPP_SNPRI) "$(INTDIR)"
+
+
+SOURCE=.\strcasecmp.c
+DEP_CPP_STRCA=\
+ "..\..\include\win32\config.h"\
+ {$(INCLUDE)}"sys\types.h"\
+
+
+"$(INTDIR)\strcasecmp.obj" : $(SOURCE) $(DEP_CPP_STRCA) "$(INTDIR)"
+
+
+SOURCE=.\strtok_r.c
+DEP_CPP_STRTO=\
+ "..\..\include\win32\config.h"\
+ "..\..\include\win32\roken.h"\
+ ".\err.h"\
+ ".\roken-common.h"\
+ {$(INCLUDE)}"sys\stat.h"\
+ {$(INCLUDE)}"sys\types.h"\
+
+
+"$(INTDIR)\strtok_r.obj" : $(SOURCE) $(DEP_CPP_STRTO) "$(INTDIR)"
+
+
+SOURCE=.\roken.rc
+
+"$(INTDIR)\roken.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+
+
+!ENDIF
+
diff --git a/crypto/heimdal/lib/roken/roken.rc b/crypto/heimdal/lib/roken/roken.rc
new file mode 100644
index 000000000000..e7e2f3e499ca
--- /dev/null
+++ b/crypto/heimdal/lib/roken/roken.rc
@@ -0,0 +1,105 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Swedish resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_SVE)
+#ifdef _WIN32
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Royal Institute of Technology (KTH)\0"
+ VALUE "FileDescription", "roken\0"
+ VALUE "FileVersion", "4, 0, 9, 9\0"
+ VALUE "InternalName", "roken\0"
+ VALUE "LegalCopyright", "Copyright © 1996 - 1998 Royal Institute of Technology (KTH)\0"
+ VALUE "OriginalFilename", "roken.dll\0"
+ VALUE "ProductName", "KTH Kerberos\0"
+ VALUE "ProductVersion", "4,0,9,9\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // Swedish resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/crypto/heimdal/lib/roken/roken_gethostby.c b/crypto/heimdal/lib/roken/roken_gethostby.c
new file mode 100644
index 000000000000..6df6c57dd765
--- /dev/null
+++ b/crypto/heimdal/lib/roken/roken_gethostby.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: roken_gethostby.c,v 1.5 1999/12/05 13:16:44 assar Exp $");
+#endif
+
+#include <roken.h>
+
+#undef roken_gethostbyname
+#undef roken_gethostbyaddr
+
+static struct sockaddr_in dns_addr;
+static char *dns_req;
+
+static int
+make_address(const char *address, struct in_addr *ip)
+{
+ if(inet_aton(address, ip) == 0){
+ /* try to resolve as hostname, it might work if the address we
+ are trying to lookup is local, for instance a web proxy */
+ struct hostent *he = gethostbyname(address);
+ if(he) {
+ unsigned char *p = (unsigned char*)he->h_addr;
+ ip->s_addr = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+setup_int(const char *proxy_host, short proxy_port,
+ const char *dns_host, short dns_port,
+ const char *dns_path)
+{
+ memset(&dns_addr, 0, sizeof(dns_addr));
+ if(dns_req)
+ free(dns_req);
+ if(proxy_host) {
+ if(make_address(proxy_host, &dns_addr.sin_addr) != 0)
+ return -1;
+ dns_addr.sin_port = htons(proxy_port);
+ asprintf(&dns_req, "http://%s:%d%s", dns_host, dns_port, dns_path);
+ } else {
+ if(make_address(dns_host, &dns_addr.sin_addr) != 0)
+ return -1;
+ dns_addr.sin_port = htons(dns_port);
+ asprintf(&dns_req, "%s", dns_path);
+ }
+ dns_addr.sin_family = AF_INET;
+ return 0;
+}
+
+static void
+split_spec(const char *spec, char **host, int *port, char **path, int def_port)
+{
+ char *p;
+ *host = strdup(spec);
+ p = strchr(*host, ':');
+ if(p) {
+ *p++ = '\0';
+ if(sscanf(p, "%d", port) != 1)
+ *port = def_port;
+ } else
+ *port = def_port;
+ p = strchr(p ? p : *host, '/');
+ if(p) {
+ if(path)
+ *path = strdup(p);
+ *p = '\0';
+ }else
+ if(path)
+ *path = NULL;
+}
+
+
+int
+roken_gethostby_setup(const char *proxy_spec, const char *dns_spec)
+{
+ char *proxy_host = NULL;
+ int proxy_port;
+ char *dns_host, *dns_path;
+ int dns_port;
+
+ int ret = -1;
+
+ split_spec(dns_spec, &dns_host, &dns_port, &dns_path, 80);
+ if(dns_path == NULL)
+ goto out;
+ if(proxy_spec)
+ split_spec(proxy_spec, &proxy_host, &proxy_port, NULL, 80);
+ ret = setup_int(proxy_host, proxy_port, dns_host, dns_port, dns_path);
+out:
+ free(proxy_host);
+ free(dns_host);
+ free(dns_path);
+ return ret;
+}
+
+
+/* Try to lookup a name or an ip-address using http as transport
+ mechanism. See the end of this file for an example program. */
+static struct hostent*
+roken_gethostby(const char *hostname)
+{
+ int s;
+ struct sockaddr_in sin;
+ char *request;
+ char buf[1024];
+ int offset = 0;
+ int n;
+ char *p, *foo;
+
+ if(dns_addr.sin_family == 0)
+ return NULL; /* no configured host */
+ sin = dns_addr;
+ asprintf(&request, "GET %s?%s HTTP/1.0\r\n\r\n", dns_req, hostname);
+ if(request == NULL)
+ return NULL;
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if(s < 0) {
+ free(request);
+ return NULL;
+ }
+ if(connect(s, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
+ close(s);
+ free(request);
+ return NULL;
+ }
+ if(write(s, request, strlen(request)) != strlen(request)) {
+ close(s);
+ free(request);
+ return NULL;
+ }
+ free(request);
+ while(1) {
+ n = read(s, buf + offset, sizeof(buf) - offset);
+ if(n <= 0)
+ break;
+ offset += n;
+ }
+ buf[offset] = '\0';
+ close(s);
+ p = strstr(buf, "\r\n\r\n"); /* find end of header */
+ if(p) p += 4;
+ else return NULL;
+ foo = NULL;
+ p = strtok_r(p, " \t\r\n", &foo);
+ if(p == NULL)
+ return NULL;
+ {
+ /* make a hostent to return */
+#define MAX_ADDRS 16
+ static struct hostent he;
+ static char addrs[4 * MAX_ADDRS];
+ static char *addr_list[MAX_ADDRS];
+ int num_addrs = 0;
+
+ he.h_name = p;
+ he.h_aliases = NULL;
+ he.h_addrtype = AF_INET;
+ he.h_length = 4;
+
+ while((p = strtok_r(NULL, " \t\r\n", &foo)) && num_addrs < MAX_ADDRS) {
+ struct in_addr ip;
+ inet_aton(p, &ip);
+ ip.s_addr = ntohl(ip.s_addr);
+ addr_list[num_addrs] = &addrs[num_addrs * 4];
+ addrs[num_addrs * 4 + 0] = (ip.s_addr >> 24) & 0xff;
+ addrs[num_addrs * 4 + 1] = (ip.s_addr >> 16) & 0xff;
+ addrs[num_addrs * 4 + 2] = (ip.s_addr >> 8) & 0xff;
+ addrs[num_addrs * 4 + 3] = (ip.s_addr >> 0) & 0xff;
+ addr_list[++num_addrs] = NULL;
+ }
+ he.h_addr_list = addr_list;
+ return &he;
+ }
+}
+
+struct hostent*
+roken_gethostbyname(const char *hostname)
+{
+ struct hostent *he;
+ he = gethostbyname(hostname);
+ if(he)
+ return he;
+ return roken_gethostby(hostname);
+}
+
+struct hostent*
+roken_gethostbyaddr(const void *addr, size_t len, int type)
+{
+ struct in_addr a;
+ const char *p;
+ struct hostent *he;
+ he = gethostbyaddr(addr, len, type);
+ if(he)
+ return he;
+ if(type != AF_INET || len != 4)
+ return NULL;
+ p = addr;
+ a.s_addr = htonl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+ return roken_gethostby(inet_ntoa(a));
+}
+
+#if 0
+
+/* this program can be used as a cgi `script' to lookup names and
+ ip-addresses */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <sys/param.h>
+
+int
+main(int argc, char **argv)
+{
+ char *query = getenv("QUERY_STRING");
+ char host[MAXHOSTNAMELEN];
+ int i;
+ struct hostent *he;
+
+ printf("Content-type: text/plain\n\n");
+ if(query == NULL)
+ exit(0);
+ he = gethostbyname(query);
+ strncpy(host, he->h_name, sizeof(host));
+ host[sizeof(host) - 1] = '\0';
+ he = gethostbyaddr(he->h_addr, he->h_length, AF_INET);
+ printf("%s\n", he->h_name);
+ for(i = 0; he->h_addr_list[i]; i++) {
+ struct in_addr ip;
+ unsigned char *p = (unsigned char*)he->h_addr_list[i];
+ ip.s_addr = htonl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+ printf("%s\n", inet_ntoa(ip));
+ }
+ exit(0);
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/sendmsg.c b/crypto/heimdal/lib/roken/sendmsg.c
new file mode 100644
index 000000000000..7075bf214211
--- /dev/null
+++ b/crypto/heimdal/lib/roken/sendmsg.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: sendmsg.c,v 1.4 1999/12/02 16:58:52 joda Exp $");
+#endif
+
+#include "roken.h"
+
+ssize_t
+sendmsg(int s, const struct msghdr *msg, int flags)
+{
+ ssize_t ret;
+ size_t tot = 0;
+ int i;
+ char *buf, *p;
+ struct iovec *iov = msg->msg_iov;
+
+ for(i = 0; i < msg->msg_iovlen; ++i)
+ tot += iov[i].iov_len;
+ buf = malloc(tot);
+ if (tot != 0 && buf == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ p = buf;
+ for (i = 0; i < msg->msg_iovlen; ++i) {
+ memcpy (p, iov[i].iov_base, iov[i].iov_len);
+ p += iov[i].iov_len;
+ }
+ ret = sendto (s, buf, tot, flags, msg->msg_name, msg->msg_namelen);
+ free (buf);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/setegid.c b/crypto/heimdal/lib/roken/setegid.c
new file mode 100644
index 000000000000..2f46fe4bf8ea
--- /dev/null
+++ b/crypto/heimdal/lib/roken/setegid.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: setegid.c,v 1.9 1999/12/02 16:58:52 joda Exp $");
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "roken.h"
+
+int
+setegid(gid_t egid)
+{
+#ifdef HAVE_SETREGID
+ return setregid(-1, egid);
+#endif
+
+#ifdef HAVE_SETRESGID
+ return setresgid(-1, egid, -1);
+#endif
+
+ return -1;
+}
diff --git a/crypto/heimdal/lib/roken/setenv.c b/crypto/heimdal/lib/roken/setenv.c
new file mode 100644
index 000000000000..15b58113ea8e
--- /dev/null
+++ b/crypto/heimdal/lib/roken/setenv.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: setenv.c,v 1.9 1999/12/02 16:58:52 joda Exp $");
+#endif
+
+#include "roken.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * This is the easy way out, use putenv to implement setenv. We might
+ * leak some memory but that is ok since we are usally about to exec
+ * anyway.
+ */
+
+int
+setenv(const char *var, const char *val, int rewrite)
+{
+ char *t;
+
+ if (!rewrite && getenv(var) != 0)
+ return 0;
+
+ asprintf (&t, "%s=%s", var, val);
+ if (t == NULL)
+ return -1;
+
+ if (putenv(t) == 0)
+ return 0;
+ else
+ return -1;
+}
diff --git a/crypto/heimdal/lib/roken/seteuid.c b/crypto/heimdal/lib/roken/seteuid.c
new file mode 100644
index 000000000000..ee68ba785e47
--- /dev/null
+++ b/crypto/heimdal/lib/roken/seteuid.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: seteuid.c,v 1.10 1999/12/02 16:58:52 joda Exp $");
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "roken.h"
+
+int
+seteuid(uid_t euid)
+{
+#ifdef HAVE_SETREUID
+ return setreuid(-1, euid);
+#endif
+
+#ifdef HAVE_SETRESUID
+ return setresuid(-1, euid, -1);
+#endif
+
+ return -1;
+}
diff --git a/crypto/heimdal/lib/roken/signal.c b/crypto/heimdal/lib/roken/signal.c
new file mode 100644
index 000000000000..85f36ee33d04
--- /dev/null
+++ b/crypto/heimdal/lib/roken/signal.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: signal.c,v 1.10 1999/12/14 01:37:58 assar Exp $");
+#endif
+
+#include <signal.h>
+
+/*
+ * We would like to always use this signal but there is a link error
+ * on NEXTSTEP
+ */
+#if !defined(NeXT) && !defined(__APPLE__)
+/*
+ * Bugs:
+ *
+ * Do we need any extra hacks for SIGCLD and/or SIGCHLD?
+ */
+
+typedef RETSIGTYPE (*SigAction)(/* int??? */);
+
+SigAction
+signal(int iSig, SigAction pAction)
+{
+ struct sigaction saNew, saOld;
+
+ saNew.sa_handler = pAction;
+ sigemptyset(&saNew.sa_mask);
+ saNew.sa_flags = 0;
+
+ if (iSig == SIGALRM)
+ {
+#ifdef SA_INTERRUPT
+ saNew.sa_flags |= SA_INTERRUPT;
+#endif
+ }
+ else
+ {
+#ifdef SA_RESTART
+ saNew.sa_flags |= SA_RESTART;
+#endif
+ }
+
+ if (sigaction(iSig, &saNew, &saOld) < 0)
+ return(SIG_ERR);
+
+ return(saOld.sa_handler);
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/simple_exec.c b/crypto/heimdal/lib/roken/simple_exec.c
new file mode 100644
index 000000000000..426f494fcc04
--- /dev/null
+++ b/crypto/heimdal/lib/roken/simple_exec.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: simple_exec.c,v 1.6 1999/12/02 16:58:52 joda Exp $");
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+#include <roken.h>
+
+#define EX_NOEXEC 126
+#define EX_NOTFOUND 127
+
+/* return values:
+ -1 on `unspecified' system errors
+ -2 on fork failures
+ -3 on waitpid errors
+ 0- is return value from subprocess
+ 126 if the program couldn't be executed
+ 127 if the program couldn't be found
+ 128- is 128 + signal that killed subprocess
+ */
+
+static int
+check_status(pid_t pid)
+{
+ while(1) {
+ int status;
+
+ while(waitpid(pid, &status, 0) < 0)
+ if (errno != EINTR)
+ return -3;
+ if(WIFSTOPPED(status))
+ continue;
+ if(WIFEXITED(status))
+ return WEXITSTATUS(status);
+ if(WIFSIGNALED(status))
+ return WTERMSIG(status) + 128;
+ }
+}
+
+int
+simple_execvp(const char *file, char *const args[])
+{
+ pid_t pid = fork();
+ switch(pid){
+ case -1:
+ return -2;
+ case 0:
+ execvp(file, args);
+ exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
+ default:
+ return check_status(pid);
+ }
+}
+
+/* gee, I'd like a execvpe */
+int
+simple_execve(const char *file, char *const args[], char *const envp[])
+{
+ pid_t pid = fork();
+ switch(pid){
+ case -1:
+ return -2;
+ case 0:
+ execve(file, args, envp);
+ exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
+ default:
+ return check_status(pid);
+ }
+}
+
+static char **
+collect_args(va_list *ap)
+{
+ char **argv = NULL;
+ int argc = 0, i = 0;
+ do {
+ if(i == argc) {
+ /* realloc argv */
+ char **tmp = realloc(argv, (argc + 5) * sizeof(*argv));
+ if(tmp == NULL) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ argv = tmp;
+ argc += 5;
+ }
+ argv[i++] = va_arg(*ap, char*);
+ } while(argv[i - 1] != NULL);
+ return argv;
+}
+
+int
+simple_execlp(const char *file, ...)
+{
+ va_list ap;
+ char **argv;
+ int ret;
+
+ va_start(ap, file);
+ argv = collect_args(&ap);
+ va_end(ap);
+ if(argv == NULL)
+ return -1;
+ ret = simple_execvp(file, argv);
+ free(argv);
+ return ret;
+}
+
+int
+simple_execle(const char *file, ... /* ,char *const envp[] */)
+{
+ va_list ap;
+ char **argv;
+ char *const* envp;
+ int ret;
+
+ va_start(ap, file);
+ argv = collect_args(&ap);
+ envp = va_arg(ap, char **);
+ va_end(ap);
+ if(argv == NULL)
+ return -1;
+ ret = simple_execve(file, argv, envp);
+ free(argv);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/snprintf.c b/crypto/heimdal/lib/roken/snprintf.c
new file mode 100644
index 000000000000..0333e8755e8e
--- /dev/null
+++ b/crypto/heimdal/lib/roken/snprintf.c
@@ -0,0 +1,619 @@
+/*
+ * Copyright (c) 1995-1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: snprintf.c,v 1.24 1999/12/02 16:58:52 joda Exp $");
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <roken.h>
+
+enum format_flags {
+ minus_flag = 1,
+ plus_flag = 2,
+ space_flag = 4,
+ alternate_flag = 8,
+ zero_flag = 16
+};
+
+/*
+ * Common state
+ */
+
+struct state {
+ unsigned char *str;
+ unsigned char *s;
+ unsigned char *theend;
+ size_t sz;
+ size_t max_sz;
+ int (*append_char)(struct state *, unsigned char);
+ int (*reserve)(struct state *, size_t);
+ /* XXX - methods */
+};
+
+#ifndef HAVE_VSNPRINTF
+static int
+sn_reserve (struct state *state, size_t n)
+{
+ return state->s + n > state->theend;
+}
+
+static int
+sn_append_char (struct state *state, unsigned char c)
+{
+ if (sn_reserve (state, 1)) {
+ return 1;
+ } else {
+ *state->s++ = c;
+ return 0;
+ }
+}
+#endif
+
+static int
+as_reserve (struct state *state, size_t n)
+{
+ if (state->s + n > state->theend) {
+ int off = state->s - state->str;
+ unsigned char *tmp;
+
+ if (state->max_sz && state->sz >= state->max_sz)
+ return 1;
+
+ state->sz = max(state->sz * 2, state->sz + n);
+ if (state->max_sz)
+ state->sz = min(state->sz, state->max_sz);
+ tmp = realloc (state->str, state->sz);
+ if (tmp == NULL)
+ return 1;
+ state->str = tmp;
+ state->s = state->str + off;
+ state->theend = state->str + state->sz - 1;
+ }
+ return 0;
+}
+
+static int
+as_append_char (struct state *state, unsigned char c)
+{
+ if(as_reserve (state, 1))
+ return 1;
+ else {
+ *state->s++ = c;
+ return 0;
+ }
+}
+
+static int
+append_number(struct state *state,
+ unsigned long num, unsigned base, char *rep,
+ int width, int prec, int flags, int minusp)
+{
+ int len = 0;
+ int i;
+
+ /* given precision, ignore zero flag */
+ if(prec != -1)
+ flags &= ~zero_flag;
+ else
+ prec = 1;
+ /* zero value with zero precision -> "" */
+ if(prec == 0 && num == 0)
+ return 0;
+ do{
+ if((*state->append_char)(state, rep[num % base]))
+ return 1;
+ len++;
+ num /= base;
+ }while(num);
+ prec -= len;
+ /* pad with prec zeros */
+ while(prec-- > 0){
+ if((*state->append_char)(state, '0'))
+ return 1;
+ len++;
+ }
+ /* add length of alternate prefix (added later) to len */
+ if(flags & alternate_flag && (base == 16 || base == 8))
+ len += base / 8;
+ /* pad with zeros */
+ if(flags & zero_flag){
+ width -= len;
+ if(minusp || (flags & space_flag) || (flags & plus_flag))
+ width--;
+ while(width-- > 0){
+ if((*state->append_char)(state, '0'))
+ return 1;
+ len++;
+ }
+ }
+ /* add alternate prefix */
+ if(flags & alternate_flag && (base == 16 || base == 8)){
+ if(base == 16)
+ if((*state->append_char)(state, rep[10] + 23)) /* XXX */
+ return 1;
+ if((*state->append_char)(state, '0'))
+ return 1;
+ }
+ /* add sign */
+ if(minusp){
+ if((*state->append_char)(state, '-'))
+ return 1;
+ len++;
+ } else if(flags & plus_flag) {
+ if((*state->append_char)(state, '+'))
+ return 1;
+ len++;
+ } else if(flags & space_flag) {
+ if((*state->append_char)(state, ' '))
+ return 1;
+ len++;
+ }
+ if(flags & minus_flag)
+ /* swap before padding with spaces */
+ for(i = 0; i < len / 2; i++){
+ char c = state->s[-i-1];
+ state->s[-i-1] = state->s[-len+i];
+ state->s[-len+i] = c;
+ }
+ width -= len;
+ while(width-- > 0){
+ if((*state->append_char)(state, ' '))
+ return 1;
+ len++;
+ }
+ if(!(flags & minus_flag))
+ /* swap after padding with spaces */
+ for(i = 0; i < len / 2; i++){
+ char c = state->s[-i-1];
+ state->s[-i-1] = state->s[-len+i];
+ state->s[-len+i] = c;
+ }
+
+ return 0;
+}
+
+static int
+append_string (struct state *state,
+ unsigned char *arg,
+ int width,
+ int prec,
+ int flags)
+{
+ if(prec != -1)
+ width -= prec;
+ else
+ width -= strlen((char *)arg);
+ if(!(flags & minus_flag))
+ while(width-- > 0)
+ if((*state->append_char) (state, ' '))
+ return 1;
+ if (prec != -1) {
+ while (*arg && prec--)
+ if ((*state->append_char) (state, *arg++))
+ return 1;
+ } else {
+ while (*arg)
+ if ((*state->append_char) (state, *arg++))
+ return 1;
+ }
+ if(flags & minus_flag)
+ while(width-- > 0)
+ if((*state->append_char) (state, ' '))
+ return 1;
+ return 0;
+}
+
+static int
+append_char(struct state *state,
+ unsigned char arg,
+ int width,
+ int flags)
+{
+ while(!(flags & minus_flag) && --width > 0)
+ if((*state->append_char) (state, ' '))
+ return 1;
+
+ if((*state->append_char) (state, arg))
+ return 1;
+ while((flags & minus_flag) && --width > 0)
+ if((*state->append_char) (state, ' '))
+ return 1;
+
+ return 0;
+}
+
+/*
+ * This can't be made into a function...
+ */
+
+#define PARSE_INT_FORMAT(res, arg, unsig) \
+if (long_flag) \
+ res = (unsig long)va_arg(arg, unsig long); \
+else if (short_flag) \
+ res = (unsig short)va_arg(arg, unsig short); \
+else \
+ res = (unsig int)va_arg(arg, unsig int)
+
+/*
+ * zyxprintf - return 0 or -1
+ */
+
+static int
+xyzprintf (struct state *state, const char *char_format, va_list ap)
+{
+ const unsigned char *format = (const unsigned char *)char_format;
+ unsigned char c;
+
+ while((c = *format++)) {
+ if (c == '%') {
+ int flags = 0;
+ int width = 0;
+ int prec = -1;
+ int long_flag = 0;
+ int short_flag = 0;
+
+ /* flags */
+ while((c = *format++)){
+ if(c == '-')
+ flags |= minus_flag;
+ else if(c == '+')
+ flags |= plus_flag;
+ else if(c == ' ')
+ flags |= space_flag;
+ else if(c == '#')
+ flags |= alternate_flag;
+ else if(c == '0')
+ flags |= zero_flag;
+ else
+ break;
+ }
+
+ if((flags & space_flag) && (flags & plus_flag))
+ flags ^= space_flag;
+
+ if((flags & minus_flag) && (flags & zero_flag))
+ flags ^= zero_flag;
+
+ /* width */
+ if (isdigit(c))
+ do {
+ width = width * 10 + c - '0';
+ c = *format++;
+ } while(isdigit(c));
+ else if(c == '*') {
+ width = va_arg(ap, int);
+ c = *format++;
+ }
+
+ /* precision */
+ if (c == '.') {
+ prec = 0;
+ c = *format++;
+ if (isdigit(c))
+ do {
+ prec = prec * 10 + c - '0';
+ c = *format++;
+ } while(isdigit(c));
+ else if (c == '*') {
+ prec = va_arg(ap, int);
+ c = *format++;
+ }
+ }
+
+ /* size */
+
+ if (c == 'h') {
+ short_flag = 1;
+ c = *format++;
+ } else if (c == 'l') {
+ long_flag = 1;
+ c = *format++;
+ }
+
+ switch (c) {
+ case 'c' :
+ if(append_char(state, va_arg(ap, int), width, flags))
+ return -1;
+ break;
+ case 's' :
+ if (append_string(state,
+ va_arg(ap, unsigned char*),
+ width,
+ prec,
+ flags))
+ return -1;
+ break;
+ case 'd' :
+ case 'i' : {
+ long arg;
+ unsigned long num;
+ int minusp = 0;
+
+ PARSE_INT_FORMAT(arg, ap, signed);
+
+ if (arg < 0) {
+ minusp = 1;
+ num = -arg;
+ } else
+ num = arg;
+
+ if (append_number (state, num, 10, "0123456789",
+ width, prec, flags, minusp))
+ return -1;
+ break;
+ }
+ case 'u' : {
+ unsigned long arg;
+
+ PARSE_INT_FORMAT(arg, ap, unsigned);
+
+ if (append_number (state, arg, 10, "0123456789",
+ width, prec, flags, 0))
+ return -1;
+ break;
+ }
+ case 'o' : {
+ unsigned long arg;
+
+ PARSE_INT_FORMAT(arg, ap, unsigned);
+
+ if (append_number (state, arg, 010, "01234567",
+ width, prec, flags, 0))
+ return -1;
+ break;
+ }
+ case 'x' : {
+ unsigned long arg;
+
+ PARSE_INT_FORMAT(arg, ap, unsigned);
+
+ if (append_number (state, arg, 0x10, "0123456789abcdef",
+ width, prec, flags, 0))
+ return -1;
+ break;
+ }
+ case 'X' :{
+ unsigned long arg;
+
+ PARSE_INT_FORMAT(arg, ap, unsigned);
+
+ if (append_number (state, arg, 0x10, "0123456789ABCDEF",
+ width, prec, flags, 0))
+ return -1;
+ break;
+ }
+ case 'p' : {
+ unsigned long arg = (unsigned long)va_arg(ap, void*);
+
+ if (append_number (state, arg, 0x10, "0123456789ABCDEF",
+ width, prec, flags, 0))
+ return -1;
+ break;
+ }
+ case 'n' : {
+ int *arg = va_arg(ap, int*);
+ *arg = state->s - state->str;
+ break;
+ }
+ case '\0' :
+ --format;
+ /* FALLTHROUGH */
+ case '%' :
+ if ((*state->append_char)(state, c))
+ return -1;
+ break;
+ default :
+ if ( (*state->append_char)(state, '%')
+ || (*state->append_char)(state, c))
+ return -1;
+ break;
+ }
+ } else
+ if ((*state->append_char) (state, c))
+ return -1;
+ }
+ return 0;
+}
+
+#ifndef HAVE_SNPRINTF
+int
+snprintf (char *str, size_t sz, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+ ret = vsnprintf (str, sz, format, args);
+
+#ifdef PARANOIA
+ {
+ int ret2;
+ char *tmp;
+
+ tmp = malloc (sz);
+ if (tmp == NULL)
+ abort ();
+
+ ret2 = vsprintf (tmp, format, args);
+ if (ret != ret2 || strcmp(str, tmp))
+ abort ();
+ free (tmp);
+ }
+#endif
+
+ va_end(args);
+ return ret;
+}
+#endif
+
+#ifndef HAVE_ASPRINTF
+int
+asprintf (char **ret, const char *format, ...)
+{
+ va_list args;
+ int val;
+
+ va_start(args, format);
+ val = vasprintf (ret, format, args);
+
+#ifdef PARANOIA
+ {
+ int ret2;
+ char *tmp;
+ tmp = malloc (val + 1);
+ if (tmp == NULL)
+ abort ();
+
+ ret2 = vsprintf (tmp, format, args);
+ if (val != ret2 || strcmp(*ret, tmp))
+ abort ();
+ free (tmp);
+ }
+#endif
+
+ va_end(args);
+ return val;
+}
+#endif
+
+#ifndef HAVE_ASNPRINTF
+int
+asnprintf (char **ret, size_t max_sz, const char *format, ...)
+{
+ va_list args;
+ int val;
+
+ va_start(args, format);
+ val = vasnprintf (ret, max_sz, format, args);
+
+#ifdef PARANOIA
+ {
+ int ret2;
+ char *tmp;
+ tmp = malloc (val + 1);
+ if (tmp == NULL)
+ abort ();
+
+ ret2 = vsprintf (tmp, format, args);
+ if (val != ret2 || strcmp(*ret, tmp))
+ abort ();
+ free (tmp);
+ }
+#endif
+
+ va_end(args);
+ return val;
+}
+#endif
+
+#ifndef HAVE_VASPRINTF
+int
+vasprintf (char **ret, const char *format, va_list args)
+{
+ return vasnprintf (ret, 0, format, args);
+}
+#endif
+
+
+#ifndef HAVE_VASNPRINTF
+int
+vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
+{
+ int st;
+ size_t len;
+ struct state state;
+
+ state.max_sz = max_sz;
+ state.sz = 1;
+ state.str = malloc(state.sz);
+ if (state.str == NULL) {
+ *ret = NULL;
+ return -1;
+ }
+ state.s = state.str;
+ state.theend = state.s + state.sz - 1;
+ state.append_char = as_append_char;
+ state.reserve = as_reserve;
+
+ st = xyzprintf (&state, format, args);
+ if (st) {
+ free (state.str);
+ *ret = NULL;
+ return -1;
+ } else {
+ char *tmp;
+
+ *state.s = '\0';
+ len = state.s - state.str;
+ tmp = realloc (state.str, len+1);
+ if (tmp == NULL) {
+ free (state.str);
+ *ret = NULL;
+ return -1;
+ }
+ *ret = tmp;
+ return len;
+ }
+}
+#endif
+
+#ifndef HAVE_VSNPRINTF
+int
+vsnprintf (char *str, size_t sz, const char *format, va_list args)
+{
+ struct state state;
+ int ret;
+ unsigned char *ustr = (unsigned char *)str;
+
+ state.max_sz = 0;
+ state.sz = sz;
+ state.str = ustr;
+ state.s = ustr;
+ state.theend = ustr + sz - 1;
+ state.append_char = sn_append_char;
+ state.reserve = sn_reserve;
+
+ ret = xyzprintf (&state, format, args);
+ *state.s = '\0';
+ if (ret)
+ return sz;
+ else
+ return state.s - state.str;
+}
+#endif
+
diff --git a/crypto/heimdal/lib/roken/socket.c b/crypto/heimdal/lib/roken/socket.c
new file mode 100644
index 000000000000..6e9c3dfe9b0a
--- /dev/null
+++ b/crypto/heimdal/lib/roken/socket.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: socket.c,v 1.3 1999/12/02 16:58:52 joda Exp $");
+#endif
+
+#include <string.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
+
+#include <roken.h>
+
+#include <err.h>
+
+/*
+ * Set `sa' to the unitialized address of address family `af'
+ */
+
+void
+socket_set_any (struct sockaddr *sa, int af)
+{
+ switch (af) {
+ case AF_INET : {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ memset (sin, 0, sizeof(*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_port = 0;
+ sin->sin_addr.s_addr = INADDR_ANY;
+ break;
+ }
+#ifdef HAVE_IPV6
+ case AF_INET6 : {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ memset (sin6, 0, sizeof(*sin6));
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = 0;
+ sin6->sin6_addr = in6addr_any;
+ break;
+ }
+#endif
+ default :
+ errx (1, "unknown address family %d", sa->sa_family);
+ break;
+ }
+}
+
+/*
+ * set `sa' to (`ptr', `port')
+ */
+
+void
+socket_set_address_and_port (struct sockaddr *sa, const void *ptr, int port)
+{
+ switch (sa->sa_family) {
+ case AF_INET : {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ memset (sin, 0, sizeof(*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ memcpy (&sin->sin_addr, ptr, sizeof(struct in_addr));
+ break;
+ }
+#ifdef HAVE_IPV6
+ case AF_INET6 : {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ memset (sin6, 0, sizeof(*sin6));
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = port;
+ memcpy (&sin6->sin6_addr, ptr, sizeof(struct in6_addr));
+ break;
+ }
+#endif
+ default :
+ errx (1, "unknown address family %d", sa->sa_family);
+ break;
+ }
+}
+
+/*
+ * Return the size of an address of the type in `sa'
+ */
+
+size_t
+socket_addr_size (const struct sockaddr *sa)
+{
+ switch (sa->sa_family) {
+ case AF_INET :
+ return sizeof(struct in_addr);
+#ifdef HAVE_IPV6
+ case AF_INET6 :
+ return sizeof(struct in6_addr);
+#endif
+ default :
+ errx (1, "unknown address family %d", sa->sa_family);
+ break;
+ }
+}
+
+/*
+ * Return the size of a `struct sockaddr' in `sa'.
+ */
+
+size_t
+socket_sockaddr_size (const struct sockaddr *sa)
+{
+ switch (sa->sa_family) {
+ case AF_INET :
+ return sizeof(struct sockaddr_in);
+#ifdef HAVE_IPV6
+ case AF_INET6 :
+ return sizeof(struct sockaddr_in6);
+#endif
+ default :
+ errx (1, "unknown address family %d", sa->sa_family);
+ break;
+ }
+}
+
+/*
+ * Return the binary address of `sa'.
+ */
+
+void *
+socket_get_address (struct sockaddr *sa)
+{
+ switch (sa->sa_family) {
+ case AF_INET : {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ return &sin->sin_addr;
+ }
+#ifdef HAVE_IPV6
+ case AF_INET6 : {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+ return &sin6->sin6_addr;
+ }
+#endif
+ default :
+ errx (1, "unknown address family %d", sa->sa_family);
+ break;
+ }
+}
+
+/*
+ * Return the port number from `sa'.
+ */
+
+int
+socket_get_port (const struct sockaddr *sa)
+{
+ switch (sa->sa_family) {
+ case AF_INET : {
+ const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
+ return sin->sin_port;
+ }
+#ifdef HAVE_IPV6
+ case AF_INET6 : {
+ const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+ return sin6->sin6_port;
+ }
+#endif
+ default :
+ errx (1, "unknown address family %d", sa->sa_family);
+ break;
+ }
+}
+
+/*
+ * Set the port in `sa' to `port'.
+ */
+
+void
+socket_set_port (struct sockaddr *sa, int port)
+{
+ switch (sa->sa_family) {
+ case AF_INET : {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ sin->sin_port = port;
+ break;
+ }
+#ifdef HAVE_IPV6
+ case AF_INET6 : {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+ sin6->sin6_port = port;
+ break;
+ }
+#endif
+ default :
+ errx (1, "unknown address family %d", sa->sa_family);
+ break;
+ }
+}
+
+/*
+ * Enable debug on `sock'.
+ */
+
+void
+socket_set_debug (int sock)
+{
+ int on = 1;
+
+#if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT)
+ if (setsockopt (sock, SOL_SOCKET, SO_DEBUG, (void *) &on, sizeof (on)) < 0)
+ warn ("setsockopt SO_DEBUG (ignored)");
+#endif
+}
+
+/*
+ * Set the type-of-service of `sock' to `tos'.
+ */
+
+void
+socket_set_tos (int sock, int tos)
+{
+#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
+ if (setsockopt (sock, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof (int)) < 0)
+ warn ("setsockopt TOS (ignored)");
+#endif
+}
+
+/*
+ * set the reuse of addresses on `sock' to `val'.
+ */
+
+void
+socket_set_reuseaddr (int sock, int val)
+{
+#if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT)
+ if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val,
+ sizeof(val)) < 0)
+ err (1, "setsockopt SO_REUSEADDR");
+#endif
+}
diff --git a/crypto/heimdal/lib/roken/strcasecmp.c b/crypto/heimdal/lib/roken/strcasecmp.c
new file mode 100644
index 000000000000..b5e20e75caf2
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strcasecmp.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strcasecmp.c,v 1.9 1999/12/02 16:58:52 joda Exp $");
+#endif
+
+#include <string.h>
+#include <ctype.h>
+#include <stddef.h>
+#include "roken.h"
+
+#ifndef HAVE_STRCASECMP
+
+int
+strcasecmp(const char *s1, const char *s2)
+{
+ while(toupper(*s1) == toupper(*s2)) {
+ if(*s1 == '\0')
+ return 0;
+ s1++;
+ s2++;
+ }
+ return toupper(*s1) - toupper(*s2);
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/strdup.c b/crypto/heimdal/lib/roken/strdup.c
new file mode 100644
index 000000000000..87fb43eb7d6e
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strdup.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strdup.c,v 1.10 1999/12/02 16:58:53 joda Exp $");
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef HAVE_STRDUP
+char *
+strdup(const char *old)
+{
+ char *t = malloc(strlen(old)+1);
+ if (t != 0)
+ strcpy(t, old);
+ return t;
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/strerror.c b/crypto/heimdal/lib/roken/strerror.c
new file mode 100644
index 000000000000..21936d71630b
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strerror.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strerror.c,v 1.10 1999/12/02 16:58:53 joda Exp $");
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+char*
+strerror(int eno)
+{
+ static char emsg[1024];
+
+ if(eno < 0 || eno >= sys_nerr)
+ snprintf(emsg, sizeof(emsg), "Error %d occurred.", eno);
+ else
+ snprintf(emsg, sizeof(emsg), "%s", sys_errlist[eno]);
+
+ return emsg;
+}
diff --git a/crypto/heimdal/lib/roken/strftime.c b/crypto/heimdal/lib/roken/strftime.c
new file mode 100644
index 000000000000..b90614bb4c4e
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strftime.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+RCSID("$Id: strftime.c,v 1.10 1999/11/13 04:18:33 assar Exp $");
+
+static const char *abb_weekdays[] = {
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+};
+
+static const char *full_weekdays[] = {
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+};
+
+static const char *abb_month[] = {
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+};
+
+static const char *full_month[] = {
+ "January",
+ "February",
+ "Mars",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+};
+
+static const char *ampm[] = {
+ "AM",
+ "PM"
+};
+
+/*
+ * Convert hour in [0, 24] to [12 1 - 11 12 1 - 11 12]
+ */
+
+static int
+hour_24to12 (int hour)
+{
+ int ret = hour % 12;
+
+ if (ret == 0)
+ ret = 12;
+ return ret;
+}
+
+/*
+ * Return AM or PM for `hour'
+ */
+
+static const char *
+hour_to_ampm (int hour)
+{
+ return ampm[hour / 12];
+}
+
+/*
+ * Return the week number of `tm' (Sunday being the first day of the week)
+ * as [0, 53]
+ */
+
+static int
+week_number_sun (const struct tm *tm)
+{
+ return (tm->tm_yday + 7 - (tm->tm_yday % 7 - tm->tm_wday + 7) % 7) / 7;
+}
+
+/*
+ * Return the week number of `tm' (Monday being the first day of the week)
+ * as [0, 53]
+ */
+
+static int
+week_number_mon (const struct tm *tm)
+{
+ int wday = (tm->tm_wday + 6) % 7;
+
+ return (tm->tm_yday + 7 - (tm->tm_yday % 7 - wday + 7) % 7) / 7;
+}
+
+/*
+ * Return the week number of `tm' (Monday being the first day of the
+ * week) as [01, 53]. Week number one is the one that has four or more
+ * days in that year.
+ */
+
+static int
+week_number_mon4 (const struct tm *tm)
+{
+ int wday = (tm->tm_wday + 6) % 7;
+ int w1day = (wday - tm->tm_yday % 7 + 7) % 7;
+ int ret;
+
+ ret = (tm->tm_yday + w1day) / 7;
+ if (w1day >= 4)
+ --ret;
+ if (ret == -1)
+ ret = 53;
+ else
+ ++ret;
+ return ret;
+}
+
+/*
+ *
+ */
+
+size_t
+strftime (char *buf, size_t maxsize, const char *format,
+ const struct tm *tm)
+{
+ size_t n = 0;
+ size_t ret;
+
+ while (*format != '\0' && n < maxsize) {
+ if (*format == '%') {
+ ++format;
+ if(*format == 'E' || *format == 'O')
+ ++format;
+ switch (*format) {
+ case 'a' :
+ ret = snprintf (buf, maxsize - n,
+ "%s", abb_weekdays[tm->tm_wday]);
+ break;
+ case 'A' :
+ ret = snprintf (buf, maxsize - n,
+ "%s", full_weekdays[tm->tm_wday]);
+ break;
+ case 'h' :
+ case 'b' :
+ ret = snprintf (buf, maxsize - n,
+ "%s", abb_month[tm->tm_mon]);
+ break;
+ case 'B' :
+ ret = snprintf (buf, maxsize - n,
+ "%s", full_month[tm->tm_mon]);
+ break;
+ case 'c' :
+ ret = snprintf (buf, maxsize - n,
+ "%d:%02d:%02d %02d:%02d:%02d",
+ tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
+ break;
+ case 'C' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d", (tm->tm_year + 1900) / 100);
+ break;
+ case 'd' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d", tm->tm_mday);
+ break;
+ case 'D' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d/%02d/%02d",
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ (tm->tm_year + 1900) % 100);
+ break;
+ case 'e' :
+ ret = snprintf (buf, maxsize - n,
+ "%2d", tm->tm_mday);
+ break;
+ case 'F':
+ ret = snprintf (buf, maxsize - n,
+ "%04d-%02d-%02d", tm->tm_year + 1900,
+ tm->tm_mon + 1, tm->tm_mday);
+ break;
+ case 'g':
+ /* last two digits of week-based year */
+ abort();
+ case 'G':
+ /* week-based year */
+ abort();
+ case 'H' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d", tm->tm_hour);
+ break;
+ case 'I' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d",
+ hour_24to12 (tm->tm_hour));
+ break;
+ case 'j' :
+ ret = snprintf (buf, maxsize - n,
+ "%03d", tm->tm_yday + 1);
+ break;
+ case 'k' :
+ ret = snprintf (buf, maxsize - n,
+ "%2d", tm->tm_hour);
+ break;
+ case 'l' :
+ ret = snprintf (buf, maxsize - n,
+ "%2d",
+ hour_24to12 (tm->tm_hour));
+ break;
+ case 'm' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d", tm->tm_mon + 1);
+ break;
+ case 'M' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d", tm->tm_min);
+ break;
+ case 'n' :
+ ret = snprintf (buf, maxsize - n, "\n");
+ break;
+ case 'p' :
+ ret = snprintf (buf, maxsize - n, "%s",
+ hour_to_ampm (tm->tm_hour));
+ break;
+ case 'r' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d:%02d:%02d %s",
+ hour_24to12 (tm->tm_hour),
+ tm->tm_min,
+ tm->tm_sec,
+ hour_to_ampm (tm->tm_hour));
+ break;
+ case 'R' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d:%02d",
+ tm->tm_hour,
+ tm->tm_min);
+
+ case 's' :
+ ret = snprintf (buf, maxsize - n,
+ "%d", (int)mktime((struct tm *)tm));
+ break;
+ case 'S' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d", tm->tm_sec);
+ break;
+ case 't' :
+ ret = snprintf (buf, maxsize - n, "\t");
+ break;
+ case 'T' :
+ case 'X' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d:%02d:%02d",
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
+ break;
+ case 'u' :
+ ret = snprintf (buf, maxsize - n,
+ "%d", (tm->tm_wday == 0) ? 7 : tm->tm_wday);
+ break;
+ case 'U' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d", week_number_sun (tm));
+ break;
+ case 'V' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d", week_number_mon4 (tm));
+ break;
+ case 'w' :
+ ret = snprintf (buf, maxsize - n,
+ "%d", tm->tm_wday);
+ break;
+ case 'W' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d", week_number_mon (tm));
+ break;
+ case 'x' :
+ ret = snprintf (buf, maxsize - n,
+ "%d:%02d:%02d",
+ tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday);
+ break;
+ case 'y' :
+ ret = snprintf (buf, maxsize - n,
+ "%02d", (tm->tm_year + 1900) % 100);
+ break;
+ case 'Y' :
+ ret = snprintf (buf, maxsize - n,
+ "%d", tm->tm_year + 1900);
+ break;
+ case 'z':
+ ret = snprintf (buf, maxsize - n,
+ "%ld",
+#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
+ (long)tm->tm_gmtoff
+#elif defined(HAVE_TIMEZONE)
+ tm->tm_isdst ?
+ (long)altzone :
+ (long)timezone
+#else
+#error Where in timezone chaos are you?
+#endif
+ );
+ break;
+ case 'Z' :
+ ret = snprintf (buf, maxsize - n,
+ "%s",
+
+#if defined(HAVE_STRUCT_TM_TM_ZONE)
+ tm->tm_zone
+#elif defined(HAVE_TIMEZONE)
+ tzname[tm->tm_isdst]
+#else
+#error what?
+#endif
+ );
+ break;
+ case '\0' :
+ --format;
+ /* FALLTHROUGH */
+ case '%' :
+ ret = snprintf (buf, maxsize - n,
+ "%%");
+ break;
+ default :
+ ret = snprintf (buf, maxsize - n,
+ "%%%c", *format);
+ break;
+ }
+ if (ret >= maxsize - n)
+ return 0;
+ n += ret;
+ buf += ret;
+ ++format;
+ } else {
+ *buf++ = *format++;
+ ++n;
+ }
+ }
+ *buf++ = '\0';
+ return n;
+}
diff --git a/crypto/heimdal/lib/roken/strlcat.c b/crypto/heimdal/lib/roken/strlcat.c
new file mode 100644
index 000000000000..d3c8baa6cc35
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strlcat.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+RCSID("$Id: strlcat.c,v 1.5 1999/12/02 16:58:53 joda Exp $");
+
+#ifndef HAVE_STRLCAT
+
+size_t
+strlcat (char *dst, const char *src, size_t dst_sz)
+{
+ size_t len = strlen(dst);
+
+ return len + strlcpy (dst + len, src, dst_sz - len);
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/strlcpy.c b/crypto/heimdal/lib/roken/strlcpy.c
new file mode 100644
index 000000000000..33cd9cb2af36
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strlcpy.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+RCSID("$Id: strlcpy.c,v 1.5 1999/12/02 16:58:53 joda Exp $");
+
+#ifndef HAVE_STRLCPY
+
+size_t
+strlcpy (char *dst, const char *src, size_t dst_sz)
+{
+ size_t n;
+ char *p;
+
+ for (p = dst, n = 0;
+ n + 1 < dst_sz && *src != '\0';
+ ++p, ++src, ++n)
+ *p = *src;
+ *p = '\0';
+ if (*src == '\0')
+ return n;
+ else
+ return n + strlen (src);
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/strlwr.c b/crypto/heimdal/lib/roken/strlwr.c
new file mode 100644
index 000000000000..cb367893f7ec
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strlwr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strlwr.c,v 1.4 1999/12/02 16:58:53 joda Exp $");
+#endif
+#include <string.h>
+#include <ctype.h>
+
+#include <roken.h>
+
+#ifndef HAVE_STRLWR
+char *
+strlwr(char *str)
+{
+ char *s;
+
+ for(s = str; *s; s++)
+ *s = tolower(*s);
+ return str;
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/strncasecmp.c b/crypto/heimdal/lib/roken/strncasecmp.c
new file mode 100644
index 000000000000..7c6474f78a3f
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strncasecmp.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strncasecmp.c,v 1.2 1999/12/02 16:58:53 joda Exp $");
+#endif
+
+#include <string.h>
+#include <ctype.h>
+#include <stddef.h>
+
+#ifndef HAVE_STRNCASECMP
+
+int
+strncasecmp(const char *s1, const char *s2, size_t n)
+{
+ while(n > 0 && toupper(*s1) == toupper(*s2)) {
+ if(*s1 == '\0')
+ return 0;
+ s1++;
+ s2++;
+ n--;
+ }
+ if(n == 0)
+ return 0;
+ return toupper(*s1) - toupper(*s2);
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/strndup.c b/crypto/heimdal/lib/roken/strndup.c
new file mode 100644
index 000000000000..31e7e9f6a1c4
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strndup.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strndup.c,v 1.2 1999/12/02 16:58:53 joda Exp $");
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include <roken.h>
+
+#ifndef HAVE_STRNDUP
+char *
+strndup(const char *old, size_t sz)
+{
+ size_t len = strnlen (old, sz);
+ char *t = malloc(len + 1);
+
+ if (t != NULL) {
+ memcpy (t, old, len);
+ t[len] = '\0';
+ }
+ return t;
+}
+#endif /* HAVE_STRNDUP */
diff --git a/crypto/heimdal/lib/roken/strnlen.c b/crypto/heimdal/lib/roken/strnlen.c
new file mode 100644
index 000000000000..fffb3b74f555
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strnlen.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strnlen.c,v 1.7 1999/12/02 16:58:53 joda Exp $");
+#endif
+
+#include "roken.h"
+
+size_t
+strnlen(const char *s, size_t len)
+{
+ size_t i;
+
+ for(i = 0; i < len && s[i]; i++)
+ ;
+ return i;
+}
diff --git a/crypto/heimdal/lib/roken/strpftime-test.c b/crypto/heimdal/lib/roken/strpftime-test.c
new file mode 100644
index 000000000000..7eb8fb85eb2a
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strpftime-test.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+RCSID("$Id: strpftime-test.c,v 1.2 1999/11/12 15:29:55 assar Exp $");
+
+enum { MAXSIZE = 26 };
+
+static struct testcase {
+ time_t t;
+ struct {
+ const char *format;
+ const char *result;
+ } vals[MAXSIZE];
+} tests[] = {
+ {0,
+ {
+ {"%A", "Thursday"},
+ {"%a", "Thu"},
+ {"%B", "January"},
+ {"%b", "Jan"},
+ {"%C", "19"},
+ {"%d", "01"},
+ {"%e", " 1"},
+ {"%H", "00"},
+ {"%I", "12"},
+ {"%j", "001"},
+ {"%k", " 0"},
+ {"%l", "12"},
+ {"%M", "00"},
+ {"%m", "01"},
+ {"%n", "\n"},
+ {"%p", "AM"},
+ {"%S", "00"},
+ {"%t", "\t"},
+ {"%w", "4"},
+ {"%Y", "1970"},
+ {"%y", "70"},
+ {"%U", "00"},
+ {"%W", "00"},
+ {"%V", "01"},
+ {"%%", "%"},
+ {NULL, NULL}}
+ },
+ {90000,
+ {
+ {"%A", "Friday"},
+ {"%a", "Fri"},
+ {"%B", "January"},
+ {"%b", "Jan"},
+ {"%C", "19"},
+ {"%d", "02"},
+ {"%e", " 2"},
+ {"%H", "01"},
+ {"%I", "01"},
+ {"%j", "002"},
+ {"%k", " 1"},
+ {"%l", " 1"},
+ {"%M", "00"},
+ {"%m", "01"},
+ {"%n", "\n"},
+ {"%p", "AM"},
+ {"%S", "00"},
+ {"%t", "\t"},
+ {"%w", "5"},
+ {"%Y", "1970"},
+ {"%y", "70"},
+ {"%U", "00"},
+ {"%W", "00"},
+ {"%V", "01"},
+ {"%%", "%"},
+ {NULL, NULL}
+ }
+ },
+ {216306,
+ {
+ {"%A", "Saturday"},
+ {"%a", "Sat"},
+ {"%B", "January"},
+ {"%b", "Jan"},
+ {"%C", "19"},
+ {"%d", "03"},
+ {"%e", " 3"},
+ {"%H", "12"},
+ {"%I", "12"},
+ {"%j", "003"},
+ {"%k", "12"},
+ {"%l", "12"},
+ {"%M", "05"},
+ {"%m", "01"},
+ {"%n", "\n"},
+ {"%p", "PM"},
+ {"%S", "06"},
+ {"%t", "\t"},
+ {"%w", "6"},
+ {"%Y", "1970"},
+ {"%y", "70"},
+ {"%U", "00"},
+ {"%W", "00"},
+ {"%V", "01"},
+ {"%%", "%"},
+ {NULL, NULL}
+ }
+ },
+ {259200,
+ {
+ {"%A", "Sunday"},
+ {"%a", "Sun"},
+ {"%B", "January"},
+ {"%b", "Jan"},
+ {"%C", "19"},
+ {"%d", "04"},
+ {"%e", " 4"},
+ {"%H", "00"},
+ {"%I", "12"},
+ {"%j", "004"},
+ {"%k", " 0"},
+ {"%l", "12"},
+ {"%M", "00"},
+ {"%m", "01"},
+ {"%n", "\n"},
+ {"%p", "AM"},
+ {"%S", "00"},
+ {"%t", "\t"},
+ {"%w", "0"},
+ {"%Y", "1970"},
+ {"%y", "70"},
+ {"%U", "01"},
+ {"%W", "00"},
+ {"%V", "01"},
+ {"%%", "%"},
+ {NULL, NULL}
+ }
+ },
+ {915148800,
+ {
+ {"%A", "Friday"},
+ {"%a", "Fri"},
+ {"%B", "January"},
+ {"%b", "Jan"},
+ {"%C", "19"},
+ {"%d", "01"},
+ {"%e", " 1"},
+ {"%H", "00"},
+ {"%I", "12"},
+ {"%j", "001"},
+ {"%k", " 0"},
+ {"%l", "12"},
+ {"%M", "00"},
+ {"%m", "01"},
+ {"%n", "\n"},
+ {"%p", "AM"},
+ {"%S", "00"},
+ {"%t", "\t"},
+ {"%w", "5"},
+ {"%Y", "1999"},
+ {"%y", "99"},
+ {"%U", "00"},
+ {"%W", "00"},
+ {"%V", "53"},
+ {"%%", "%"},
+ {NULL, NULL}}
+ },
+ {942161105,
+ {
+
+ {"%A", "Tuesday"},
+ {"%a", "Tue"},
+ {"%B", "November"},
+ {"%b", "Nov"},
+ {"%C", "19"},
+ {"%d", "09"},
+ {"%e", " 9"},
+ {"%H", "15"},
+ {"%I", "03"},
+ {"%j", "313"},
+ {"%k", "15"},
+ {"%l", " 3"},
+ {"%M", "25"},
+ {"%m", "11"},
+ {"%n", "\n"},
+ {"%p", "PM"},
+ {"%S", "05"},
+ {"%t", "\t"},
+ {"%w", "2"},
+ {"%Y", "1999"},
+ {"%y", "99"},
+ {"%U", "45"},
+ {"%W", "45"},
+ {"%V", "45"},
+ {"%%", "%"},
+ {NULL, NULL}
+ }
+ }
+};
+
+int
+main(int argc, char **argv)
+{
+ int i, j;
+ int ret = 0;
+
+ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) {
+ struct tm *tm;
+
+ tm = gmtime (&tests[i].t);
+
+ for (j = 0; tests[i].vals[j].format != NULL; ++j) {
+ char buf[128];
+ size_t len;
+ struct tm tm2;
+ char *ptr;
+
+ len = strftime (buf, sizeof(buf), tests[i].vals[j].format, tm);
+ if (len != strlen (buf)) {
+ printf ("length of strftime(\"%s\") = %d (\"%s\")\n",
+ tests[i].vals[j].format, len,
+ buf);
+ ++ret;
+ continue;
+ }
+ if (strcmp (buf, tests[i].vals[j].result) != 0) {
+ printf ("result of strftime(\"%s\") = \"%s\" != \"%s\"\n",
+ tests[i].vals[j].format, buf,
+ tests[i].vals[j].result);
+ ++ret;
+ continue;
+ }
+ memset (&tm2, 0, sizeof(tm2));
+ ptr = strptime (tests[i].vals[j].result,
+ tests[i].vals[j].format,
+ &tm2);
+ if (ptr == NULL || *ptr != '\0') {
+ printf ("bad return value from strptime("
+ "\"%s\", \"%s\")\n",
+ tests[i].vals[j].result,
+ tests[i].vals[j].format);
+ ++ret;
+ }
+ strftime (buf, sizeof(buf), tests[i].vals[j].format, &tm2);
+ if (strcmp (buf, tests[i].vals[j].result) != 0) {
+ printf ("reverse of \"%s\" failed: \"%s\" vs \"%s\"\n",
+ tests[i].vals[j].format,
+ buf, tests[i].vals[j].result);
+ ++ret;
+ }
+ }
+ }
+ if (ret) {
+ printf ("%d errors\n", ret);
+ return 1;
+ } else
+ return 0;
+}
diff --git a/crypto/heimdal/lib/roken/strptime.c b/crypto/heimdal/lib/roken/strptime.c
new file mode 100644
index 000000000000..36f0822431f8
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strptime.c
@@ -0,0 +1,444 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <ctype.h>
+#include "roken.h"
+
+RCSID("$Id: strptime.c,v 1.2 1999/11/12 15:29:55 assar Exp $");
+
+static const char *abb_weekdays[] = {
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+ NULL
+};
+
+static const char *full_weekdays[] = {
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ NULL
+};
+
+static const char *abb_month[] = {
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+ NULL
+};
+
+static const char *full_month[] = {
+ "January",
+ "February",
+ "Mars",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December",
+ NULL,
+};
+
+static const char *ampm[] = {
+ "am",
+ "pm",
+ NULL
+};
+
+/*
+ * Try to match `*buf' to one of the strings in `strs'. Return the
+ * index of the matching string (or -1 if none). Also advance buf.
+ */
+
+static int
+match_string (const char **buf, const char **strs)
+{
+ int i = 0;
+
+ for (i = 0; strs[i] != NULL; ++i) {
+ int len = strlen (strs[i]);
+
+ if (strncasecmp (*buf, strs[i], len) == 0) {
+ *buf += len;
+ return i;
+ }
+ }
+ return -1;
+}
+
+/*
+ * tm_year is relative this year */
+
+const int tm_year_base = 1900;
+
+/*
+ * Return TRUE iff `year' was a leap year.
+ */
+
+static int
+is_leap_year (int year)
+{
+ return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0);
+}
+
+/*
+ * Return the weekday [0,6] (0 = Sunday) of the first day of `year'
+ */
+
+static int
+first_day (int year)
+{
+ int ret = 4;
+
+ for (; year > 1970; --year)
+ ret = (ret + 365 + is_leap_year (year) ? 1 : 0) % 7;
+ return ret;
+}
+
+/*
+ * Set `timeptr' given `wnum' (week number [0, 53])
+ */
+
+static void
+set_week_number_sun (struct tm *timeptr, int wnum)
+{
+ int fday = first_day (timeptr->tm_year + tm_year_base);
+
+ timeptr->tm_yday = wnum * 7 + timeptr->tm_wday - fday;
+ if (timeptr->tm_yday < 0) {
+ timeptr->tm_wday = fday;
+ timeptr->tm_yday = 0;
+ }
+}
+
+/*
+ * Set `timeptr' given `wnum' (week number [0, 53])
+ */
+
+static void
+set_week_number_mon (struct tm *timeptr, int wnum)
+{
+ int fday = (first_day (timeptr->tm_year + tm_year_base) + 6) % 7;
+
+ timeptr->tm_yday = wnum * 7 + (timeptr->tm_wday + 6) % 7 - fday;
+ if (timeptr->tm_yday < 0) {
+ timeptr->tm_wday = (fday + 1) % 7;
+ timeptr->tm_yday = 0;
+ }
+}
+
+/*
+ * Set `timeptr' given `wnum' (week number [0, 53])
+ */
+
+static void
+set_week_number_mon4 (struct tm *timeptr, int wnum)
+{
+ int fday = (first_day (timeptr->tm_year + tm_year_base) + 6) % 7;
+ int offset = 0;
+
+ if (fday < 4)
+ offset += 7;
+
+ timeptr->tm_yday = offset + (wnum - 1) * 7 + timeptr->tm_wday - fday;
+ if (timeptr->tm_yday < 0) {
+ timeptr->tm_wday = fday;
+ timeptr->tm_yday = 0;
+ }
+}
+
+/*
+ *
+ */
+
+char *
+strptime (const char *buf, const char *format, struct tm *timeptr)
+{
+ char c;
+
+ for (; (c = *format) != '\0'; ++format) {
+ char *s;
+ int ret;
+
+ if (isspace (c)) {
+ while (isspace (*buf))
+ ++buf;
+ } else if (c == '%' && format[1] != '\0') {
+ c = *++format;
+ if (c == 'E' || c == 'O')
+ c = *++format;
+ switch (c) {
+ case 'A' :
+ ret = match_string (&buf, full_weekdays);
+ if (ret < 0)
+ return NULL;
+ timeptr->tm_wday = ret;
+ break;
+ case 'a' :
+ ret = match_string (&buf, abb_weekdays);
+ if (ret < 0)
+ return NULL;
+ timeptr->tm_wday = ret;
+ break;
+ case 'B' :
+ ret = match_string (&buf, full_month);
+ if (ret < 0)
+ return NULL;
+ timeptr->tm_mon = ret;
+ break;
+ case 'b' :
+ case 'h' :
+ ret = match_string (&buf, abb_month);
+ if (ret < 0)
+ return NULL;
+ timeptr->tm_mon = ret;
+ break;
+ case 'C' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ timeptr->tm_year = (ret * 100) - tm_year_base;
+ buf = s;
+ break;
+ case 'c' :
+ abort ();
+ case 'D' : /* %m/%d/%y */
+ s = strptime (buf, "%m/%d/%y", timeptr);
+ if (s == NULL)
+ return NULL;
+ buf = s;
+ break;
+ case 'd' :
+ case 'e' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ timeptr->tm_mday = ret;
+ buf = s;
+ break;
+ case 'H' :
+ case 'k' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ timeptr->tm_hour = ret;
+ buf = s;
+ break;
+ case 'I' :
+ case 'l' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ if (ret == 12)
+ timeptr->tm_hour = 0;
+ else
+ timeptr->tm_hour = ret;
+ buf = s;
+ break;
+ case 'j' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ timeptr->tm_yday = ret - 1;
+ buf = s;
+ break;
+ case 'm' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ timeptr->tm_mon = ret - 1;
+ buf = s;
+ break;
+ case 'M' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ timeptr->tm_min = ret;
+ buf = s;
+ break;
+ case 'n' :
+ if (*buf == '\n')
+ ++buf;
+ else
+ return NULL;
+ break;
+ case 'p' :
+ ret = match_string (&buf, ampm);
+ if (ret < 0)
+ return NULL;
+ if (timeptr->tm_hour == 0) {
+ if (ret == 1)
+ timeptr->tm_hour = 12;
+ } else
+ timeptr->tm_hour += 12;
+ break;
+ case 'r' : /* %I:%M:%S %p */
+ s = strptime (buf, "%I:%M:%S %p", timeptr);
+ if (s == NULL)
+ return NULL;
+ buf = s;
+ break;
+ case 'R' : /* %H:%M */
+ s = strptime (buf, "%H:%M", timeptr);
+ if (s == NULL)
+ return NULL;
+ buf = s;
+ break;
+ case 'S' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ timeptr->tm_sec = ret;
+ buf = s;
+ break;
+ case 't' :
+ if (*buf == '\t')
+ ++buf;
+ else
+ return NULL;
+ break;
+ case 'T' : /* %H:%M:%S */
+ case 'X' :
+ s = strptime (buf, "%H:%M:%S", timeptr);
+ if (s == NULL)
+ return NULL;
+ buf = s;
+ break;
+ case 'u' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ timeptr->tm_wday = ret - 1;
+ buf = s;
+ break;
+ case 'w' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ timeptr->tm_wday = ret;
+ buf = s;
+ break;
+ case 'U' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ set_week_number_sun (timeptr, ret);
+ buf = s;
+ break;
+ case 'V' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ set_week_number_mon4 (timeptr, ret);
+ buf = s;
+ break;
+ case 'W' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ set_week_number_mon (timeptr, ret);
+ buf = s;
+ break;
+ case 'x' :
+ s = strptime (buf, "%Y:%m:%d", timeptr);
+ if (s == NULL)
+ return NULL;
+ buf = s;
+ break;
+ case 'y' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ if (ret < 70)
+ timeptr->tm_year = 100 + ret;
+ else
+ timeptr->tm_year = ret;
+ buf = s;
+ break;
+ case 'Y' :
+ ret = strtol (buf, &s, 10);
+ if (s == buf)
+ return NULL;
+ timeptr->tm_year = ret - tm_year_base;
+ buf = s;
+ break;
+ case 'Z' :
+ abort ();
+ case '\0' :
+ --format;
+ /* FALLTHROUGH */
+ case '%' :
+ if (*buf == '%')
+ ++buf;
+ else
+ return NULL;
+ break;
+ default :
+ if (*buf == '%' || *++buf == c)
+ ++buf;
+ else
+ return NULL;
+ break;
+ }
+ } else {
+ if (*buf == c)
+ ++buf;
+ else
+ return NULL;
+ }
+ }
+ return (char *)buf;
+}
diff --git a/crypto/heimdal/lib/roken/strsep.c b/crypto/heimdal/lib/roken/strsep.c
new file mode 100644
index 000000000000..efc714a66426
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strsep.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strsep.c,v 1.3 1999/12/02 16:58:53 joda Exp $");
+#endif
+
+#include <string.h>
+
+#include "roken.h"
+
+#ifndef HAVE_STRSEP
+
+char *
+strsep(char **str, const char *delim)
+{
+ char *save = *str;
+ if(*str == NULL)
+ return NULL;
+ *str = *str + strcspn(*str, delim);
+ if(**str == 0)
+ *str = NULL;
+ else{
+ **str = 0;
+ (*str)++;
+ }
+ return save;
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/strtok_r.c b/crypto/heimdal/lib/roken/strtok_r.c
new file mode 100644
index 000000000000..45b036aa9f36
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strtok_r.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strtok_r.c,v 1.5 1999/12/02 16:58:53 joda Exp $");
+#endif
+
+#include <string.h>
+
+#include "roken.h"
+
+#ifndef HAVE_STRTOK_R
+
+char *
+strtok_r(char *s1, const char *s2, char **lasts)
+{
+ char *ret;
+
+ if (s1 == NULL)
+ s1 = *lasts;
+ while(*s1 && strchr(s2, *s1))
+ ++s1;
+ if(*s1 == '\0')
+ return NULL;
+ ret = s1;
+ while(*s1 && !strchr(s2, *s1))
+ ++s1;
+ if(*s1)
+ *s1++ = '\0';
+ *lasts = s1;
+ return ret;
+}
+
+#endif /* HAVE_STRTOK_R */
diff --git a/crypto/heimdal/lib/roken/strupr.c b/crypto/heimdal/lib/roken/strupr.c
new file mode 100644
index 000000000000..96dd042a83e7
--- /dev/null
+++ b/crypto/heimdal/lib/roken/strupr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: strupr.c,v 1.4 1999/12/02 16:58:53 joda Exp $");
+#endif
+#include <string.h>
+#include <ctype.h>
+
+#include <roken.h>
+
+#ifndef HAVE_STRUPR
+char *
+strupr(char *str)
+{
+ char *s;
+
+ for(s = str; *s; s++)
+ *s = toupper(*s);
+ return str;
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/swab.c b/crypto/heimdal/lib/roken/swab.c
new file mode 100644
index 000000000000..c623bd0708e7
--- /dev/null
+++ b/crypto/heimdal/lib/roken/swab.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "roken.h"
+
+#ifndef HAVE_SWAB
+
+RCSID("$Id: swab.c,v 1.7 1999/12/02 16:58:53 joda Exp $");
+
+void
+swab (char *from, char *to, int nbytes)
+{
+ while(nbytes >= 2) {
+ *(to + 1) = *from;
+ *to = *(from + 1);
+ to += 2;
+ from += 2;
+ nbytes -= 2;
+ }
+}
+#endif
diff --git a/crypto/heimdal/lib/roken/tm2time.c b/crypto/heimdal/lib/roken/tm2time.c
new file mode 100644
index 000000000000..b912e32dae33
--- /dev/null
+++ b/crypto/heimdal/lib/roken/tm2time.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: tm2time.c,v 1.7 1999/12/02 16:58:53 joda Exp $");
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#include "roken.h"
+
+time_t
+tm2time (struct tm tm, int local)
+{
+ time_t t;
+
+ tm.tm_isdst = -1;
+
+ t = mktime (&tm);
+
+ if (!local)
+ t += t - mktime (gmtime (&t));
+ return t;
+}
diff --git a/crypto/heimdal/lib/roken/unsetenv.c b/crypto/heimdal/lib/roken/unsetenv.c
new file mode 100644
index 000000000000..6d95a513dcd3
--- /dev/null
+++ b/crypto/heimdal/lib/roken/unsetenv.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: unsetenv.c,v 1.7 1999/12/02 16:58:53 joda Exp $");
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "roken.h"
+
+extern char **environ;
+
+/*
+ * unsetenv --
+ */
+void
+unsetenv(const char *name)
+{
+ int len;
+ const char *np;
+ char **p;
+
+ if (name == 0 || environ == 0)
+ return;
+
+ for (np = name; *np && *np != '='; np++)
+ /* nop */;
+ len = np - name;
+
+ for (p = environ; *p != 0; p++)
+ if (strncmp(*p, name, len) == 0 && (*p)[len] == '=')
+ break;
+
+ for (; *p != 0; p++)
+ *p = *(p + 1);
+}
+
diff --git a/crypto/heimdal/lib/roken/verify.c b/crypto/heimdal/lib/roken/verify.c
new file mode 100644
index 000000000000..842fa9a3aee8
--- /dev/null
+++ b/crypto/heimdal/lib/roken/verify.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: verify.c,v 1.13 1999/12/02 16:58:53 joda Exp $");
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+#include "roken.h"
+
+int
+unix_verify_user(char *user, char *password)
+{
+ struct passwd *pw;
+
+ pw = k_getpwnam(user);
+ if(pw == NULL)
+ return -1;
+ if(strlen(pw->pw_passwd) == 0 && strlen(password) == 0)
+ return 0;
+ if(strcmp(crypt(password, pw->pw_passwd), pw->pw_passwd) == 0)
+ return 0;
+ return -1;
+}
+
diff --git a/crypto/heimdal/lib/roken/verr.c b/crypto/heimdal/lib/roken/verr.c
new file mode 100644
index 000000000000..511e6402e030
--- /dev/null
+++ b/crypto/heimdal/lib/roken/verr.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: verr.c,v 1.8 1999/12/02 16:58:53 joda Exp $");
+#endif
+
+#include "err.h"
+
+void
+verr(int eval, const char *fmt, va_list ap)
+{
+ warnerr(1, fmt, ap);
+ exit(eval);
+}
diff --git a/crypto/heimdal/lib/roken/verrx.c b/crypto/heimdal/lib/roken/verrx.c
new file mode 100644
index 000000000000..f4578d322bc7
--- /dev/null
+++ b/crypto/heimdal/lib/roken/verrx.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: verrx.c,v 1.8 1999/12/02 16:58:53 joda Exp $");
+#endif
+
+#include "err.h"
+
+void
+verrx(int eval, const char *fmt, va_list ap)
+{
+ warnerr(0, fmt, ap);
+ exit(eval);
+}
diff --git a/crypto/heimdal/lib/roken/vsyslog.c b/crypto/heimdal/lib/roken/vsyslog.c
new file mode 100644
index 000000000000..22e6a35a80c0
--- /dev/null
+++ b/crypto/heimdal/lib/roken/vsyslog.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: vsyslog.c,v 1.3 1999/12/02 16:58:54 joda Exp $");
+#endif
+
+#ifndef HAVE_VSYSLOG
+
+#include <stdio.h>
+#include <syslog.h>
+#include <stdarg.h>
+
+#include "roken.h"
+
+void
+vsyslog(int pri, const char *fmt, va_list ap)
+{
+ char *p;
+
+ vasprintf (&p, fmt, ap);
+ syslog (pri, "%s", p);
+ free (p);
+}
+
+#endif
diff --git a/crypto/heimdal/lib/roken/vwarn.c b/crypto/heimdal/lib/roken/vwarn.c
new file mode 100644
index 000000000000..15f9a3827650
--- /dev/null
+++ b/crypto/heimdal/lib/roken/vwarn.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: vwarn.c,v 1.8 1999/12/02 16:58:54 joda Exp $");
+#endif
+
+#include "err.h"
+
+void
+vwarn(const char *fmt, va_list ap)
+{
+ warnerr(1, fmt, ap);
+}
diff --git a/crypto/heimdal/lib/roken/vwarnx.c b/crypto/heimdal/lib/roken/vwarnx.c
new file mode 100644
index 000000000000..48f1ffd46bfc
--- /dev/null
+++ b/crypto/heimdal/lib/roken/vwarnx.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: vwarnx.c,v 1.8 1999/12/02 16:58:54 joda Exp $");
+#endif
+
+#include "err.h"
+
+void
+vwarnx(const char *fmt, va_list ap)
+{
+ warnerr(0, fmt, ap);
+}
+
diff --git a/crypto/heimdal/lib/roken/warn.c b/crypto/heimdal/lib/roken/warn.c
new file mode 100644
index 000000000000..d8ee335106a1
--- /dev/null
+++ b/crypto/heimdal/lib/roken/warn.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: warn.c,v 1.6 1999/12/02 16:58:54 joda Exp $");
+#endif
+
+#include "err.h"
+
+void
+warn(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarn(fmt, ap);
+ va_end(ap);
+}
diff --git a/crypto/heimdal/lib/roken/warnerr.c b/crypto/heimdal/lib/roken/warnerr.c
new file mode 100644
index 000000000000..4df375da67f5
--- /dev/null
+++ b/crypto/heimdal/lib/roken/warnerr.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: warnerr.c,v 1.8 1999/12/02 16:58:54 joda Exp $");
+#endif
+
+#include "roken.h"
+#include "err.h"
+
+#ifndef HAVE___PROGNAME
+const char *__progname;
+#endif
+
+void
+set_progname(char *argv0)
+{
+#ifndef HAVE___PROGNAME
+ char *p;
+ if(argv0 == NULL)
+ return;
+ p = strrchr(argv0, '/');
+ if(p == NULL)
+ p = argv0;
+ else
+ p++;
+ __progname = p;
+#endif
+}
+
+void
+warnerr(int doerrno, const char *fmt, va_list ap)
+{
+ int sverrno = errno;
+ if(__progname != NULL){
+ fprintf(stderr, "%s", __progname);
+ if(fmt != NULL || doerrno)
+ fprintf(stderr, ": ");
+ }
+ if (fmt != NULL){
+ vfprintf(stderr, fmt, ap);
+ if(doerrno)
+ fprintf(stderr, ": ");
+ }
+ if(doerrno)
+ fprintf(stderr, "%s", strerror(sverrno));
+ fprintf(stderr, "\n");
+}
diff --git a/crypto/heimdal/lib/roken/warnx.c b/crypto/heimdal/lib/roken/warnx.c
new file mode 100644
index 000000000000..c991176a9de1
--- /dev/null
+++ b/crypto/heimdal/lib/roken/warnx.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: warnx.c,v 1.6 1999/12/02 16:58:54 joda Exp $");
+#endif
+
+#include "err.h"
+
+void
+warnx(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+}
diff --git a/crypto/heimdal/lib/roken/writev.c b/crypto/heimdal/lib/roken/writev.c
new file mode 100644
index 000000000000..e3859bfe332c
--- /dev/null
+++ b/crypto/heimdal/lib/roken/writev.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: writev.c,v 1.3 1999/12/02 16:58:54 joda Exp $");
+#endif
+
+#include "roken.h"
+
+ssize_t
+writev(int d, const struct iovec *iov, int iovcnt)
+{
+ ssize_t ret;
+ size_t tot = 0;
+ int i;
+ char *buf, *p;
+
+ for(i = 0; i < iovcnt; ++i)
+ tot += iov[i].iov_len;
+ buf = malloc(tot);
+ if (tot != 0 && buf == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ p = buf;
+ for (i = 0; i < iovcnt; ++i) {
+ memcpy (p, iov[i].iov_base, iov[i].iov_len);
+ p += iov[i].iov_len;
+ }
+ ret = write (d, buf, tot);
+ free (buf);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/roken/xdbm.h b/crypto/heimdal/lib/roken/xdbm.h
new file mode 100644
index 000000000000..83885b3bfc1c
--- /dev/null
+++ b/crypto/heimdal/lib/roken/xdbm.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: xdbm.h,v 1.6 1999/12/02 16:58:54 joda Exp $ */
+
+/* Generic *dbm include file */
+
+#ifndef __XDBM_H__
+#define __XDBM_H__
+
+#ifdef HAVE_NDBM_H
+#include <ndbm.h>
+#elif defined(HAVE_DBM_H)
+#include <dbm.h>
+#elif defined(HAVE_RPCSVC_DBM_H)
+#include <rpcsvc/dbm.h>
+#elif defined(HAVE_DB_H)
+#define DB_DBM_HSEARCH 1
+#include <db.h>
+#endif
+
+/* Macros to convert ndbm names to dbm names.
+ * Note that dbm_nextkey() cannot be simply converted using a macro, since
+ * it is invoked giving the database, and nextkey() needs the previous key.
+ *
+ * Instead, all routines call "dbm_next" instead.
+ */
+
+#ifndef NDBM
+typedef char DBM;
+
+#define dbm_open(file, flags, mode) ((dbminit(file) == 0)?"":((char *)0))
+#define dbm_fetch(db, key) fetch(key)
+#define dbm_store(db, key, content, flag) store(key, content)
+#define dbm_delete(db, key) delete(key)
+#define dbm_firstkey(db) firstkey()
+#define dbm_next(db,key) nextkey(key)
+#define dbm_close(db) dbmclose()
+#else
+#define dbm_next(db,key) dbm_nextkey(db)
+#endif
+
+#endif /* __XDBM_H__ */
diff --git a/crypto/heimdal/lib/sl/ChangeLog b/crypto/heimdal/lib/sl/ChangeLog
new file mode 100644
index 000000000000..eca72177f5ee
--- /dev/null
+++ b/crypto/heimdal/lib/sl/ChangeLog
@@ -0,0 +1,120 @@
+2000-01-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump both versions to 0:1:0
+
+1999-12-16 Assar Westerlund <assar@sics.se>
+
+ * parse.y (name2number): not used here. remove.
+
+Thu Apr 1 17:03:59 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * make_cmds.c: use getarg
+
+Tue Mar 23 14:36:21 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: don't rename
+
+Sun Mar 21 14:13:29 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: don't roken-rename
+
+Sat Mar 20 03:43:30 1999 Assar Westerlund <assar@sics.se>
+
+ * parse.y: replace return with YYACCEPT
+
+Fri Mar 19 14:53:20 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: add libss; add version-info
+
+Thu Mar 18 15:07:06 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: clean lex.c parse.c parse.h
+
+ * Makefile.am: install ss.h
+
+ * Makefile.am: include Makefile.am.common
+
+Thu Mar 11 15:01:01 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * parse.y: prototype for error_message
+
+Tue Feb 9 23:45:37 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.in: add snprintf.o to make_cmds
+
+Sun Nov 22 10:46:23 1998 Assar Westerlund <assar@sics.se>
+
+ * sl.c (sl_command_loop): remove unused variable
+
+ * ss.c (ss_error): remove unused variable
+
+ * make_cmds.c: include err.h
+ (main): remove unused variable
+
+ * Makefile.in (WFLAGS): set
+
+Sun Sep 27 01:28:21 1998 Assar Westerlund <assar@sics.se>
+
+ * make_cmds.c: clean-up and simplification
+
+Mon May 25 02:54:13 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (clean): try to remove shared library debris
+
+ * Makefile.in: make symlink magic work
+
+Sun Apr 19 10:00:26 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: add symlink magic for linux
+
+Sun Apr 5 09:21:43 1998 Assar Westerlund <assar@sics.se>
+
+ * parse.y: define alloca to malloc in case we're using bison but
+ don't have alloca
+
+Sat Mar 28 11:39:00 1998 Assar Westerlund <assar@sics.se>
+
+ * sl.c (sl_loop): s/2/1
+
+Sat Mar 21 00:46:51 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * sl.c (sl_loop): check that there is at least one argument before
+ calling sl_command
+
+Sun Mar 1 05:14:37 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * sl.c (sl_loop): Fix general broken-ness.
+
+ * sl.c: Cleanup printing of help strings.
+
+Thu Feb 26 02:22:02 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: @LEXLIB@
+
+Sat Feb 21 15:18:21 1998 assar westerlund <assar@sics.se>
+
+ * Makefile.in: set YACC and LEX
+
+Mon Feb 16 16:08:25 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Makefile.am: Some fixes for ss/mk_cmds.
+
+Sun Feb 15 05:12:11 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Makefile.in: Install libsl under the `libss' name too. Install
+ mk_cmds, and ss.h.
+
+ * make_cmds.c: A mk_cmds clone that creates SL structures.
+
+ * ss.c: SS compatibility functions.
+
+ * sl.c: Move command line split to function `sl_make_argv'.
+
+Tue Feb 3 16:45:44 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * sl.c: Add sl_command_loop, that is the loop body of sl_loop.
+
+Mon Oct 20 01:13:21 1997 Assar Westerlund <assar@sics.se>
+
+ * sl.c (sl_help): actually use the `help' field of `SL_cmd'
+
diff --git a/crypto/heimdal/lib/sl/Makefile.am b/crypto/heimdal/lib/sl/Makefile.am
new file mode 100644
index 000000000000..e572e21052f1
--- /dev/null
+++ b/crypto/heimdal/lib/sl/Makefile.am
@@ -0,0 +1,44 @@
+# $Id: Makefile.am,v 1.15 2000/01/06 21:52:20 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+YFLAGS = -d
+
+include_HEADERS = sl.h
+
+lib_LTLIBRARIES = libsl.la libss.la
+libsl_la_LDFLAGS = -version-info 0:1:0
+libss_la_LDFLAGS = -version-info 0:1:0
+
+RENAME_SRC = roken_rename.h strtok_r.c snprintf.c
+
+libsl_la_SOURCES = sl_locl.h sl.c
+libss_la_SOURCES = $(libsl_la_SOURCES) ss.c ss.h
+
+EXTRA_libsl_la_SOURCES = strtok_r.c snprintf.c roken_rename.h
+
+# install these?
+
+noinst_PROGRAMS = mk_cmds
+
+mk_cmds_SOURCES = make_cmds.c make_cmds.h parse.y lex.l
+
+RENAME_mk_cmds_SRC = roken_rename.h snprintf.c
+
+EXTRA_mk_cmds_SOURCES = snprintf.c roken_rename.h
+
+ssincludedir = $(includedir)/ss
+ssinclude_HEADERS = ss.h
+
+CLEANFILES = lex.c parse.c parse.h snprintf.c strtok_r.c
+
+$(mk_cmds_OBJECTS): parse.h
+
+LDADD = \
+ $(LIB_roken) \
+ $(LEXLIB)
+
+strtok_r.c:
+ $(LN_S) $(srcdir)/../roken/strtok_r.c .
+snprintf.c:
+ $(LN_S) $(srcdir)/../roken/snprintf.c .
diff --git a/crypto/heimdal/lib/sl/Makefile.in b/crypto/heimdal/lib/sl/Makefile.in
new file mode 100644
index 000000000000..634cd741e679
--- /dev/null
+++ b/crypto/heimdal/lib/sl/Makefile.in
@@ -0,0 +1,737 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.15 2000/01/06 21:52:20 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+YFLAGS = -d
+
+include_HEADERS = sl.h
+
+lib_LTLIBRARIES = libsl.la libss.la
+libsl_la_LDFLAGS = -version-info 0:1:0
+libss_la_LDFLAGS = -version-info 0:1:0
+
+RENAME_SRC = roken_rename.h strtok_r.c snprintf.c
+
+libsl_la_SOURCES = sl_locl.h sl.c
+libss_la_SOURCES = $(libsl_la_SOURCES) ss.c ss.h
+
+EXTRA_libsl_la_SOURCES = strtok_r.c snprintf.c roken_rename.h
+
+# install these?
+
+noinst_PROGRAMS = mk_cmds
+
+mk_cmds_SOURCES = make_cmds.c make_cmds.h parse.y lex.l
+
+RENAME_mk_cmds_SRC = roken_rename.h snprintf.c
+
+EXTRA_mk_cmds_SOURCES = snprintf.c roken_rename.h
+
+ssincludedir = $(includedir)/ss
+ssinclude_HEADERS = ss.h
+
+CLEANFILES = lex.c parse.c parse.h snprintf.c strtok_r.c
+
+LDADD = $(LIB_roken) $(LEXLIB)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libsl_la_LIBADD =
+libsl_la_OBJECTS = sl.lo
+libss_la_LIBADD =
+libss_la_OBJECTS = sl.lo ss.lo
+noinst_PROGRAMS = mk_cmds$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+mk_cmds_OBJECTS = make_cmds.$(OBJEXT) parse.$(OBJEXT) lex.$(OBJEXT)
+mk_cmds_LDADD = $(LDADD)
+mk_cmds_DEPENDENCIES =
+mk_cmds_LDFLAGS =
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(include_HEADERS) $(ssinclude_HEADERS)
+
+DIST_COMMON = ChangeLog Makefile.am Makefile.in lex.c parse.c
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libsl_la_SOURCES) $(EXTRA_libsl_la_SOURCES) $(libss_la_SOURCES) $(mk_cmds_SOURCES) $(EXTRA_mk_cmds_SOURCES)
+OBJECTS = $(libsl_la_OBJECTS) $(libss_la_OBJECTS) $(mk_cmds_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .l .lo .o .obj .s .x .y
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/sl/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libsl.la: $(libsl_la_OBJECTS) $(libsl_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libsl_la_LDFLAGS) $(libsl_la_OBJECTS) $(libsl_la_LIBADD) $(LIBS)
+
+libss.la: $(libss_la_OBJECTS) $(libss_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libss_la_LDFLAGS) $(libss_la_OBJECTS) $(libss_la_LIBADD) $(LIBS)
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+mk_cmds$(EXEEXT): $(mk_cmds_OBJECTS) $(mk_cmds_DEPENDENCIES)
+ @rm -f mk_cmds$(EXEEXT)
+ $(LINK) $(mk_cmds_LDFLAGS) $(mk_cmds_OBJECTS) $(mk_cmds_LDADD) $(LIBS)
+.l.c:
+ $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@
+.y.c:
+ $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c
+ if test -f y.tab.h; then \
+ if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
+ else :; fi
+parse.h: parse.c
+
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+install-ssincludeHEADERS: $(ssinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(ssincludedir)
+ @list='$(ssinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(ssincludedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(ssincludedir)/$$p; \
+ done
+
+uninstall-ssincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(ssinclude_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(ssincludedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/sl
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-includeHEADERS install-ssincludeHEADERS \
+ install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS \
+ uninstall-ssincludeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir) \
+ $(DESTDIR)$(ssincludedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ -test -z "lexlparsehparsec" || rm -f lexl parseh parsec
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-noinstPROGRAMS \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \
+ clean-noinstPROGRAMS clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-noinstPROGRAMS \
+ distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool mostlyclean-noinstPROGRAMS \
+distclean-noinstPROGRAMS clean-noinstPROGRAMS \
+maintainer-clean-noinstPROGRAMS uninstall-includeHEADERS \
+install-includeHEADERS uninstall-ssincludeHEADERS \
+install-ssincludeHEADERS tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-local install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+$(mk_cmds_OBJECTS): parse.h
+
+strtok_r.c:
+ $(LN_S) $(srcdir)/../roken/strtok_r.c .
+snprintf.c:
+ $(LN_S) $(srcdir)/../roken/snprintf.c .
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/sl/lex.l b/crypto/heimdal/lib/sl/lex.l
new file mode 100644
index 000000000000..b7c1c4432346
--- /dev/null
+++ b/crypto/heimdal/lib/sl/lex.l
@@ -0,0 +1,114 @@
+%{
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "make_cmds.h"
+#include "parse.h"
+
+RCSID("$Id: lex.l,v 1.3 1999/12/02 16:58:55 joda Exp $");
+
+static unsigned lineno = 1;
+void error_message(char *, ...);
+int getstring(void);
+
+%}
+
+
+%%
+command_table { return TABLE; }
+request { return REQUEST; }
+unknown { return UNKNOWN; }
+unimplemented { return UNIMPLEMENTED; }
+end { return END; }
+#[^\n]* ;
+[ \t] ;
+\n { lineno++; }
+\" { return getstring(); }
+[a-zA-Z0-9_]+ { yylval.string = strdup(yytext); return STRING; }
+. { return *yytext; }
+%%
+
+#ifndef yywrap /* XXX */
+int
+yywrap ()
+{
+ return 1;
+}
+#endif
+
+int
+getstring(void)
+{
+ char x[128];
+ int i = 0;
+ int c;
+ int backslash = 0;
+ while((c = input()) != EOF){
+ if(backslash) {
+ if(c == 'n')
+ c = '\n';
+ else if(c == 't')
+ c = '\t';
+ x[i++] = c;
+ backslash = 0;
+ continue;
+ }
+ if(c == '\n'){
+ error_message("unterminated string");
+ lineno++;
+ break;
+ }
+ if(c == '\\'){
+ backslash++;
+ continue;
+ }
+ if(c == '\"')
+ break;
+ x[i++] = c;
+ }
+ x[i] = '\0';
+ yylval.string = strdup(x);
+ return STRING;
+}
+
+void
+error_message (char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ fprintf (stderr, "%s:%d: ", filename, lineno);
+ vfprintf (stderr, format, args);
+ va_end (args);
+ numerror++;
+}
diff --git a/crypto/heimdal/lib/sl/make_cmds.c b/crypto/heimdal/lib/sl/make_cmds.c
new file mode 100644
index 000000000000..492e9e671272
--- /dev/null
+++ b/crypto/heimdal/lib/sl/make_cmds.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 1998-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "make_cmds.h"
+#include <getarg.h>
+
+RCSID("$Id: make_cmds.c,v 1.6 1999/12/02 16:58:55 joda Exp $");
+
+#include <roken.h>
+#include <err.h>
+#include "parse.h"
+
+int numerror;
+extern FILE *yyin;
+FILE *c_file;
+
+extern void yyparse(void);
+
+#ifdef YYDEBUG
+extern int yydebug = 1;
+#endif
+
+char *filename;
+char *table_name;
+
+static struct command_list *commands;
+
+void
+add_command(char *function,
+ char *help,
+ struct string_list *aliases,
+ unsigned flags)
+{
+ struct command_list *cl = malloc(sizeof(*cl));
+
+ if (cl == NULL)
+ err (1, "malloc");
+ cl->function = function;
+ cl->help = help;
+ cl->aliases = aliases;
+ cl->flags = flags;
+ cl->next = NULL;
+ if(commands) {
+ *commands->tail = cl;
+ commands->tail = &cl->next;
+ return;
+ }
+ cl->tail = &cl->next;
+ commands = cl;
+}
+
+static char *
+quote(const char *str)
+{
+ char buf[1024]; /* XXX */
+ const char *p;
+ char *q;
+ q = buf;
+
+ *q++ = '\"';
+ for(p = str; *p != '\0'; p++) {
+ if(*p == '\n') {
+ *q++ = '\\';
+ *q++ = 'n';
+ continue;
+ }
+ if(*p == '\t') {
+ *q++ = '\\';
+ *q++ = 't';
+ continue;
+ }
+ if(*p == '\"' || *p == '\\')
+ *q++ = '\\';
+ *q++ = *p;
+ }
+ *q++ = '\"';
+ *q++ = '\0';
+ return strdup(buf);
+}
+
+static void
+generate_commands(void)
+{
+ char *base;
+ char *cfn;
+ char *p;
+
+ p = strrchr(table_name, '/');
+ if(p == NULL)
+ p = table_name;
+ else
+ p++;
+
+ base = strdup (p);
+ if (base == NULL)
+ err (1, "strdup");
+
+ p = strrchr(base, '.');
+ if(p)
+ *p = '\0';
+
+ asprintf(&cfn, "%s.c", base);
+ if (cfn == NULL)
+ err (1, "asprintf");
+
+ c_file = fopen(cfn, "w");
+ if (c_file == NULL)
+ err (1, "cannot fopen %s", cfn);
+
+ fprintf(c_file, "/* Generated from %s */\n", filename);
+ fprintf(c_file, "\n");
+ fprintf(c_file, "#include <stddef.h>\n");
+ fprintf(c_file, "#include <sl.h>\n");
+ fprintf(c_file, "\n");
+
+ {
+ struct command_list *cl, *xl;
+ char *p, *q;
+
+ for(cl = commands; cl; cl = cl->next) {
+ for(xl = commands; xl != cl; xl = xl->next)
+ if(strcmp(cl->function, xl->function) == 0)
+ break;
+ if(xl != cl)
+ continue;
+ /* XXX hack for ss_quit */
+ if(strcmp(cl->function, "ss_quit") == 0) {
+ fprintf(c_file, "int %s (int, char**);\n", cl->function);
+ fprintf(c_file, "#define _ss_quit_wrap ss_quit\n\n");
+ continue;
+ }
+ fprintf(c_file, "void %s (int, char**);\n", cl->function);
+ fprintf(c_file, "static int _%s_wrap (int argc, char **argv)\n",
+ cl->function);
+ fprintf(c_file, "{\n");
+ fprintf(c_file, " %s (argc, argv);\n", cl->function);
+ fprintf(c_file, " return 0;\n");
+ fprintf(c_file, "}\n\n");
+ }
+
+ fprintf(c_file, "SL_cmd %s[] = {\n", table_name);
+ for(cl = commands; cl; cl = cl->next) {
+ struct string_list *sl;
+ sl = cl->aliases;
+ p = quote(sl->string);
+ q = quote(cl->help);
+ fprintf(c_file, " { %s, _%s_wrap, %s },\n", p, cl->function, q);
+ free(p);
+ free(q);
+
+ for(sl = sl->next; sl; sl = sl->next) {
+ p = quote(sl->string);
+ fprintf(c_file, " { %s },\n", p);
+ free(p);
+ }
+ }
+ fprintf(c_file, " { NULL },\n");
+ fprintf(c_file, "};\n");
+ fprintf(c_file, "\n");
+ }
+ fclose(c_file);
+ free(base);
+ free(cfn);
+}
+
+int version_flag;
+int help_flag;
+struct getargs args[] = {
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int code)
+{
+ arg_printusage(args, num_args, NULL, "command-table");
+ exit(code);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+
+ set_progname(argv[0]);
+ if(getarg(args, num_args, argc, argv, &optind))
+ usage(1);
+ if(help_flag)
+ usage(0);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ if(argc == optind)
+ usage(1);
+ filename = argv[optind];
+ yyin = fopen(filename, "r");
+ if(yyin == NULL)
+ err(1, "%s", filename);
+
+ yyparse();
+
+ generate_commands();
+
+ if(numerror)
+ return 1;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/sl/make_cmds.h b/crypto/heimdal/lib/sl/make_cmds.h
new file mode 100644
index 000000000000..24dbd60d6c59
--- /dev/null
+++ b/crypto/heimdal/lib/sl/make_cmds.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: make_cmds.h,v 1.2 1999/12/02 16:58:55 joda Exp $ */
+
+#ifndef __MAKE_CMDS_H__
+#define __MAKE_CMDS_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+extern char *filename;
+extern char *table_name;
+extern int numerror;
+
+struct command_list {
+ char *function;
+ char *help;
+ struct string_list *aliases;
+ unsigned flags;
+ struct command_list *next;
+ struct command_list **tail;
+};
+
+struct string_list {
+ char *string;
+ struct string_list *next;
+ struct string_list **tail;
+};
+
+void add_command(char*, char*, struct string_list*, unsigned);
+
+#endif /* __MAKE_CMDS_H__ */
diff --git a/crypto/heimdal/lib/sl/parse.y b/crypto/heimdal/lib/sl/parse.y
new file mode 100644
index 000000000000..18ef5cadda7c
--- /dev/null
+++ b/crypto/heimdal/lib/sl/parse.y
@@ -0,0 +1,168 @@
+%{
+/*
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "make_cmds.h"
+RCSID("$Id: parse.y,v 1.6 1999/12/16 10:34:11 assar Exp $");
+
+void yyerror (char *s);
+void error_message(char *, ...);
+
+struct string_list* append_string(struct string_list*, char*);
+void free_string_list(struct string_list *list);
+unsigned string_to_flag(const char *);
+
+/* This is for bison */
+
+#if !defined(alloca) && !defined(HAVE_ALLOCA)
+#define alloca(x) malloc(x)
+#endif
+
+%}
+
+%union {
+ char *string;
+ unsigned number;
+ struct string_list *list;
+}
+
+%token TABLE REQUEST UNKNOWN UNIMPLEMENTED END
+%token <string> STRING
+%type <number> flag flags
+%type <list> aliases
+
+%%
+
+file : /* */
+ | statements
+ ;
+
+statements : statement
+ | statements statement
+ ;
+
+statement : TABLE STRING ';'
+ {
+ table_name = $2;
+ }
+ | REQUEST STRING ',' STRING ',' aliases ',' '(' flags ')' ';'
+ {
+ add_command($2, $4, $6, $9);
+ }
+ | REQUEST STRING ',' STRING ',' aliases ';'
+ {
+ add_command($2, $4, $6, 0);
+ }
+ | UNIMPLEMENTED STRING ',' STRING ',' aliases ';'
+ {
+ free($2);
+ free($4);
+ free_string_list($6);
+ }
+ | UNKNOWN aliases ';'
+ {
+ free_string_list($2);
+ }
+ | END ';'
+ {
+ YYACCEPT;
+ }
+ ;
+
+aliases : STRING
+ {
+ $$ = append_string(NULL, $1);
+ }
+ | aliases ',' STRING
+ {
+ $$ = append_string($1, $3);
+ }
+ ;
+
+flags : flag
+ {
+ $$ = $1;
+ }
+ | flags ',' flag
+ {
+ $$ = $1 | $3;
+ }
+ ;
+flag : STRING
+ {
+ $$ = string_to_flag($1);
+ free($1);
+ }
+ ;
+
+
+
+%%
+
+void
+yyerror (char *s)
+{
+ error_message ("%s\n", s);
+}
+
+struct string_list*
+append_string(struct string_list *list, char *str)
+{
+ struct string_list *sl = malloc(sizeof(*sl));
+ sl->string = str;
+ sl->next = NULL;
+ if(list) {
+ *list->tail = sl;
+ list->tail = &sl->next;
+ return list;
+ }
+ sl->tail = &sl->next;
+ return sl;
+}
+
+void
+free_string_list(struct string_list *list)
+{
+ while(list) {
+ struct string_list *sl = list->next;
+ free(list->string);
+ free(list);
+ list = sl;
+ }
+}
+
+unsigned
+string_to_flag(const char *string)
+{
+ return 0;
+}
diff --git a/crypto/heimdal/lib/sl/roken_rename.h b/crypto/heimdal/lib/sl/roken_rename.h
new file mode 100644
index 000000000000..c668802ac5d5
--- /dev/null
+++ b/crypto/heimdal/lib/sl/roken_rename.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: roken_rename.h,v 1.3 1999/12/02 16:58:55 joda Exp $ */
+
+#ifndef __roken_rename_h__
+#define __roken_rename_h__
+
+#ifndef HAVE_STRTOK_R
+#define strtok_r _sl_strtok_r
+#endif
+#ifndef HAVE_SNPRINTF
+#define snprintf _sl_snprintf
+#endif
+#ifndef HAVE_ASPRINTF
+#define asprintf _sl_asprintf
+#endif
+#ifndef HAVE_ASNPRINTF
+#define asnprintf _sl_asnprintf
+#endif
+#ifndef HAVE_VASPRINTF
+#define vasprintf _sl_vasprintf
+#endif
+#ifndef HAVE_VASNPRINTF
+#define vasnprintf _sl_vasnprintf
+#endif
+#ifndef HAVE_VSNPRINTF
+#define vsnprintf _sl_vsnprintf
+#endif
+
+#endif /* __roken_rename_h__ */
diff --git a/crypto/heimdal/lib/sl/sl.c b/crypto/heimdal/lib/sl/sl.c
new file mode 100644
index 000000000000..688ca8b22a25
--- /dev/null
+++ b/crypto/heimdal/lib/sl/sl.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: sl.c,v 1.25 1999/12/02 16:58:55 joda Exp $");
+#endif
+
+#include "sl_locl.h"
+
+static SL_cmd *
+sl_match (SL_cmd *cmds, char *cmd, int exactp)
+{
+ SL_cmd *c, *current = NULL, *partial_cmd = NULL;
+ int partial_match = 0;
+
+ for (c = cmds; c->name; ++c) {
+ if (c->func)
+ current = c;
+ if (strcmp (cmd, c->name) == 0)
+ return current;
+ else if (strncmp (cmd, c->name, strlen(cmd)) == 0 &&
+ partial_cmd != current) {
+ ++partial_match;
+ partial_cmd = current;
+ }
+ }
+ if (partial_match == 1 && !exactp)
+ return partial_cmd;
+ else
+ return NULL;
+}
+
+void
+sl_help (SL_cmd *cmds, int argc, char **argv)
+{
+ SL_cmd *c, *prev_c;
+
+ if (argc == 1) {
+ prev_c = NULL;
+ for (c = cmds; c->name; ++c) {
+ if (c->func) {
+ if(prev_c)
+ printf ("\n\t%s%s", prev_c->usage ? prev_c->usage : "",
+ prev_c->usage ? "\n" : "");
+ prev_c = c;
+ printf ("%s", c->name);
+ } else
+ printf (", %s", c->name);
+ }
+ if(prev_c)
+ printf ("\n\t%s%s", prev_c->usage ? prev_c->usage : "",
+ prev_c->usage ? "\n" : "");
+ } else {
+ c = sl_match (cmds, argv[1], 0);
+ if (c == NULL)
+ printf ("No such command: %s. "
+ "Try \"help\" for a list of all commands\n",
+ argv[1]);
+ else {
+ printf ("%s\t%s\n", c->name, c->usage);
+ if(c->help && *c->help)
+ printf ("%s\n", c->help);
+ if((++c)->name && c->func == NULL) {
+ printf ("Synonyms:");
+ while (c->name && c->func == NULL)
+ printf ("\t%s", (c++)->name);
+ printf ("\n");
+ }
+ }
+ }
+}
+
+#ifdef HAVE_READLINE
+
+char *readline(char *prompt);
+void add_history(char *p);
+
+#else
+
+static char *
+readline(char *prompt)
+{
+ char buf[BUFSIZ];
+ printf ("%s", prompt);
+ fflush (stdout);
+ if(fgets(buf, sizeof(buf), stdin) == NULL)
+ return NULL;
+ if (buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ return strdup(buf);
+}
+
+static void
+add_history(char *p)
+{
+}
+
+#endif
+
+int
+sl_command(SL_cmd *cmds, int argc, char **argv)
+{
+ SL_cmd *c;
+ c = sl_match (cmds, argv[0], 0);
+ if (c == NULL)
+ return -1;
+ return (*c->func)(argc, argv);
+}
+
+struct sl_data {
+ int max_count;
+ char **ptr;
+};
+
+int
+sl_make_argv(char *line, int *ret_argc, char ***ret_argv)
+{
+ char *foo = NULL;
+ char *p;
+ int argc, nargv;
+ char **argv;
+
+ nargv = 10;
+ argv = malloc(nargv * sizeof(*argv));
+ if(argv == NULL)
+ return ENOMEM;
+ argc = 0;
+
+ for(p = strtok_r (line, " \t", &foo);
+ p;
+ p = strtok_r (NULL, " \t", &foo)) {
+ if(argc == nargv - 1) {
+ char **tmp;
+ nargv *= 2;
+ tmp = realloc (argv, nargv * sizeof(*argv));
+ if (tmp == NULL) {
+ free(argv);
+ return ENOMEM;
+ }
+ argv = tmp;
+ }
+ argv[argc++] = p;
+ }
+ argv[argc] = NULL;
+ *ret_argc = argc;
+ *ret_argv = argv;
+ return 0;
+}
+
+/* return values: 0 on success, -1 on fatal error, or return value of command */
+int
+sl_command_loop(SL_cmd *cmds, char *prompt, void **data)
+{
+ int ret = 0;
+ char *buf;
+ int argc;
+ char **argv;
+
+ ret = 0;
+ buf = readline(prompt);
+ if(buf == NULL)
+ return 1;
+
+ if(*buf)
+ add_history(buf);
+ ret = sl_make_argv(buf, &argc, &argv);
+ if(ret) {
+ fprintf(stderr, "sl_loop: out of memory\n");
+ free(buf);
+ return -1;
+ }
+ if (argc >= 1) {
+ ret = sl_command(cmds, argc, argv);
+ if(ret == -1) {
+ printf ("Unrecognized command: %s\n", argv[0]);
+ ret = 0;
+ }
+ }
+ free(buf);
+ free(argv);
+ return ret;
+}
+
+int
+sl_loop(SL_cmd *cmds, char *prompt)
+{
+ void *data = NULL;
+ int ret;
+ while((ret = sl_command_loop(cmds, prompt, &data)) == 0)
+ ;
+ return ret;
+}
diff --git a/crypto/heimdal/lib/sl/sl.h b/crypto/heimdal/lib/sl/sl.h
new file mode 100644
index 000000000000..1a6d3fa6e6e1
--- /dev/null
+++ b/crypto/heimdal/lib/sl/sl.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: sl.h,v 1.7 1999/12/02 16:58:55 joda Exp $ */
+
+#ifndef _SL_H
+#define _SL_H
+
+typedef int (*cmd_func)(int, char **);
+
+struct sl_cmd {
+ char *name;
+ cmd_func func;
+ char *usage;
+ char *help;
+};
+
+typedef struct sl_cmd SL_cmd;
+
+void sl_help (SL_cmd *, int argc, char **argv);
+int sl_loop (SL_cmd *, char *prompt);
+int sl_command_loop (SL_cmd *cmds, char *prompt, void **data);
+int sl_command (SL_cmd *cmds, int argc, char **argv);
+int sl_make_argv(char*, int*, char***);
+
+
+#endif /* _SL_H */
diff --git a/crypto/heimdal/lib/sl/sl_locl.h b/crypto/heimdal/lib/sl/sl_locl.h
new file mode 100644
index 000000000000..4bd966003b3d
--- /dev/null
+++ b/crypto/heimdal/lib/sl/sl_locl.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+/* $Id: sl_locl.h,v 1.6 1999/12/02 16:58:55 joda Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <roken.h>
+
+#include <sl.h>
diff --git a/crypto/heimdal/lib/sl/ss.c b/crypto/heimdal/lib/sl/ss.c
new file mode 100644
index 000000000000..f3c0546b4d78
--- /dev/null
+++ b/crypto/heimdal/lib/sl/ss.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "sl_locl.h"
+#include <com_err.h>
+#include "ss.h"
+
+RCSID("$Id: ss.c,v 1.4 1999/12/02 16:58:55 joda Exp $");
+
+struct ss_subst {
+ char *name;
+ char *version;
+ char *info;
+ ss_request_table *table;
+};
+
+static struct ss_subst subsystems[2];
+static int num_subsystems;
+
+int
+ss_create_invocation(const char *subsystem,
+ const char *version,
+ const char *info,
+ ss_request_table *table,
+ int *code)
+{
+ struct ss_subst *ss;
+ if(num_subsystems >= sizeof(subsystems) / sizeof(subsystems[0])) {
+ *code = 17;
+ return 0;
+ }
+ ss = &subsystems[num_subsystems];
+ ss->name = subsystem ? strdup(subsystem) : NULL;
+ ss->version = version ? strdup(version) : NULL;
+ ss->info = info ? strdup(info) : NULL;
+ ss->table = table;
+ *code = 0;
+ return num_subsystems++;
+}
+
+void
+ss_error (int index, long code, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ com_err_va (subsystems[index].name, code, fmt, ap);
+ va_end(ap);
+}
+
+void
+ss_perror (int index, long code, const char *msg)
+{
+ ss_error(index, code, "%s", msg);
+}
+
+int
+ss_execute_command(int index, char **argv)
+{
+ int argc = 0;
+ while(argv[argc++]);
+ sl_command(subsystems[index].table, argc, argv);
+ return 0;
+}
+
+int
+ss_execute_line (int index, const char *line)
+{
+ char *buf = strdup(line);
+ int argc;
+ char **argv;
+
+ sl_make_argv(buf, &argc, &argv);
+ sl_command(subsystems[index].table, argc, argv);
+ free(buf);
+ return 0;
+}
+
+int
+ss_listen (int index)
+{
+ char *prompt = malloc(strlen(subsystems[index].name) + 3);
+ if(prompt == NULL) {
+ abort();
+ }
+ strcpy(prompt, subsystems[index].name);
+ strcat(prompt, ": ");
+ sl_loop(subsystems[index].table, prompt);
+ free(prompt);
+ return 0;
+}
+
+int
+ss_list_requests(int argc, char **argv /* , int index, void *info */)
+{
+ sl_help(subsystems[0 /* index */].table, argc, argv);
+ return 0;
+}
+
+int
+ss_quit(int argc, char **argv)
+{
+ return 1;
+}
diff --git a/crypto/heimdal/lib/sl/ss.h b/crypto/heimdal/lib/sl/ss.h
new file mode 100644
index 000000000000..0d9d2977b7ac
--- /dev/null
+++ b/crypto/heimdal/lib/sl/ss.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ */
+/* $Id: ss.h,v 1.2 1999/12/02 16:58:55 joda Exp $ */
+
+/* SS compatibility for SL */
+
+#ifndef __ss_h__
+#define __ss_h__
+
+#include <sl.h>
+
+typedef SL_cmd ss_request_table;
+
+int ss_create_invocation (const char *, const char *, const char*,
+ ss_request_table*, int*);
+
+void ss_error (int, long, const char*, ...);
+int ss_execute_command (int, char**);
+int ss_execute_line (int, const char*);
+int ss_list_requests (int argc, char**);
+int ss_listen (int);
+void ss_perror (int, long, const char*);
+int ss_quit (int argc, char**);
+
+#endif /* __ss_h__ */
diff --git a/crypto/heimdal/ltconfig b/crypto/heimdal/ltconfig
new file mode 100755
index 000000000000..62ac4790feec
--- /dev/null
+++ b/crypto/heimdal/ltconfig
@@ -0,0 +1,2101 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != "Xset"; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+ test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH /usr/ucb; do
+ if test -f $dir/echo &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif test -f /bin/ksh && test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running ltconfig again with it.
+ ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ echo='printf %s\n'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.2d
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking.
+enable_static=yes
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+objext=o
+libext=a
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+ case "$option" in
+ -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ eval "$prev=\$option"
+ prev=
+ continue
+ fi
+
+ case "$option" in
+ --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+ --debug enable verbose shell tracing
+ --disable-shared do not build shared libraries
+ --disable-static do not build static libraries
+ --help display this help and exit
+ --no-verify do not verify that HOST is a valid host type
+-o, --output=FILE specify the output file [default=$default_ofile]
+ --quiet same as \`--silent'
+ --silent do not print informational messages
+ --srcdir=DIR find \`config.guess' in DIR
+ --version output version information and exit
+ --with-gcc assume that the GNU C compiler will be used
+ --with-gnu-ld assume that the C compiler uses the GNU linker
+ --disable-lock disable file locking
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --disable-shared) enable_shared=no ;;
+
+ --disable-static) enable_static=no ;;
+
+ --quiet | --silent) silent=yes ;;
+
+ --srcdir) prev=srcdir ;;
+ --srcdir=*) srcdir="$optarg" ;;
+
+ --no-verify) verify_host=no ;;
+
+ --output | -o) prev=ofile ;;
+ --output=*) ofile="$optarg" ;;
+
+ --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION"; exit 0 ;;
+
+ --with-gcc) with_gcc=yes ;;
+ --with-gnu-ld) with_gnu_ld=yes ;;
+
+ --disable-lock) need_locks=no ;;
+
+ -*)
+ echo "$progname: unrecognized option \`$option'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ if test -z "$ltmain"; then
+ ltmain="$option"
+ elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+# echo "$progname: warning \`$option' is not a valid host type" 1>&2
+# fi
+ host="$option"
+ else
+ echo "$progname: too many arguments" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+done
+
+if test -z "$ltmain"; then
+ echo "$progname: you must specify a LTMAIN file" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+if test ! -f "$ltmain"; then
+ echo "$progname: \`$ltmain' does not exist" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+ case "$arg" in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ltconfig_args="$ltconfig_args '$arg'" ;;
+ *) ltconfig_args="$ltconfig_args $arg" ;;
+ esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+ # Assume the source directory is the same one as the path to LTMAIN.
+ srcdir=`$echo "$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+ test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+ # Check for config.guess and config.sub.
+ ac_aux_dir=
+ for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/config.guess; then
+ ac_aux_dir=$ac_dir
+ break
+ fi
+ done
+ if test -z "$ac_aux_dir"; then
+ echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+ ac_config_guess=$ac_aux_dir/config.guess
+ ac_config_sub=$ac_aux_dir/config.sub
+
+ # Make sure we can run config.sub.
+ if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+ else
+ echo "$progname: cannot run $ac_config_sub" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+
+ echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+ host_alias=$host
+ case "$host_alias" in
+ "")
+ if host_alias=`$SHELL $ac_config_guess`; then :
+ else
+ echo "$progname: cannot guess host type; you must specify one" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+ host=`$SHELL $ac_config_sub $host_alias`
+ echo "$ac_t$host" 1>&6
+
+ # Make sure the host verified.
+ test -z "$host" && exit 1
+
+elif test -z "$host"; then
+ echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+else
+ host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "${COLLECT_NAMES+set}" != set; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+ result=no
+
+ echo $ac_n "checking for ranlib... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/ranlib; then
+ RANLIB="ranlib"
+ result="ranlib"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL' and `AS', used on cygwin32.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+ # If CC is not set, then try to find GCC or a usable CC.
+ if test -z "$CC"; then
+ echo $ac_n "checking for gcc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ IFS="$save_ifs"
+ test -z "$dir" && dir=.
+ if test -f $dir/gcc; then
+ CC="gcc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+ fi
+
+ # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+ if test -z "$CC"; then
+ echo $ac_n "checking for cc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ cc_rejected=no
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/cc; then
+ if test "$dir/cc" = "/usr/ucb/cc"; then
+ cc_rejected=yes
+ continue
+ fi
+ CC="cc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test $cc_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same name, so the bogon will be chosen
+ # first if we set CC to just the name; use the full file name.
+ shift
+ set dummy "$dir/cc" "$@"
+ shift
+ CC="$@"
+ fi
+ fi
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$CC"; then
+ echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+ exit 1
+ fi
+ fi
+
+ # Now see if the compiler is really GCC.
+ with_gcc=no
+ echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+ echo "$progname:530: checking whether we are using GNU C" >&5
+
+ $rm conftest.c
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+ if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:538: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ with_gcc=yes
+ fi
+ $rm conftest.c
+ echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:552: checking for object suffix" >& 5
+if { (eval echo $progname:553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+else
+ cat conftest.err 1>&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+ wl='-Wl,'
+ link_static_flag='-static'
+
+ case "$host_os" in
+ aix3* | aix4* | irix5* | irix6* | osf3* | osf4*)
+ # PIC is the default for these OSes.
+ ;;
+ cygwin32* | mingw32* | os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ pic_flag='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ *)
+ pic_flag='-fPIC'
+ ;;
+ esac
+else
+ # PORTME Check for PIC flags for the system compiler.
+ case "$host_os" in
+ aix3* | aix4*)
+ # All AIX code is PIC.
+ link_static_flag='-bnso -bI:/lib/syscalls.exp'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ # Is there a better link_static_flag that works with the bundled CC?
+ wl='-Wl,'
+ link_static_flag="${wl}-a ${wl}archive"
+ pic_flag='+Z'
+ ;;
+
+ irix5* | irix6*)
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ cygwin32* | mingw32* | os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+
+ osf3* | osf4*)
+ # All OSF/1 code is PIC.
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ pic_flag='-Kpic'
+ link_static_flag='-dn'
+ special_shlib_compile_flags='-belf'
+ ;;
+
+ solaris*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ sunos4*)
+ pic_flag='-PIC'
+ link_static_flag='-Bstatic'
+ wl='-Qoption ld '
+ ;;
+
+ sysv4.2uw2* | sysv5*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ uts4*)
+ pic_flag='-pic'
+ link_static_flag='-Bstatic'
+ ;;
+
+ *)
+ can_build_shared=no
+ ;;
+ esac
+fi
+
+if test -n "$pic_flag"; then
+ echo "$ac_t$pic_flag" 1>&6
+
+ # Check to make sure the pic_flag actually works.
+ echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $pic_flag -DPIC"
+ echo "$progname:674: checking if $compiler PIC flag $pic_flag works" >&5
+ if { (eval echo $progname:675: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+ # create non-PIC objects. So, if there were any warnings, we assume that
+ # PIC is not supported.
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ can_build_shared=no
+ pic_flag=
+ else
+ echo "$ac_t"yes 1>&6
+ pic_flag=" $pic_flag"
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ can_build_shared=no
+ pic_flag=
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -c -o conftest2.o"
+echo "$progname:709: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:710: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest2.o; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_c_o=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_c_o=no
+ echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+$rm conftest*
+
+if test x"$compiler_c_o" = x"yes"; then
+ # Check to see if we can write to a .lo
+ echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -c -o conftest.lo"
+ echo "$progname:737: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:738: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_o_lo=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_o_lo=yes
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_o_lo=no
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ echo "$ac_t$hard_links" 1>&6
+ $rm conftest*
+ if test "$hard_links" = no; then
+ echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+ echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+ echo "$progname:789: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+ if { (eval echo $progname:790: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_rtti_exceptions=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_rtti_exceptions=yes
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_rtti_exceptions=no
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+
+ if test "$compiler_rtti_exceptions" = "yes"; then
+ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+ else
+ no_builtin_flag=' -fno-builtin'
+ fi
+
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+ echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then :
+ else
+ echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+ can_build_shared=no
+ fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:833: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:834: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ echo "$ac_t$link_static_flag" 1>&6
+else
+ echo "$ac_t"none 1>&6
+ link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+ # Check to see if we can use ln -s, or we need hard links.
+ echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+ $rm conftestdata
+ if ln -s X conftestdata 2>/dev/null; then
+ $rm conftestdata
+ LN_S="ln -s"
+ else
+ LN_S=ln
+ fi
+ if test "$LN_S" = "ln -s"; then
+ echo "$ac_t"yes 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+ ac_prog=ld
+ if test "$with_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+ echo "$progname:866: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ /* | [A-Za-z]:/*)
+ re_direlt='/[^/][^/]*/\.\./'
+ sub_uncdrive='s%^\([A-Za-z]\):/%//\1/%'
+ # Canonicalize the path of ld
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ case "$host_os" in
+ cygwin*)
+ # Convert to a UNC path for cygwin
+ test -z "$LD" && LD=`echo X$ac_prog | $Xsed -e "$sub_uncdrive"`
+ ;;
+ *)
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ esac
+ ;;
+ ##
+ ## FIXME: The code fails later on if we try to use an $LD with
+ ## '\\' path separators.
+ ##
+ [A-Za-z]:[\\]*)
+ re_direlt='\\[^\\][^\\]*\\\.\.\(\\\)'
+ sub_uncdrive='s%^\([A-Za-z]\):\\%//\1/%'
+ sub_uncdir='s%\\%/%g'
+ # Canonicalize the path of ld
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%\1%"`
+ done
+ case "$host_os" in
+ cygwin*)
+ # Convert to a UNC path for cygwin
+ test -z "$LD" && LD=`echo X$ac_prog | $Xsed -e "$sub_uncdrive" -e "$sub_uncdir"`
+ ;;
+ *)
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ esac
+ ;;
+ "")
+ # If it fails, then pretend we are not using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+ elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+ echo "$progname:920: checking for GNU ld" >&5
+ else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+ echo "$progname:923: checking for non-GNU ld" >&5
+ fi
+
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ fi
+
+ if test -n "$LD"; then
+ echo "$ac_t$LD" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$LD"; then
+ echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+ exit 1
+ fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+archive_cmds=
+archive_sym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+
+case "$host_os" in
+aix3* | aix4*)
+ # On AIX, the GNU linker works like the native linker.
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+
+ # See if GNU ld supports shared libraries.
+ case "$host_os" in
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib$libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib$libobjs$deplibs'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ cygwin32* | mingw32*)
+ if test "$with_gcc" = yes; then
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ # Very, very bogus.
+ echo '
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <stdio.h>
+
+BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+
+#include <cygwin/cygwin_dll.h>
+DECLARE_CYGWIN_DLL( DllMain );
+HINSTANCE __hDllInstance_base;
+
+BOOL APIENTRY
+DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+{
+ __hDllInstance_base = hInst;
+ return TRUE;
+}
+' > ltdll.c
+ archive_cmds='$CC -c '"`pwd`"'/ltdll.c~echo EXPORTS > $lib-def~
+ $DLLTOOL --export-all --output-def $lib-def $libobjs ltdll.$objext~
+ $CC -Wl,--base-file,$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 $libobjs ltdll.$objext~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbol=_cygwin_dll_entry@12 --def $lib-def --base-file $soname-base --output-exp $soname-exp~
+ $CC -Wl,--base-file,$soname-base $soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $libobjs ltdll.$objext$deplibs~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbol=_cygwin_dll_entry@12 --def $lib-def --base-file $soname-base --output-exp $soname-exp~
+ $CC $soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $libobjs ltdll.$objext$deplibs~
+ $rm ltdll.$objext $soname-base $soname-exp'
+ archive_sym_cmds='$CC -c '"`pwd`"'/ltdll.c~echo EXPORTS > $lib-def~
+ cat "$export_symbols" >> $lib-def~
+ $CC -Wl,--base-file,$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 $libobjs ltdll.$objext~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbol=_cygwin_dll_entry@12 --def $lib-def --base-file $soname-base --output-exp $soname-exp~
+ $CC -Wl,--base-file,$soname-base $soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $libobjs ltdll.$objext$deplibs~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbol=_cygwin_dll_entry@12 --def $lib-def --base-file $soname-base --output-exp $soname-exp~
+ $CC $soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $libobjs ltdll.$objext$deplibs~
+ $rm ltdll.$objext $soname-base $soname-exp'
+ old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $lib-def --output-lib $objdir/$libname.a~$rm $lib.exp'
+ else
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ with_gnu_ld=no
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib$libobjs`echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+ fix_srcfile_path='`cygpath -w $srcfile`'
+ fi
+ ;;
+
+ *)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared ${wl}-soname $wl$soname -o $lib$libobjs$deplibs'
+ archive_sym_cmds='$CC -shared ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib$libobjs$deplibs'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = yes && test "$with_gnu_ld" = yes; then
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case "$host_os" in
+ aix3*)
+ allow_undefined_flag=unsupported
+ archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '\''s/.* //'\' | sort | uniq' > $lib.exp~
+ $LD -o $objdir/$soname$libobjs$deplibs -bE:$lib.exp -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+ archive_sym_cmds='$LD -o $objdir/$soname$libobjs$deplibs -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4*)
+ allow_undefined_flag=unsupported
+ archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '\''s/.* //'\' | sort | uniq' > $lib.exp else cat $export_symbols > $lib.exp~
+ $CC -o $objdir/$soname$libobjs$deplibs ${wl}-bE:$lib.exp ${wl}-bM:SRE ${wl}-bnoentry~$AR cru $lib $objdir/$soname'
+ archive_sym_cmds='$CC -o $objdir/$soname$libobjs$deplibs ${wl}-bE:$export_symbols ${wl}-bM:SRE ${wl}-bnoentry~$AR cru $lib $objdir/$soname'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib$libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+
+ cygwin32* | mingw32*)
+ if test "$with_gcc" = yes; then
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ # Very, very bogus.
+ echo '
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <stdio.h>
+
+BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+
+#include <cygwin/cygwin_dll.h>
+DECLARE_CYGWIN_DLL( DllMain );
+HINSTANCE __hDllInstance_base;
+
+BOOL APIENTRY
+DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+{
+ __hDllInstance_base = hInst;
+ return TRUE;
+}
+' > ltdll.c
+ archive_cmds='$CC -c '"`pwd`"'/ltdll.c~echo EXPORTS > $lib-def~
+ $DLLTOOL --export-all --output-def $lib-def $libobjs ltdll.$objext~
+ $CC -Wl,--base-file,$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 $libobjs ltdll.$objext~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbol=_cygwin_dll_entry@12 --def $lib-def --base-file $soname-base --output-exp $soname-exp~
+ $CC -Wl,--base-file,$soname-base $soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $libobjs ltdll.$objext$deplibs~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbol=_cygwin_dll_entry@12 --def $lib-def --base-file $soname-base --output-exp $soname-exp~
+ $CC $soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $libobjs ltdll.$objext$deplibs~
+ $rm ltdll.$objext $soname-base $soname-exp'
+ archive_sym_cmds='$CC -c '"`pwd`"'/ltdll.c~echo EXPORTS > $lib-def~
+ cat "$export_symbols" >> $lib-def~
+ $CC -Wl,--base-file,$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 $libobjs ltdll.$objext~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbol=_cygwin_dll_entry@12 --def $lib-def --base-file $soname-base --output-exp $soname-exp~
+ $CC -Wl,--base-file,$soname-base $soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $libobjs ltdll.$objext$deplibs~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbol=_cygwin_dll_entry@12 --def $lib-def --base-file $soname-base --output-exp $soname-exp~
+ $CC $soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $libobjs ltdll.$objext$deplibs~
+ $rm ltdll.$objext $soname-base $soname-exp'
+ old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $lib-def --output-lib $objdir/$libname.a~$rm $lib.exp'
+ else
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib$libobjs`echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+ fix_srcfile_path='`cygpath -w $srcfile`'
+ fi
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3, at last, uses gcc -shared to do shared libraries.
+ freebsd3*)
+ archive_cmds='$CC -shared -o $lib$libobjs$deplibs'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ archive_cmds='$rm $objdir/$soname~$LD -b +s +b $install_libdir -o $objdir/$soname$libobjs$deplibs~test $objdir/$soname = $lib || mv $objdir/$soname $lib'
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10* | hpux11*)
+ archive_cmds='$LD -b +h $soname +s +b $install_libdir -o $lib$libobjs$deplibs'
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6*)
+ if test "$with_gcc" = yes; then
+ archive_cmds='$CC -shared -o $lib ${wl}-soname ${wl}$soname ${wl}-set_version ${wl}$verstring$libobjs$deplibs'
+ else
+ archive_cmds='$LD -shared -o $lib -soname $soname -set_version $verstring$libobjs$deplibs'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ ;;
+
+ netbsd*)
+ # Tested with NetBSD 1.2 ld
+ archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp$libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib$libobjs$deplibs $objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+ ;;
+
+ osf3* | osf4*)
+ if test "$with_gcc" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} -o $lib ${wl}-soname ${wl}$soname ${wl}-set_version ${wl}$verstring$libobjs$deplibs'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} -o $lib -soname $soname -set_version $verstring$libobjs$deplibs'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -o $lib$libobjs$deplibs'
+ hardcode_direct=yes
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib$libobjs$deplibs'
+ archive_sym_cmds='$echo "{ global:" > $lib.exp~sed $export_symbols -e "s/.*/\1;/" >> $lib.exp~$echo "local: * }" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $export_symbols -h $soname -o $lib$libobjs$deplibs~$rm $lib.exp'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+
+ # Solaris 2 before 2.5 hardcodes -L paths.
+ case "$host_os" in
+ solaris2.[0-4]*)
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ # Why do we need -Bstatic? To avoid inter-library dependencies, maybe...
+ if test "$with_gcc" = yes; then
+ archive_cmds='$CC -shared ${wl}-Bstatic -o $lib$libobjs$deplibs'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib$libobjs$deplibs'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=no
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=no
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ can_build_shared=no
+ ;;
+ esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+
+if test -z "$NM"; then
+ echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+ case "$NM" in
+ /* | [A-Za-z]:[/\\]*) ;; # Let the user override the test with a path.
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -B"
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -p"
+ else
+ NM="$ac_dir/nm"
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$NM" && NM=nm
+ ;;
+ esac
+ echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRSTU]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \1'
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ symcode='[BCDTU]'
+ ;;
+sunos* | cygwin32* | mingw32*)
+ sympat='_\([_A-Za-z][_A-Za-z0-9]*\)'
+ symxfrm='_\1 \1'
+ ;;
+irix*)
+ # Cannot use undefined symbols on IRIX because inlined functions mess us up.
+ symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ symcode='[BDTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[ABCDGISTUW]'
+fi
+
+case "$host_os" in
+cygwin32* | mingw32*)
+ # We do not want undefined symbols on cygwin32. The user must
+ # arrange to define them via -l arguments.
+ symcode='[ABCDGISTW]'
+ ;;
+esac
+
+# Write the raw and C identifiers.
+global_symbol_pipe="sed -n -e 's/^.* $symcode $sympat$/$symxfrm/p'"
+
+# Check to see that the pipe works correctly.
+pipe_works=no
+$rm conftest*
+cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+echo "$progname:1425: checking if global_symbol_pipe works" >&5
+if { (eval echo $progname:1426: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { echo "$progname:1429: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ wcout=`wc "$nlist" 2>/dev/null`
+ count=`$echo "X$wcout" | $Xsed -e 's/^[ ]*\([0-9][0-9]*\).*$/\1/'`
+ (test "$count" -ge 0) 2>/dev/null || count=-1
+ else
+ rm -f "$nlist"T
+ count=-1
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ sed 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> conftest.c
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+ char *name;
+ __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{
+EOF
+ sed 's/^\(.*\) \(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (__ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$objext conftestm.$objext
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="conftestm.$objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo $progname:1487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ pipe_works=yes
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$save_LIBS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $global_symbol_pipe" >&5
+ fi
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+fi
+$rm conftest*
+
+# Do not use the global_symbol_pipe unless it works.
+echo "$ac_t$pipe_works" 1>&6
+test "$pipe_works" = yes || global_symbol_pipe=
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no && \
+ test "$hardcode_minus_L" != no && \
+ test "$hardcode_shlibpath_var" != no; then
+
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_search_path="/lib /usr/lib /usr/local/lib"
+check_shared_deplibs_method='none'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_regex' -- check by looking for filenames that look like the shared
+# library in the library path.
+# 'file_magic [regex]' -- check by looking for files in library path which
+# responds to the "file" command with a given regex. This is actually a
+# superset of the file_regex command. If you have file on your system, you'll
+# want to use this instead.
+# Notes: regexes are run through expr.
+
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3* | aix4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so$major'
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+bsdi4*)
+ version_type=linux
+ library_names_spec='${libname}.so.$major ${libname}.so'
+ soname_spec='${libname}.so'
+ finish_cmds='PATH="$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+cygwin32* | mingw32*)
+ version_type=windows
+ if test "$with_gcc" = yes; then
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+ else
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+ fi
+ dynamic_linker='Win32 ld.exe'
+ libname_spec='$name'
+ shlibpath_var=PATH
+ ;;
+
+freebsd2* | freebsd3*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ library_names_spec='${libname}${release}.so$versuffix $libname.so'
+ finish_cmds='PATH="$PATH:/sbin" OBJFORMAT="$objformat" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+gnu*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ shlibpath_var=SHLIB_PATH
+ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+ soname_spec='${libname}${release}.sl$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+irix6*)
+ version_type=osf
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix $libname.so'
+ shlibpath_var=LD_LIBRARYN32_PATH
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ check_shared_deplibs_method='file_magic ELF 32-bit LSB shared object'
+ sys_lib_search_path="/lib /usr/lib /usr/local/lib `echo $LD_LIBRARY_PATH | sed -e 's/:/ /g'`"
+
+ if test -f /lib/ld.so.1; then
+ dynamic_linker='GNU ld.so'
+ else
+ # Only the GNU ld.so supports shared libraries on MkLinux.
+ case "$host_cpu" in
+ powerpc*) dynamic_linker=no ;;
+ *) dynamic_linker='Linux ld.so' ;;
+ esac
+ fi
+ ;;
+
+netbsd* | openbsd*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4*)
+ version_type=osf
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ check_shared_deplibs_method='pass_all'
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sysv4.2uw2*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+ soname_spec='${libname}${release}.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+dgux*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+ # Now quote all the things that may contain metacharacters.
+ for var in ltecho old_CC old_CFLAGS old_CPPFLAGS old_LD old_NM old_RANLIB \
+ old_LN_S old_DLLTOOL old_AS AR CC LD LN_S NM LTSHELL VERSION \
+ reload_flag reload_cmds wl \
+ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ whole_archive_flag_spec libname_spec library_names_spec soname_spec \
+ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds archive_sym_cmds postinstall_cmds postuninstall_cmds \
+ check_shared_deplibs_method allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe \
+ hardcode_libdir_flag_spec hardcode_libdir_separator sys_lib_search_path \
+ compiler_c_o compiler_o_lo need_locks; do
+
+ case "$var" in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ archive_cmds | archive_sym_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ finish_cmds | sys_lib_search_path)
+ # Double-quote double-evaled strings.
+ eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ *)
+ eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ case "$ltecho" in
+ *'\$0 --fallback-echo"')
+ ltecho=`$echo "X$ltecho" |
+ $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+ ;;
+ esac
+
+ trap "$rm \"$ofile\"; exit 1" 1 2 15
+ echo "creating $ofile"
+ $rm "$ofile"
+ cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+ cfgfile="$ofile"
+ ;;
+
+*)
+ # Double-quote the variables that need it (for aesthetics).
+ for var in old_CC old_CFLAGS old_CPPFLAGS old_LD old_NM old_RANLIB \
+ old_LN_S old_DLLTOOL old_AS; do
+ eval "$var=\\\"\$var\\\""
+ done
+
+ # Just create a config file.
+ cfgfile="$ofile.cfg"
+ trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+ echo "creating $cfgfile"
+ $rm "$cfgfile"
+ cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION)
+EOF
+ ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL="$old_DLLTOOL" AS="$old_AS" \\
+# $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin32: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin32: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_sym_cmds=$archive_sym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+check_shared_deplibs_method=$check_shared_deplibs_method
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# System search path for libraries
+sys_lib_search_path=$sys_lib_search_path
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+EOF
+
+case "$ltmain" in
+*.sh)
+ echo '### END LIBTOOL CONFIG' >> "$ofile"
+ echo >> "$ofile"
+ case "$host_os" in
+ aix3*)
+ cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "${COLLECT_NAMES+set}" != set; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ # Append the ltmain.sh script.
+ cat "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+
+ chmod +x "$ofile"
+ ;;
+
+*)
+ # Compile the libtool program.
+ echo "FIXME: would compile $ltmain"
+ ;;
+esac
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/crypto/heimdal/ltmain.sh b/crypto/heimdal/ltmain.sh
new file mode 100644
index 000000000000..397cc1e2b63e
--- /dev/null
+++ b/crypto/heimdal/ltmain.sh
@@ -0,0 +1,3079 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell, and then maybe $echo will work.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.2d
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+ save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+ save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+ echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ echo "$modename: not configured to build any kind of library" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+los2o="s/\\.lo /.${objext} /g"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+ arg="$1"
+ shift
+
+ case "$arg" in
+ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ execute_dlfiles)
+ eval "$prev=\"\$$prev \$arg\""
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
+ prev=
+ prevopt=
+ continue
+ fi
+
+ # Have we seen a non-optional argument yet?
+ case "$arg" in
+ --help)
+ show_help=yes
+ ;;
+
+ --version)
+ echo "$PROGRAM (GNU $PACKAGE) $VERSION"
+ exit 0
+ ;;
+
+ --config)
+ sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --dry-run | -n)
+ run=:
+ ;;
+
+ --features)
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+ exit 0
+ ;;
+
+ --finish) mode="finish" ;;
+
+ --mode) prevopt="--mode" prev=mode ;;
+ --mode=*) mode="$optarg" ;;
+
+ --quiet | --silent)
+ show=:
+ ;;
+
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
+ -*)
+ $echo "$modename: unrecognized option \`$arg'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ nonopt="$arg"
+ break
+ ;;
+ esac
+done
+
+if test -n "$prevopt"; then
+ $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+fi
+
+if test -z "$show_help"; then
+
+ # Infer the operation mode.
+ if test -z "$mode"; then
+ case "$nonopt" in
+ *cc | *++ | gcc* | *-gcc*)
+ mode=link
+ for arg
+ do
+ case "$arg" in
+ -c)
+ mode=compile
+ break
+ ;;
+ esac
+ done
+ ;;
+ *db | *dbx | *strace | *truss)
+ mode=execute
+ ;;
+ *install*|cp|mv)
+ mode=install
+ ;;
+ *rm)
+ mode=uninstall
+ ;;
+ *)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
+ # Just use the default operation mode.
+ if test -z "$mode"; then
+ if test -n "$nonopt"; then
+ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+ else
+ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+ fi
+ fi
+ ;;
+ esac
+ fi
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$modename --help --mode=$mode' for more information."
+
+ # These modes are in order of execution frequency so that they run quickly.
+ case "$mode" in
+ # libtool compile mode
+ compile)
+ modename="$modename: compile"
+ # Get the compilation command and the source file.
+ base_compile=
+ lastarg=
+ srcfile="$nonopt"
+ suppress_output=
+ force_static=no
+
+ user_target=no
+ for arg
+ do
+ # Accept any command-line options.
+ case "$arg" in
+ -o)
+ if test "$user_target" != "no"; then
+ $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+ exit 1
+ fi
+ user_target=next
+ ;;
+
+ -force-static)
+ force_static=yes
+ continue
+ ;;
+
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
+ esac
+
+ case "$user_target" in
+ next)
+ # The next one is the -o target name
+ user_target=yes
+ continue
+ ;;
+ yes)
+ # We got the output file
+ user_target=set
+ libobj="$arg"
+ continue
+ ;;
+ esac
+
+ # Accept the current argument as the source file.
+ lastarg="$srcfile"
+ srcfile="$arg"
+
+ # Aesthetically quote the previous argument.
+
+ # Backslashify any backslashes, double quotes, and dollar signs.
+ # These are the only characters that are still specially
+ # interpreted inside of double-quoted scrings.
+ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly in scan
+ # sets, so we specify it separately.
+ case "$lastarg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ lastarg="\"$lastarg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ done
+
+ case "$user_target" in
+ set)
+ ;;
+ no)
+ # Get the name of the library object.
+ libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ ;;
+ *)
+ $echo "$modename: you must specify a target with \`-o'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ xform='[cCFSfmso]'
+ case "$libobj" in
+ *.ada) xform=ada ;;
+ *.adb) xform=adb ;;
+ *.ads) xform=ads ;;
+ *.asm) xform=asm ;;
+ *.c++) xform=c++ ;;
+ *.cc) xform=cc ;;
+ *.cpp) xform=cpp ;;
+ *.cxx) xform=cxx ;;
+ *.f90) xform=f90 ;;
+ *.for) xform=for ;;
+ esac
+
+ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+ case "$libobj" in
+ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+ *)
+ $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$base_compile"; then
+ $echo "$modename: you must specify a compilation command" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $libobj $lockfile"
+ else
+ removelist="$libobj $lockfile"
+ fi
+
+ $run $rm $removelist
+ trap "$run $rm $removelist; exit 1" 1 2 15
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ removelist="$removelist $output_obj $lockfile"
+ trap "$run $rm $removelist; exit 1" 1 2 15
+ else
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until ln "$0" "$lockfile" 2>/dev/null; do
+ $show "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+ echo $srcfile > "$lockfile"
+ fi
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ command="$base_compile$pic_flag -DPIC $srcfile"
+ if test "$compiler_o_lo" = yes; then
+ command="$command -o $libobj"
+ output_obj="$libobj"
+ elif test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ output_obj="$obj"
+ fi
+
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ test -n "$output_obj" && $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test "$compiler_o_lo" = no && test x"$output_obj" != x"$libobj"; then
+ $show "$mv $output_obj $libobj"
+ if $run $mv $output_obj $libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # If we have no pic_flag and do not have -force-static,
+ # then copy the object into place and finish.
+ if test -z "$pic_flag" && test "$force_static" = no; then
+ $show "$LN_S $libobj $obj"
+ if $run $LN_S $libobj $obj; then
+ exit 0
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Allow error messages only from the first compilation.
+ suppress_output=' >/dev/null 2>&1'
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ command="$base_compile $srcfile"
+ if test "$force_static" = yes; then
+ command="$command -DLIBTOOL_STATIC"
+ fi
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ output_obj="$obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed
+ if test "$compiler_c_o" = no && test x"$output_obj" != x"$obj"; then
+ $show "$mv $output_obj $obj"
+ if $run $mv $output_obj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+ fi
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $rm "$lockfile"
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we do not
+ # accidentally link it into a program.
+ if test "$build_libtool_libs" != yes; then
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > \$libobj" || exit $?
+ fi
+
+ exit 0
+ ;;
+
+ # libtool link mode
+ link)
+ modename="$modename: link"
+ C_compiler="$CC" # save it, to compile generated C sources
+ CC="$nonopt"
+ allow_undefined=yes
+ compile_command="$CC"
+ finalize_command="$CC"
+
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ eval lib_search_path=\"$sys_lib_search_path\"
+
+ dlfiles=
+ dlprefiles=
+ export_dynamic=no
+ export_symbols=
+ generated=
+ hardcode_libdirs=
+ libobjs=
+ link_against_libtool_libs=
+ ltlibs=
+ module=no
+ objs=
+ prev=
+ prevarg=
+ release=
+ rpath=
+ perm_rpath=
+ temp_rpath=
+ vinfo=
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case "$arg" in
+ -all-static | -static)
+ if test "X$arg" = "X-all-static" && test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+ fi
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test $# -gt 0; do
+ arg="$1"
+ shift
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ output)
+ compile_command="$compile_command @OUTPUT@"
+ finalize_command="$finalize_command @OUTPUT@"
+ ;;
+ esac
+
+ case "$prev" in
+ dlfiles|dlprefiles)
+ case "$arg" in
+ *.la | *.lo) ;; # We handle these cases below.
+ *)
+ dlprefiles="$dlprefiles $arg"
+ test "$prev" = dlfiles && dlfiles="$dlfiles $arg"
+ prev=
+ ;;
+ esac
+ ;;
+ exportsyms)
+ export_symbols="$arg"
+ if test ! -f "$arg"; then
+ $echo "$modename: symbol file \`$arg' does not exist"
+ exit 1
+ fi
+ prev=
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath)
+ rpath="$rpath $arg"
+ prev=
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi
+
+ prevarg="$arg"
+
+ case "$arg" in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ if test "$export_dynamic" != yes; then
+ export_dynamic=yes
+ if test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ else
+ arg=
+ fi
+
+ # Add the symbol object into the linking commands.
+ compile_command="$compile_command @SYMFILE@"
+ finalize_command="$finalize_command @SYMFILE@"
+ fi
+ ;;
+
+ -export-symbols)
+ if test -n "$export_symbols"; then
+ $echo "$modename: cannot have more than one -exported-symbols"
+ exit 1
+ fi
+ prev=exportsyms
+ continue
+ ;;
+
+ -L*)
+ dir=`$echo "X$arg" | $Xsed -e 's%^-L\(.*\)$%\1%'`
+ case "$dir" in
+ /* | [A-Za-z]:[/\\]*)
+ # Add the corresponding hardcode_libdir_flag, if it is not identical.
+ ;;
+ *)
+ $echo "$modename: \`-L$dir' cannot specify a relative directory" 1>&2
+ exit 1
+ ;;
+ esac
+ deplibs="$deplibs $arg"
+ lib_search_path="$lib_search_path `expr $arg : '-L\(.*\)'`"
+ ;;
+
+ -l*) deplibs="$deplibs $arg" ;;
+
+ -module)
+ if test "$module" != yes; then
+ module=yes
+ if test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ else
+ arg=
+ fi
+ fi
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -static)
+ # If we have no pic_flag, then this is the same as -all-static.
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+
+ *.o | *.obj | *.a | *.lib)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A library object.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test "$build_libtool_libs" = yes; then
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+ prev=
+ fi
+ libobjs="$libobjs $arg"
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ dlname=
+ libdir=
+ library_names=
+ old_library=
+
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variable installed.
+ installed=yes
+
+ # If there is no directory component, then add one.
+ case "$arg" in
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
+ esac
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+
+ if test -z "$linklib"; then
+ $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Find the relevant object directory and library name.
+ name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+ if test "X$installed" = Xyes; then
+ dir="$libdir"
+ else
+ dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$arg"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ fi
+
+ if test -z "$libdir"; then
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $dir/$old_library"
+ old_convenience="$old_convenience $dir/$old_library"
+ deplibs="$deplibs$dependency_libs"
+ compile_command="$compile_command $dir/$old_library$dependency_libs"
+ finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+ continue
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test -z "$dlname" || test "$build_libtool_libs" = no; then
+ # If there is no dlname or we're linking statically,
+ # we need to preload.
+ prev=dlprefiles
+ else
+ # We should not create a dependency on this library, but we
+ # may need any libraries it requires.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ prev=
+ continue
+ fi
+ fi
+
+ # The library was specified with -dlpreopen.
+ if test "$prev" = dlprefiles; then
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ dlprefiles="$dlprefiles $dir/$old_library"
+ else
+ dlprefiles="$dlprefiles $dir/$linklib"
+ fi
+ prev=
+ fi
+
+ if test "$build_libtool_libs" = yes && test -n "$library_names"; then
+ link_against_libtool_libs="$link_against_libtool_libs $arg"
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
+
+ # This is the magic to use -rpath.
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ # Put the magic libdir with the hardcode flag.
+ hardcode_libdirs="$libdir"
+ libdir="@HARDCODE_LIBDIRS@"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ libdir=
+ fi
+ fi
+
+ if test -n "$libdir"; then
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ compile_command="$compile_command $flag"
+ finalize_command="$finalize_command $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ # Do the same for the permanent run path.
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+
+
+ lib_linked=yes
+ case "$hardcode_action" in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ compile_command="$compile_command $dir/$linklib"
+ elif test "$hardcode_minus_L" = no; then
+ case "$host" in
+ *-*-sunos*)
+ compile_shlibpath="$compile_shlibpath$dir:"
+ ;;
+ esac
+ compile_command="$compile_command -L$dir -l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ compile_shlibpath="$compile_shlibpath$dir:"
+ compile_command="$compile_command -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ relink)
+ # We need an absolute path.
+ case "$dir" in
+ /* | [A-Za-z]:[/\\]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+ exit 1
+ fi
+ dir="$absdir"
+ ;;
+ esac
+
+ if test "$hardcode_direct" = yes; then
+ compile_command="$compile_command $dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ compile_command="$compile_command -L$dir -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ compile_shlibpath="$compile_shlibpath$dir:"
+ compile_command="$compile_command -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ *)
+ lib_linked=no
+ ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ $echo "$modename: configuration error: unsupported hardcode properties"
+ exit 1
+ fi
+
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes; then
+ finalize_command="$finalize_command $libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ finalize_command="$finalize_command -L$libdir -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ finalize_shlibpath="$finalize_shlibpath$libdir:"
+ finalize_command="$finalize_command -l$name"
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ finalize_command="$finalize_command -L$libdir -l$name"
+ fi
+ else
+ # Transform directly to old archives if we don't build new libraries.
+ if test -n "$pic_flag" && test -z "$old_library"; then
+ $echo "$modename: cannot find static library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_command="$compile_command $dir/$linklib"
+ finalize_command="$finalize_command $dir/$linklib"
+ else
+ compile_command="$compile_command -L$dir -l$name"
+ finalize_command="$finalize_command -L$dir -l$name"
+ fi
+ fi
+
+ # Add in any libraries that this one depends upon.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+ esac
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+ done
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$export_symbols" && test "$module" = yes; then
+ $echo "$modename: \`-export-symbols' is not supported for modules"
+ exit 1
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+
+ case "$output" in
+ "")
+ $echo "$modename: you must specify an output file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *.a | *.lib)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles"; then
+ $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$export_symbols"; then
+ $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+ fi
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ ;;
+
+ *.la)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case "$outputname" in
+ lib*) ;;
+ *)
+ $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval libname=\"$libname_spec\"
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ if test -n "$objs"; then
+ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+ exit 1
+ fi
+
+ # How the heck are we supposed to write a wrapper for a shared library?
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+ exit 1
+ fi
+
+ if test -n "$dlfiles$dlprefiles"; then
+ $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+ fi
+
+ set dummy $rpath
+ if test $# -gt 2; then
+ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+ fi
+ install_libdir="$2"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ # Building a libtool convenience library.
+ libext=al
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ dependency_libs="$deplibs"
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+ fi
+ else
+
+ # Parse the version information argument.
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ IFS="$save_ifs"
+
+ if test -n "$8"; then
+ $echo "$modename: too many parameters to \`-version-info'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ current="$2"
+ revision="$3"
+ age="$4"
+
+ # Check that each of the things are valid numbers.
+ case "$current" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$revision" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$age" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test $age -gt $current; then
+ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case "$version_type" in
+ none) ;;
+
+ linux)
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ major=`expr $current - $age`
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test $loop != 0; do
+ iface=`expr $current - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current";
+ ;;
+
+ windows)
+ # Like Linux, but with '-' rather than '.', since we only
+ # want one extension on Windows 95.
+ major=`expr $current - $age`
+ versuffix="-$major-$age-$revision"
+ ;;
+
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ versuffix=
+ verstring="0.0"
+ case "$host" in
+ *-*-sunos*)
+ versuffix=".0.0"
+ ;;
+ esac
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ # Add libc to deplibs on all systems.
+ dependency_libs="$deplibs"
+ deplibs="$deplibs -lc"
+ fi
+
+ # Create the output directory, or remove our outputs if we need to.
+ if test -d $output_objdir; then
+ $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+ $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+ else
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^ ]*\.'${libext}' //g' -e "$los2o" -e 's/ $//g'`
+ fi
+
+ if test "$build_libtool_libs" = yes; then
+ # Transform deplibs into only deplibs that can be linked in shared.
+ ## Gordon: Do you check for the existence of the libraries in deplibs
+ ## on the system? That should maybe be merged in here someplace....
+ ## Actually: I think test_compile and file_magic do this... file_regex
+ ## sorta does this. Only pas_all needs to be changed. -Toshio
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ case "$check_shared_deplibs_method" in
+ pass_all)
+ newdeplibs=$deplibs
+ ;; # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behaviour.
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $rm conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $rm a.out
+ $C_compiler conftest.c $deplibs
+ if test $? -eq 0 ; then
+ ldd_output=`ldd a.out`
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ else
+ # Error occured in the first compile. Let's try to salvage the situation:
+ # Compile a seperate program for each library.
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ $rm a.out
+ $C_compiler conftest.c $i
+ # Did it work?
+ if test $? -eq 0 ; then
+ ldd_output=`ldd a.out`
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ echo
+ echo "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ fi
+ deplibs=$newdeplibs
+ ;;
+ file_magic* | file_regex)
+ set dummy $check_shared_deplibs_method
+ file_magic_regex="`expr \"$check_shared_deplibs_method\" : \"$2\(.*\)\"`"
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ case "$check_shared_deplibs_method" in
+ file_magic*)
+ for i in $lib_search_path; do
+ # This needs to be more general than file_regex in order to
+ # catch things like glibc on linux. Maybe file_regex
+ # should be more general as well, but maybe not. Since
+ # library names are supposed to conform to
+ # library_name_spec, I think file_regex should remain
+ # strict. What do you think Gordon?
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ file_output=`file $potent_lib`
+ if test `expr "$file_output" : ".*$file_magic_regex"` -ne 0 ; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ ;;
+ file_regex)
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ for i in $lib_search_path; do
+ potential_libs=`ls $i/$deplib_match* 2>/dev/null`
+ if test "$potential_libs" != "" ; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break
+ fi
+ done
+ ;;
+ esac
+ if test "$a_deplib" != "" ; then
+ echo
+ echo "*** Warning: This library needs some functionality provided by $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ none | *) deplibs="" ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+ deplibs=$newdeplibs
+ # Done checking deplibs!
+
+ # Get the real and link names of the library.
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ lib="$output_objdir/$realname"
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Use standard objects if they are PIC.
+ test -z "$pic_flag" && libobjs=`$echo "X$libobjs " | $Xsed -e "$los2o" -e 's/ $//g'`
+
+ if test -n "$whole_archive_flag_spec"; then
+ if test -n "$convenience"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ fi
+ else
+ for xlib in $convenience; do
+ # Extract the objects.
+ xdir="$xlib"x
+ generated="$generated $xdir"
+ xlib=`echo "$xlib" | $Xsed -e 's%^.*/%%'`
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x ../$xlib)"
+ $run eval "(cd \$xdir && $AR x ../\$xlib)" || exit $?
+
+ libobjs="$libobjs `echo $xdir/*`"
+ done
+ fi
+
+ # Do each of the archive commands.
+ if test -n "$export_symbols" && test -n "$archive_sym_cmds"; then
+ eval cmds=\"$archive_sym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ $show "(cd $output_objdir && $LN_S $realname $linkname)"
+ $run eval '(cd $output_objdir && $LN_S $realname $linkname)' || exit $?
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ *.lo | *.o | *.obj)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles"; then
+ $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+ fi
+
+ case "$output" in
+ *.lo)
+ if test -n "$objs"; then
+ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+ exit 1
+ fi
+ libobj="$output"
+ obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $run $rm $obj $libobj
+
+ # Create the old-style object.
+ reload_objs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^ ]*\.'${libext}' //g' -e 's/[^ ]*\.lib //g' -e "$los2o" -e 's/ $//g'`
+
+ output="$obj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Exit if we aren't doing a library object file.
+ test -z "$libobj" && exit 0
+
+ if test "$build_libtool_libs" != yes; then
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > $libobj" || exit $?
+ exit 0
+ fi
+
+ if test -n "$pic_flag"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs"
+ output="$libobj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ else
+ # Just create a symlink.
+ $show "$LN_S $obj $libobj"
+ $run $LN_S $obj $libobj || exit $?
+ fi
+
+ exit 0
+ ;;
+
+ # Anything else should be a program.
+ *)
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ # Put the magic libdir with the hardcode flag.
+ hardcode_libdirs="$libdir"
+ libdir="@HARDCODE_LIBDIRS@"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ libdir=
+ fi
+ fi
+
+ if test -n "$libdir"; then
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ compile_command="$compile_command $flag"
+ finalize_command="$finalize_command $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ fi
+
+ # Substitute the hardcoded libdirs into the compile commands.
+ if test -n "$hardcode_libdir_separator"; then
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+ fi
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$echo "X$compile_command " | $Xsed -e "$los2o" -e 's/ $//'`
+ finalize_command=`$echo "X$finalize_command " | $Xsed -e "$los2o" -e 's/ $//'`
+ fi
+
+ if test "$export_dynamic" = yes && test -n "$NM" && test -n "$global_symbol_pipe"; then
+ dlsyms="${outputname}S.c"
+ else
+ dlsyms=
+ fi
+
+ if test -n "$dlsyms"; then
+ case "$dlsyms" in
+ "") ;;
+ *.c)
+ if test -z "$export_symbols"; then
+ # Add our own program objects to the preloaded list.
+ dlprefiles=`$echo "X$objs$dlprefiles " | $Xsed -e "$los2o" -e 's/ $//'`
+ fi
+
+ # Discover the nlist of each of the dlfiles.
+ nlist="$objdir/${output}.nm"
+
+ if test -d $objdir; then
+ $show "$rm $nlist ${nlist}T"
+ $run $rm "$nlist" "${nlist}T"
+ else
+ $show "$mkdir $objdir"
+ $run $mkdir $objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $objdir; then
+ exit $status
+ fi
+ fi
+
+ # Parse the name list into a source file.
+ $show "creating $objdir/$dlsyms"
+
+ $echo > "$objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define dld_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test -n "$export_symbols"; then
+ sed -e 's/^\(.*\)/\1 \1/' < "$export_symbols" > "$nlist"
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -z "$run"; then
+ # Make sure we at least have an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ $rm "$nlist"T
+ fi
+
+ if test -f "$nlist"; then
+ sed -e 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> "$output_objdir/$dlsyms"
+ else
+ echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$dlsyms" "\
+
+#undef dld_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The mapping between symbol names and symbols. */
+struct {
+ char *name;
+ __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{\
+"
+
+ if test -n "$export_symbols"; then
+ echo >> "$objdir/$dlsyms" "\
+ {\"${output}\", (__ptr_t) 0},"
+ sed 's/^\(.*\)/ {"\1", (__ptr_t) \&\1},/' < "$export_symbols" >> "$objdir/$dlsyms"
+ fi
+
+ for arg in $dlprefiles; do
+ name=`echo "$arg" | sed -e 's%^.*/%%'`
+ echo >> "$objdir/$dlsyms" "\
+ {\"$name\", (__ptr_t) 0},"
+ eval "$NM $arg | $global_symbol_pipe > '$nlist'"
+
+ if test -f "$nlist"; then
+ sed 's/^\(.*\) \(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$nlist" >> "$objdir/$dlsyms"
+ else
+ echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ fi
+
+ done
+
+ if test -f "$nlist"; then
+ sed 's/^\(.*\) \(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$nlist" >> "$output_objdir/$dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$dlsyms" "\
+ {0, (__ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ fi
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $objdir && $C_compiler -c$no_builtin_flag \"$dlsyms\")"
+ $run eval '(cd $objdir && $C_compiler -c$no_builtin_flag "$dlsyms")' || exit $?
+
+ # Transform the symbol file into the correct name.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.${objext}%"`
+ ;;
+ *)
+ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+ exit 1
+ ;;
+ esac
+ elif test "$export_dynamic" != yes; then
+ test -n "$dlfiles$dlprefiles" && $echo "$modename: warning: \`-dlopen' and \`-dlpreopen' are ignored without \`-export-dynamic'" 1>&2
+ else
+ # We keep going just in case the user didn't refer to
+ # dld_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ $show "$compile_command"
+ $run eval "$compile_command"
+ exit $?
+ fi
+
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'T%g'`
+
+ # Create the binary in the object directory, then wrap it.
+ if test ! -d $output_objdir; then
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $objdir; then
+ exit $status
+ fi
+ fi
+
+ if test -n "$shlibpath_var"; then
+ # We should set the shlibpath_var
+ rpath=
+ for dir in $temp_rpath; do
+ case "$dir" in
+ /* | [A-Za-z]:[/\\]*)
+ # Absolute path.
+ rpath="$rpath$dir:"
+ ;;
+ *)
+ # Relative path: add a thisdir entry.
+ rpath="$rpath\$thisdir/$dir:"
+ ;;
+ esac
+ done
+ temp_rpath="$rpath"
+ fi
+
+ # Delete the old output file.
+ $run $rm $output
+
+ if test -n "$compile_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_command="$runpath_var=\"$rpath\$$runpath_var\" $compile_command"
+ finalize_command="$runpath_var=\"$rpath\$$runpath_var\" $finalize_command"
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # AGH! Flame the AIX and HP-UX people for me, will ya?
+ $echo "$modename: warning: this platform doesn\'t like uninstalled shared libraries" 1>&2
+ $echo "$modename: \`$output' will be relinked during installation" 1>&2
+ fi
+
+ $show "$compile_command"
+ $run eval "$compile_command" || exit $?
+
+ # Now create the wrapper script.
+ $show "creating $output"
+
+ # Quote the finalize command for shipping.
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "$sed_quote_subst"`
+
+ # Quote $echo for shipping.
+ if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+ case "$0" in
+ /* | [A-Za-z]:[/\\]*) qecho="$SHELL $0 --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+ esac
+ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if our run command is non-null.
+ if test -z "$run"; then
+ $rm $output
+ trap "$rm $output; exit 1" 1 2 15
+
+ $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ link_against_libtool_libs='$link_against_libtool_libs'
+ finalize_command=\"cd `pwd | sed -e $sed_quote_subst`; $finalize_command\"
+else
+ # When we are sourced in execute mode, \$file and \$echo are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ echo=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$echo works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$echo will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $echo >> $output "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ /* | [A-Za-z]:[/\\]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+ done
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+
+ progdir=\"\$thisdir/$objdir\"
+ program='$outputname'
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $echo >> $output "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/:*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $echo >> $output "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+
+ # Export the path to the program.
+ PATH=\"\$progdir:\$PATH\"
+ export PATH
+
+ exec \$program \${1+\"\$@\"}
+
+ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"This script is just a wrapper for \$program.\" 1>&2
+ echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+ chmod +x $output
+ fi
+ exit 0
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ oldobjs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^ ]*\.'${libext}' //g' -e 's/[^ ]*\.lib //g' -e "$los2o" -e 's/ $//g'`
+ addlibs="$old_convenience"
+ fi
+
+ # Add in members from convenience archives.
+ for xlib in $addlibs; do
+ # Extract the objects.
+ xdir="$xlib"x
+ generated="$generated $xdir"
+ xlib=`echo "$xlib" | $Xsed -e 's%^.*/%%'`
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x ../$xlib)"
+ $run eval "(cd \$xdir && $AR x ../\$xlib)" || exit $?
+
+ oldobjs="$oldobjs `echo $xdir/*`"
+ done
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ eval cmds=\"$old_archive_from_new_cmds\"
+ else
+ eval cmds=\"$old_archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$generated"; then
+ $show "${rm}r$generated"
+ $run ${rm}r$generated
+ fi
+
+ # Now create the libtool archive.
+ case "$output" in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ $show "creating $output"
+
+ # Only create the output if not a dry run.
+ if test -z "$run"; then
+ $echo > $output "\
+# $output - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=no
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+ fi
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ $show "(cd $output_objdir && $LN_S ../$outputname $outputname)"
+ $run eval "(cd $output_objdir && $LN_S ../$outputname $outputname)" || exit $?
+ ;;
+ esac
+ exit 0
+ ;;
+
+ # libtool install mode
+ install)
+ modename="$modename: install"
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+ # Aesthetically quote it.
+ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$arg "
+ arg="$1"
+ shift
+ else
+ install_prog=
+ arg="$nonopt"
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog$arg"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest="$arg"
+ continue
+ fi
+
+ case "$arg" in
+ -d) isdir=yes ;;
+ -f) prev="-f" ;;
+ -g) prev="-g" ;;
+ -m) prev="-m" ;;
+ -o) prev="-o" ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*) ;;
+
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest="$arg"
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog $arg"
+ done
+
+ if test -z "$install_prog"; then
+ $echo "$modename: you must specify an install program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prev' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ $echo "$modename: no file or destination specified" 1>&2
+ else
+ $echo "$modename: you must specify a destination" 1>&2
+ fi
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Strip any trailing slash from the destination.
+ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$destdir" = "X$dest" && destdir=.
+ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files
+ if test $# -gt 2; then
+ $echo "$modename: \`$dest' is not a directory" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ fi
+ case "$destdir" in
+ /* | [A-Za-z]:[/\\]*) ;;
+ *)
+ for file in $files; do
+ case "$file" in
+ *.lo) ;;
+ *)
+ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case "$file" in
+ *.a | *.lib)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ library_names=
+ old_library=
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+ test "X$dir" = "X$file/" && dir=
+ dir="$dir$objdir"
+
+ # See the names of the shared library.
+ set dummy $library_names
+ if test -n "$2"; then
+ realname="$2"
+ shift
+ shift
+
+ # Install the shared library and build the symlinks.
+ $show "$install_prog $dir/$realname $destdir/$realname"
+ $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+ test "X$dlname" = "X$realname" && dlname=
+
+ if test $# -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ for linkname
+ do
+ test "X$dlname" = "X$linkname" && dlname=
+ if test "$linkname" != "$realname"; then
+ $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ fi
+ done
+ fi
+
+ if test -n "$dlname"; then
+ # Install the dynamically-loadable library.
+ $show "$install_prog $dir/$dlname $destdir/$dlname"
+ $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $?
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ eval cmds=\"$postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Install the pseudo-library for information purposes.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ instname="$dir/$name"i
+ $show "Creating $instname"
+ $rm "$instname"
+ sed 's/^installed=no$/installed=yes/' "$file" > "$instname"
+ $show "$install_prog $instname $destdir/$name"
+ $run eval "$install_prog $instname $destdir/$name" || exit $?
+ $show "$rm $instname"
+ $rm "$instname"
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case "$destfile" in
+ *.lo)
+ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+ ;;
+ *.o | *.obj)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ if test -n "$destfile"; then
+ $show "$install_prog $file $destfile"
+ $run eval "$install_prog $file $destfile" || exit $?
+ fi
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+ $show "$install_prog $staticobj $staticdest"
+ $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+ fi
+ exit 0
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ link_against_libtool_libs=
+ finalize_command=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Check the variables that should have been set.
+ if test -z "$link_against_libtool_libs" || test -z "$finalize_command"; then
+ $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+ exit 1
+ fi
+
+ finalize=yes
+ for lib in $link_against_libtool_libs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ # If there is no directory component, then add one.
+ case "$lib" in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ fi
+ libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+ finalize=no
+ fi
+ done
+
+ if test "$hardcode_action" = relink; then
+ if test "$finalize" = yes; then
+ $echo "$modename: warning: relinking \`$file' on behalf of your buggy system linker" 1>&2
+ $show "$finalize_command"
+ if $run eval "$finalize_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ continue
+ fi
+ file="$objdir/$file"T
+ else
+ $echo "$modename: warning: cannot relink \`$file' on behalf of your buggy system linker" 1>&2
+ fi
+ else
+ # Install the binary that we compiled earlier.
+ file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ $show "$install_prog$stripme $file $destfile"
+ $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ $show "$install_prog $file $oldlib"
+ $run eval "$install_prog \$file \$oldlib" || exit $?
+
+ # Do each command in the postinstall commands.
+ eval cmds=\"$old_postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$future_libdirs"; then
+ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+ fi
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ test -n "$run" && current_libdirs=" -n$current_libdirs"
+ exec $SHELL $0 --finish$current_libdirs
+ exit 1
+ fi
+
+ exit 0
+ ;;
+
+ # libtool finish mode
+ finish)
+ modename="$modename: finish"
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ eval cmds=\"$finish_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || admincmds="$admincmds
+ $cmd"
+ done
+ IFS="$save_ifs"
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $run eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ test "$show" = : && exit 0
+
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ echo " $libdir"
+ done
+ echo
+ echo "To link against installed libraries in a given directory, LIBDIR,"
+ echo "you must use the \`-LLIBDIR' flag during linking."
+ echo
+ echo " You will also need to do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ echo " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ echo " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+ echo "See any operating system documentation about shared libraries for"
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ echo "----------------------------------------------------------------------"
+ exit 0
+ ;;
+
+ # libtool execute mode
+ execute)
+ modename="$modename: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ $echo "$modename: you must specify a COMMAND" 1>&2
+ $echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test ! -f "$file"; then
+ $echo "$modename: \`$file' is not a file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case "$file" in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case "$file" in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+ args="$args \"$file\""
+ done
+
+ if test -z "$run"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+
+ # Restore saved enviroment variables
+ if test "${save_LC_ALL+set}" = set; then
+ LC_ALL="$save_LC_ALL"; export LC_ALL
+ fi
+ if test "${save_LANG+set}" = set; then
+ LANG="$save_LANG"; export LANG
+ fi
+
+ # Now actually exec the command.
+ eval "exec \$cmd$args"
+
+ $echo "$modename: cannot exec \$cmd$args"
+ exit 1
+ else
+ # Display what would be done.
+ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+ $echo "export $shlibpath_var"
+ $echo "$cmd$args"
+ exit 0
+ fi
+ ;;
+
+ # libtool uninstall mode
+ uninstall)
+ modename="$modename: uninstall"
+ rm="$nonopt"
+ files=
+
+ for arg
+ do
+ case "$arg" in
+ -*) rm="$rm $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ if test -z "$rm"; then
+ $echo "$modename: you must specify an RM program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ for file in $files; do
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ rmfiles="$file"
+
+ case "$name" in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ . $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $dir/$n"
+ test "X$n" = "X$dlname" && dlname=
+ done
+ test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname"
+ test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ eval cmds=\"$postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ eval cmds=\"$old_postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ # FIXME: should reinstall the best remaining shared library.
+ fi
+ ;;
+
+ *.lo)
+ if test "$build_old_libs" = yes; then
+ oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+ rmfiles="$rmfiles $dir/$oldobj"
+ fi
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+
+ *)
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+ esac
+ done
+ exit 0
+ ;;
+
+ "")
+ $echo "$modename: you must specify a MODE" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+-n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --finish same as \`--mode=finish'
+ --help display this help message and exit
+ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
+ --quiet same as \`--silent'
+ --silent don't print informational messages
+ --version print version information
+
+MODE must be one of the following:
+
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+ exit 0
+ ;;
+
+compile)
+ $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -static always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+execute)
+ $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+finish)
+ $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+install)
+ $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+link)
+ $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to dld_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -static do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only
+library objects (\`.lo' files) may be specified, and \`-rpath' is required.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+uninstall)
+ $echo
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+*)
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/crypto/heimdal/missing b/crypto/heimdal/missing
new file mode 100644
index 000000000000..bdf90f59d5c6
--- /dev/null
+++ b/crypto/heimdal/missing
@@ -0,0 +1,2 @@
+#! /bin/sh
+# This is a silly file that automake needs
diff --git a/crypto/heimdal/mkinstalldirs b/crypto/heimdal/mkinstalldirs
new file mode 100755
index 000000000000..018b6800c668
--- /dev/null
+++ b/crypto/heimdal/mkinstalldirs
@@ -0,0 +1,40 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id: mkinstalldirs,v 1.1 1996/10/22 22:25:14 joda Exp $
+
+errstatus=0
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here